1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "net/socket_stream/socket_stream.h" 6 7 #include <string> 8 #include <vector> 9 10 #include "base/bind.h" 11 #include "base/bind_helpers.h" 12 #include "base/callback.h" 13 #include "base/strings/utf_string_conversions.h" 14 #include "net/base/auth.h" 15 #include "net/base/net_log.h" 16 #include "net/base/net_log_unittest.h" 17 #include "net/base/test_completion_callback.h" 18 #include "net/dns/mock_host_resolver.h" 19 #include "net/http/http_network_session.h" 20 #include "net/proxy/proxy_service.h" 21 #include "net/socket/socket_test_util.h" 22 #include "net/url_request/url_request_test_util.h" 23 #include "testing/gtest/include/gtest/gtest.h" 24 #include "testing/platform_test.h" 25 26 using base::ASCIIToUTF16; 27 28 namespace net { 29 30 namespace { 31 32 struct SocketStreamEvent { 33 enum EventType { 34 EVENT_START_OPEN_CONNECTION, EVENT_CONNECTED, EVENT_SENT_DATA, 35 EVENT_RECEIVED_DATA, EVENT_CLOSE, EVENT_AUTH_REQUIRED, EVENT_ERROR, 36 }; 37 38 SocketStreamEvent(EventType type, 39 SocketStream* socket_stream, 40 int num, 41 const std::string& str, 42 AuthChallengeInfo* auth_challenge_info, 43 int error) 44 : event_type(type), socket(socket_stream), number(num), data(str), 45 auth_info(auth_challenge_info), error_code(error) {} 46 47 EventType event_type; 48 SocketStream* socket; 49 int number; 50 std::string data; 51 scoped_refptr<AuthChallengeInfo> auth_info; 52 int error_code; 53 }; 54 55 class SocketStreamEventRecorder : public SocketStream::Delegate { 56 public: 57 // |callback| will be run when the OnClose() or OnError() method is called. 58 // For OnClose(), |callback| is called with OK. For OnError(), it's called 59 // with the error code. 60 explicit SocketStreamEventRecorder(const CompletionCallback& callback) 61 : callback_(callback) {} 62 virtual ~SocketStreamEventRecorder() {} 63 64 void SetOnStartOpenConnection( 65 const base::Callback<int(SocketStreamEvent*)>& callback) { 66 on_start_open_connection_ = callback; 67 } 68 void SetOnConnected( 69 const base::Callback<void(SocketStreamEvent*)>& callback) { 70 on_connected_ = callback; 71 } 72 void SetOnSentData( 73 const base::Callback<void(SocketStreamEvent*)>& callback) { 74 on_sent_data_ = callback; 75 } 76 void SetOnReceivedData( 77 const base::Callback<void(SocketStreamEvent*)>& callback) { 78 on_received_data_ = callback; 79 } 80 void SetOnClose(const base::Callback<void(SocketStreamEvent*)>& callback) { 81 on_close_ = callback; 82 } 83 void SetOnAuthRequired( 84 const base::Callback<void(SocketStreamEvent*)>& callback) { 85 on_auth_required_ = callback; 86 } 87 void SetOnError(const base::Callback<void(SocketStreamEvent*)>& callback) { 88 on_error_ = callback; 89 } 90 91 virtual int OnStartOpenConnection( 92 SocketStream* socket, 93 const CompletionCallback& callback) OVERRIDE { 94 connection_callback_ = callback; 95 events_.push_back( 96 SocketStreamEvent(SocketStreamEvent::EVENT_START_OPEN_CONNECTION, 97 socket, 0, std::string(), NULL, OK)); 98 if (!on_start_open_connection_.is_null()) 99 return on_start_open_connection_.Run(&events_.back()); 100 return OK; 101 } 102 virtual void OnConnected(SocketStream* socket, 103 int num_pending_send_allowed) OVERRIDE { 104 events_.push_back( 105 SocketStreamEvent(SocketStreamEvent::EVENT_CONNECTED, 106 socket, num_pending_send_allowed, std::string(), 107 NULL, OK)); 108 if (!on_connected_.is_null()) 109 on_connected_.Run(&events_.back()); 110 } 111 virtual void OnSentData(SocketStream* socket, 112 int amount_sent) OVERRIDE { 113 events_.push_back( 114 SocketStreamEvent(SocketStreamEvent::EVENT_SENT_DATA, socket, 115 amount_sent, std::string(), NULL, OK)); 116 if (!on_sent_data_.is_null()) 117 on_sent_data_.Run(&events_.back()); 118 } 119 virtual void OnReceivedData(SocketStream* socket, 120 const char* data, int len) OVERRIDE { 121 events_.push_back( 122 SocketStreamEvent(SocketStreamEvent::EVENT_RECEIVED_DATA, socket, len, 123 std::string(data, len), NULL, OK)); 124 if (!on_received_data_.is_null()) 125 on_received_data_.Run(&events_.back()); 126 } 127 virtual void OnClose(SocketStream* socket) OVERRIDE { 128 events_.push_back( 129 SocketStreamEvent(SocketStreamEvent::EVENT_CLOSE, socket, 0, 130 std::string(), NULL, OK)); 131 if (!on_close_.is_null()) 132 on_close_.Run(&events_.back()); 133 if (!callback_.is_null()) 134 callback_.Run(OK); 135 } 136 virtual void OnAuthRequired(SocketStream* socket, 137 AuthChallengeInfo* auth_info) OVERRIDE { 138 events_.push_back( 139 SocketStreamEvent(SocketStreamEvent::EVENT_AUTH_REQUIRED, socket, 0, 140 std::string(), auth_info, OK)); 141 if (!on_auth_required_.is_null()) 142 on_auth_required_.Run(&events_.back()); 143 } 144 virtual void OnError(const SocketStream* socket, int error) OVERRIDE { 145 events_.push_back( 146 SocketStreamEvent(SocketStreamEvent::EVENT_ERROR, NULL, 0, 147 std::string(), NULL, error)); 148 if (!on_error_.is_null()) 149 on_error_.Run(&events_.back()); 150 if (!callback_.is_null()) 151 callback_.Run(error); 152 } 153 154 void DoClose(SocketStreamEvent* event) { 155 event->socket->Close(); 156 } 157 void DoRestartWithAuth(SocketStreamEvent* event) { 158 VLOG(1) << "RestartWithAuth username=" << credentials_.username() 159 << " password=" << credentials_.password(); 160 event->socket->RestartWithAuth(credentials_); 161 } 162 void SetAuthInfo(const AuthCredentials& credentials) { 163 credentials_ = credentials; 164 } 165 // Wakes up the SocketStream waiting for completion of OnStartOpenConnection() 166 // of its delegate. 167 void CompleteConnection(int result) { 168 connection_callback_.Run(result); 169 } 170 171 const std::vector<SocketStreamEvent>& GetSeenEvents() const { 172 return events_; 173 } 174 175 private: 176 std::vector<SocketStreamEvent> events_; 177 base::Callback<int(SocketStreamEvent*)> on_start_open_connection_; 178 base::Callback<void(SocketStreamEvent*)> on_connected_; 179 base::Callback<void(SocketStreamEvent*)> on_sent_data_; 180 base::Callback<void(SocketStreamEvent*)> on_received_data_; 181 base::Callback<void(SocketStreamEvent*)> on_close_; 182 base::Callback<void(SocketStreamEvent*)> on_auth_required_; 183 base::Callback<void(SocketStreamEvent*)> on_error_; 184 const CompletionCallback callback_; 185 CompletionCallback connection_callback_; 186 AuthCredentials credentials_; 187 188 DISALLOW_COPY_AND_ASSIGN(SocketStreamEventRecorder); 189 }; 190 191 // This is used for the test OnErrorDetachDelegate. 192 class SelfDeletingDelegate : public SocketStream::Delegate { 193 public: 194 // |callback| must cause the test message loop to exit when called. 195 explicit SelfDeletingDelegate(const CompletionCallback& callback) 196 : socket_stream_(), callback_(callback) {} 197 198 virtual ~SelfDeletingDelegate() {} 199 200 // Call DetachDelegate(), delete |this|, then run the callback. 201 virtual void OnError(const SocketStream* socket, int error) OVERRIDE { 202 // callback_ will be deleted when we delete |this|, so copy it to call it 203 // afterwards. 204 CompletionCallback callback = callback_; 205 socket_stream_->DetachDelegate(); 206 delete this; 207 callback.Run(OK); 208 } 209 210 // This can't be passed in the constructor because this object needs to be 211 // created before SocketStream. 212 void set_socket_stream(const scoped_refptr<SocketStream>& socket_stream) { 213 socket_stream_ = socket_stream; 214 EXPECT_EQ(socket_stream_->delegate(), this); 215 } 216 217 virtual void OnConnected(SocketStream* socket, int max_pending_send_allowed) 218 OVERRIDE { 219 ADD_FAILURE() << "OnConnected() should not be called"; 220 } 221 virtual void OnSentData(SocketStream* socket, int amount_sent) OVERRIDE { 222 ADD_FAILURE() << "OnSentData() should not be called"; 223 } 224 virtual void OnReceivedData(SocketStream* socket, const char* data, int len) 225 OVERRIDE { 226 ADD_FAILURE() << "OnReceivedData() should not be called"; 227 } 228 virtual void OnClose(SocketStream* socket) OVERRIDE { 229 ADD_FAILURE() << "OnClose() should not be called"; 230 } 231 232 private: 233 scoped_refptr<SocketStream> socket_stream_; 234 const CompletionCallback callback_; 235 236 DISALLOW_COPY_AND_ASSIGN(SelfDeletingDelegate); 237 }; 238 239 class TestURLRequestContextWithProxy : public TestURLRequestContext { 240 public: 241 explicit TestURLRequestContextWithProxy(const std::string& proxy) 242 : TestURLRequestContext(true) { 243 context_storage_.set_proxy_service(ProxyService::CreateFixed(proxy)); 244 Init(); 245 } 246 virtual ~TestURLRequestContextWithProxy() {} 247 }; 248 249 class TestSocketStreamNetworkDelegate : public TestNetworkDelegate { 250 public: 251 TestSocketStreamNetworkDelegate() 252 : before_connect_result_(OK) {} 253 virtual ~TestSocketStreamNetworkDelegate() {} 254 255 virtual int OnBeforeSocketStreamConnect( 256 SocketStream* stream, 257 const CompletionCallback& callback) OVERRIDE { 258 return before_connect_result_; 259 } 260 261 void SetBeforeConnectResult(int result) { 262 before_connect_result_ = result; 263 } 264 265 private: 266 int before_connect_result_; 267 }; 268 269 } // namespace 270 271 class SocketStreamTest : public PlatformTest { 272 public: 273 virtual ~SocketStreamTest() {} 274 virtual void SetUp() { 275 mock_socket_factory_.reset(); 276 handshake_request_ = kWebSocketHandshakeRequest; 277 handshake_response_ = kWebSocketHandshakeResponse; 278 } 279 virtual void TearDown() { 280 mock_socket_factory_.reset(); 281 } 282 283 virtual void SetWebSocketHandshakeMessage( 284 const char* request, const char* response) { 285 handshake_request_ = request; 286 handshake_response_ = response; 287 } 288 virtual void AddWebSocketMessage(const std::string& message) { 289 messages_.push_back(message); 290 } 291 292 virtual MockClientSocketFactory* GetMockClientSocketFactory() { 293 mock_socket_factory_.reset(new MockClientSocketFactory); 294 return mock_socket_factory_.get(); 295 } 296 297 // Functions for SocketStreamEventRecorder to handle calls to the 298 // SocketStream::Delegate methods from the SocketStream. 299 300 virtual void DoSendWebSocketHandshake(SocketStreamEvent* event) { 301 event->socket->SendData( 302 handshake_request_.data(), handshake_request_.size()); 303 } 304 305 virtual void DoCloseFlushPendingWriteTest(SocketStreamEvent* event) { 306 // handshake response received. 307 for (size_t i = 0; i < messages_.size(); i++) { 308 std::vector<char> frame; 309 frame.push_back('\0'); 310 frame.insert(frame.end(), messages_[i].begin(), messages_[i].end()); 311 frame.push_back('\xff'); 312 EXPECT_TRUE(event->socket->SendData(&frame[0], frame.size())); 313 } 314 // Actual StreamSocket close must happen after all frames queued by 315 // SendData above are sent out. 316 event->socket->Close(); 317 } 318 319 virtual void DoCloseFlushPendingWriteTestWithSetContextNull( 320 SocketStreamEvent* event) { 321 event->socket->DetachContext(); 322 // handshake response received. 323 for (size_t i = 0; i < messages_.size(); i++) { 324 std::vector<char> frame; 325 frame.push_back('\0'); 326 frame.insert(frame.end(), messages_[i].begin(), messages_[i].end()); 327 frame.push_back('\xff'); 328 EXPECT_TRUE(event->socket->SendData(&frame[0], frame.size())); 329 } 330 // Actual StreamSocket close must happen after all frames queued by 331 // SendData above are sent out. 332 event->socket->Close(); 333 } 334 335 virtual void DoFailByTooBigDataAndClose(SocketStreamEvent* event) { 336 std::string frame(event->number + 1, 0x00); 337 VLOG(1) << event->number; 338 EXPECT_FALSE(event->socket->SendData(&frame[0], frame.size())); 339 event->socket->Close(); 340 } 341 342 virtual int DoSwitchToSpdyTest(SocketStreamEvent* event) { 343 return ERR_PROTOCOL_SWITCHED; 344 } 345 346 // Notifies |io_test_callback_| of that this method is called, and keeps the 347 // SocketStream waiting. 348 virtual int DoIOPending(SocketStreamEvent* event) { 349 io_test_callback_.callback().Run(OK); 350 return ERR_IO_PENDING; 351 } 352 353 static const char kWebSocketHandshakeRequest[]; 354 static const char kWebSocketHandshakeResponse[]; 355 356 protected: 357 TestCompletionCallback io_test_callback_; 358 359 private: 360 std::string handshake_request_; 361 std::string handshake_response_; 362 std::vector<std::string> messages_; 363 364 scoped_ptr<MockClientSocketFactory> mock_socket_factory_; 365 }; 366 367 const char SocketStreamTest::kWebSocketHandshakeRequest[] = 368 "GET /demo HTTP/1.1\r\n" 369 "Host: example.com\r\n" 370 "Connection: Upgrade\r\n" 371 "Sec-WebSocket-Key2: 12998 5 Y3 1 .P00\r\n" 372 "Sec-WebSocket-Protocol: sample\r\n" 373 "Upgrade: WebSocket\r\n" 374 "Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5\r\n" 375 "Origin: http://example.com\r\n" 376 "\r\n" 377 "^n:ds[4U"; 378 379 const char SocketStreamTest::kWebSocketHandshakeResponse[] = 380 "HTTP/1.1 101 WebSocket Protocol Handshake\r\n" 381 "Upgrade: WebSocket\r\n" 382 "Connection: Upgrade\r\n" 383 "Sec-WebSocket-Origin: http://example.com\r\n" 384 "Sec-WebSocket-Location: ws://example.com/demo\r\n" 385 "Sec-WebSocket-Protocol: sample\r\n" 386 "\r\n" 387 "8jKS'y:G*Co,Wxa-"; 388 389 TEST_F(SocketStreamTest, CloseFlushPendingWrite) { 390 TestCompletionCallback test_callback; 391 392 scoped_ptr<SocketStreamEventRecorder> delegate( 393 new SocketStreamEventRecorder(test_callback.callback())); 394 delegate->SetOnConnected(base::Bind( 395 &SocketStreamTest::DoSendWebSocketHandshake, base::Unretained(this))); 396 delegate->SetOnReceivedData(base::Bind( 397 &SocketStreamTest::DoCloseFlushPendingWriteTest, 398 base::Unretained(this))); 399 400 TestURLRequestContext context; 401 402 scoped_refptr<SocketStream> socket_stream( 403 new SocketStream(GURL("ws://example.com/demo"), delegate.get(), 404 &context, NULL)); 405 406 MockWrite data_writes[] = { 407 MockWrite(SocketStreamTest::kWebSocketHandshakeRequest), 408 MockWrite(ASYNC, "\0message1\xff", 10), 409 MockWrite(ASYNC, "\0message2\xff", 10) 410 }; 411 MockRead data_reads[] = { 412 MockRead(SocketStreamTest::kWebSocketHandshakeResponse), 413 // Server doesn't close the connection after handshake. 414 MockRead(ASYNC, ERR_IO_PENDING) 415 }; 416 AddWebSocketMessage("message1"); 417 AddWebSocketMessage("message2"); 418 419 DelayedSocketData data_provider( 420 1, data_reads, arraysize(data_reads), 421 data_writes, arraysize(data_writes)); 422 423 MockClientSocketFactory* mock_socket_factory = 424 GetMockClientSocketFactory(); 425 mock_socket_factory->AddSocketDataProvider(&data_provider); 426 427 socket_stream->SetClientSocketFactory(mock_socket_factory); 428 429 socket_stream->Connect(); 430 431 test_callback.WaitForResult(); 432 433 EXPECT_TRUE(data_provider.at_read_eof()); 434 EXPECT_TRUE(data_provider.at_write_eof()); 435 436 const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents(); 437 ASSERT_EQ(7U, events.size()); 438 439 EXPECT_EQ(SocketStreamEvent::EVENT_START_OPEN_CONNECTION, 440 events[0].event_type); 441 EXPECT_EQ(SocketStreamEvent::EVENT_CONNECTED, events[1].event_type); 442 EXPECT_EQ(SocketStreamEvent::EVENT_SENT_DATA, events[2].event_type); 443 EXPECT_EQ(SocketStreamEvent::EVENT_RECEIVED_DATA, events[3].event_type); 444 EXPECT_EQ(SocketStreamEvent::EVENT_SENT_DATA, events[4].event_type); 445 EXPECT_EQ(SocketStreamEvent::EVENT_SENT_DATA, events[5].event_type); 446 EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE, events[6].event_type); 447 } 448 449 TEST_F(SocketStreamTest, ResolveFailure) { 450 TestCompletionCallback test_callback; 451 452 scoped_ptr<SocketStreamEventRecorder> delegate( 453 new SocketStreamEventRecorder(test_callback.callback())); 454 455 // Make resolver fail. 456 TestURLRequestContext context; 457 scoped_ptr<MockHostResolver> mock_host_resolver( 458 new MockHostResolver()); 459 mock_host_resolver->rules()->AddSimulatedFailure("example.com"); 460 context.set_host_resolver(mock_host_resolver.get()); 461 462 scoped_refptr<SocketStream> socket_stream( 463 new SocketStream(GURL("ws://example.com/demo"), delegate.get(), 464 &context, NULL)); 465 466 // No read/write on socket is expected. 467 StaticSocketDataProvider data_provider(NULL, 0, NULL, 0); 468 MockClientSocketFactory* mock_socket_factory = 469 GetMockClientSocketFactory(); 470 mock_socket_factory->AddSocketDataProvider(&data_provider); 471 socket_stream->SetClientSocketFactory(mock_socket_factory); 472 473 socket_stream->Connect(); 474 475 test_callback.WaitForResult(); 476 477 const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents(); 478 ASSERT_EQ(2U, events.size()); 479 480 EXPECT_EQ(SocketStreamEvent::EVENT_ERROR, events[0].event_type); 481 EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE, events[1].event_type); 482 } 483 484 TEST_F(SocketStreamTest, ExceedMaxPendingSendAllowed) { 485 TestCompletionCallback test_callback; 486 487 scoped_ptr<SocketStreamEventRecorder> delegate( 488 new SocketStreamEventRecorder(test_callback.callback())); 489 delegate->SetOnConnected(base::Bind( 490 &SocketStreamTest::DoFailByTooBigDataAndClose, base::Unretained(this))); 491 492 TestURLRequestContext context; 493 494 scoped_refptr<SocketStream> socket_stream( 495 new SocketStream(GURL("ws://example.com/demo"), delegate.get(), 496 &context, NULL)); 497 498 DelayedSocketData data_provider(1, NULL, 0, NULL, 0); 499 500 MockClientSocketFactory* mock_socket_factory = 501 GetMockClientSocketFactory(); 502 mock_socket_factory->AddSocketDataProvider(&data_provider); 503 504 socket_stream->SetClientSocketFactory(mock_socket_factory); 505 506 socket_stream->Connect(); 507 508 test_callback.WaitForResult(); 509 510 const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents(); 511 ASSERT_EQ(4U, events.size()); 512 513 EXPECT_EQ(SocketStreamEvent::EVENT_START_OPEN_CONNECTION, 514 events[0].event_type); 515 EXPECT_EQ(SocketStreamEvent::EVENT_CONNECTED, events[1].event_type); 516 EXPECT_EQ(SocketStreamEvent::EVENT_ERROR, events[2].event_type); 517 EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE, events[3].event_type); 518 } 519 520 TEST_F(SocketStreamTest, BasicAuthProxy) { 521 MockClientSocketFactory mock_socket_factory; 522 MockWrite data_writes1[] = { 523 MockWrite("CONNECT example.com:80 HTTP/1.1\r\n" 524 "Host: example.com\r\n" 525 "Proxy-Connection: keep-alive\r\n\r\n"), 526 }; 527 MockRead data_reads1[] = { 528 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"), 529 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), 530 MockRead("\r\n"), 531 }; 532 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 533 data_writes1, arraysize(data_writes1)); 534 mock_socket_factory.AddSocketDataProvider(&data1); 535 536 MockWrite data_writes2[] = { 537 MockWrite("CONNECT example.com:80 HTTP/1.1\r\n" 538 "Host: example.com\r\n" 539 "Proxy-Connection: keep-alive\r\n" 540 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 541 }; 542 MockRead data_reads2[] = { 543 MockRead("HTTP/1.1 200 Connection Established\r\n"), 544 MockRead("Proxy-agent: Apache/2.2.8\r\n"), 545 MockRead("\r\n"), 546 // SocketStream::DoClose is run asynchronously. Socket can be read after 547 // "\r\n". We have to give ERR_IO_PENDING to SocketStream then to indicate 548 // server doesn't close the connection. 549 MockRead(ASYNC, ERR_IO_PENDING) 550 }; 551 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), 552 data_writes2, arraysize(data_writes2)); 553 mock_socket_factory.AddSocketDataProvider(&data2); 554 555 TestCompletionCallback test_callback; 556 557 scoped_ptr<SocketStreamEventRecorder> delegate( 558 new SocketStreamEventRecorder(test_callback.callback())); 559 delegate->SetOnConnected(base::Bind(&SocketStreamEventRecorder::DoClose, 560 base::Unretained(delegate.get()))); 561 delegate->SetAuthInfo(AuthCredentials(ASCIIToUTF16("foo"), 562 ASCIIToUTF16("bar"))); 563 delegate->SetOnAuthRequired(base::Bind( 564 &SocketStreamEventRecorder::DoRestartWithAuth, 565 base::Unretained(delegate.get()))); 566 567 TestURLRequestContextWithProxy context("myproxy:70"); 568 569 scoped_refptr<SocketStream> socket_stream( 570 new SocketStream(GURL("ws://example.com/demo"), delegate.get(), 571 &context, NULL)); 572 573 socket_stream->SetClientSocketFactory(&mock_socket_factory); 574 575 socket_stream->Connect(); 576 577 test_callback.WaitForResult(); 578 579 const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents(); 580 ASSERT_EQ(5U, events.size()); 581 582 EXPECT_EQ(SocketStreamEvent::EVENT_START_OPEN_CONNECTION, 583 events[0].event_type); 584 EXPECT_EQ(SocketStreamEvent::EVENT_AUTH_REQUIRED, events[1].event_type); 585 EXPECT_EQ(SocketStreamEvent::EVENT_CONNECTED, events[2].event_type); 586 EXPECT_EQ(SocketStreamEvent::EVENT_ERROR, events[3].event_type); 587 EXPECT_EQ(ERR_ABORTED, events[3].error_code); 588 EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE, events[4].event_type); 589 590 // TODO(eroman): Add back NetLogTest here... 591 } 592 593 TEST_F(SocketStreamTest, BasicAuthProxyWithAuthCache) { 594 MockClientSocketFactory mock_socket_factory; 595 MockWrite data_writes[] = { 596 // WebSocket(SocketStream) always uses CONNECT when it is configured to use 597 // proxy so the port may not be 443. 598 MockWrite("CONNECT example.com:80 HTTP/1.1\r\n" 599 "Host: example.com\r\n" 600 "Proxy-Connection: keep-alive\r\n" 601 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 602 }; 603 MockRead data_reads[] = { 604 MockRead("HTTP/1.1 200 Connection Established\r\n"), 605 MockRead("Proxy-agent: Apache/2.2.8\r\n"), 606 MockRead("\r\n"), 607 MockRead(ASYNC, ERR_IO_PENDING) 608 }; 609 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 610 data_writes, arraysize(data_writes)); 611 mock_socket_factory.AddSocketDataProvider(&data); 612 613 TestCompletionCallback test_callback; 614 scoped_ptr<SocketStreamEventRecorder> delegate( 615 new SocketStreamEventRecorder(test_callback.callback())); 616 delegate->SetOnConnected(base::Bind(&SocketStreamEventRecorder::DoClose, 617 base::Unretained(delegate.get()))); 618 619 TestURLRequestContextWithProxy context("myproxy:70"); 620 HttpAuthCache* auth_cache = 621 context.http_transaction_factory()->GetSession()->http_auth_cache(); 622 auth_cache->Add(GURL("http://myproxy:70"), 623 "MyRealm1", 624 HttpAuth::AUTH_SCHEME_BASIC, 625 "Basic realm=MyRealm1", 626 AuthCredentials(ASCIIToUTF16("foo"), 627 ASCIIToUTF16("bar")), 628 "/"); 629 630 scoped_refptr<SocketStream> socket_stream( 631 new SocketStream(GURL("ws://example.com/demo"), delegate.get(), 632 &context, NULL)); 633 634 socket_stream->SetClientSocketFactory(&mock_socket_factory); 635 636 socket_stream->Connect(); 637 638 test_callback.WaitForResult(); 639 640 const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents(); 641 ASSERT_EQ(4U, events.size()); 642 EXPECT_EQ(SocketStreamEvent::EVENT_START_OPEN_CONNECTION, 643 events[0].event_type); 644 EXPECT_EQ(SocketStreamEvent::EVENT_CONNECTED, events[1].event_type); 645 EXPECT_EQ(ERR_ABORTED, events[2].error_code); 646 EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE, events[3].event_type); 647 } 648 649 TEST_F(SocketStreamTest, WSSBasicAuthProxyWithAuthCache) { 650 MockClientSocketFactory mock_socket_factory; 651 MockWrite data_writes1[] = { 652 MockWrite("CONNECT example.com:443 HTTP/1.1\r\n" 653 "Host: example.com\r\n" 654 "Proxy-Connection: keep-alive\r\n" 655 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 656 }; 657 MockRead data_reads1[] = { 658 MockRead("HTTP/1.1 200 Connection Established\r\n"), 659 MockRead("Proxy-agent: Apache/2.2.8\r\n"), 660 MockRead("\r\n"), 661 MockRead(ASYNC, ERR_IO_PENDING) 662 }; 663 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), 664 data_writes1, arraysize(data_writes1)); 665 mock_socket_factory.AddSocketDataProvider(&data1); 666 667 SSLSocketDataProvider data2(ASYNC, OK); 668 mock_socket_factory.AddSSLSocketDataProvider(&data2); 669 670 TestCompletionCallback test_callback; 671 scoped_ptr<SocketStreamEventRecorder> delegate( 672 new SocketStreamEventRecorder(test_callback.callback())); 673 delegate->SetOnConnected(base::Bind(&SocketStreamEventRecorder::DoClose, 674 base::Unretained(delegate.get()))); 675 676 TestURLRequestContextWithProxy context("myproxy:70"); 677 HttpAuthCache* auth_cache = 678 context.http_transaction_factory()->GetSession()->http_auth_cache(); 679 auth_cache->Add(GURL("http://myproxy:70"), 680 "MyRealm1", 681 HttpAuth::AUTH_SCHEME_BASIC, 682 "Basic realm=MyRealm1", 683 AuthCredentials(ASCIIToUTF16("foo"), 684 ASCIIToUTF16("bar")), 685 "/"); 686 687 scoped_refptr<SocketStream> socket_stream( 688 new SocketStream(GURL("wss://example.com/demo"), delegate.get(), 689 &context, NULL)); 690 691 socket_stream->SetClientSocketFactory(&mock_socket_factory); 692 693 socket_stream->Connect(); 694 695 test_callback.WaitForResult(); 696 697 const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents(); 698 ASSERT_EQ(4U, events.size()); 699 EXPECT_EQ(SocketStreamEvent::EVENT_START_OPEN_CONNECTION, 700 events[0].event_type); 701 EXPECT_EQ(SocketStreamEvent::EVENT_CONNECTED, events[1].event_type); 702 EXPECT_EQ(ERR_ABORTED, events[2].error_code); 703 EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE, events[3].event_type); 704 } 705 706 TEST_F(SocketStreamTest, IOPending) { 707 TestCompletionCallback test_callback; 708 709 scoped_ptr<SocketStreamEventRecorder> delegate( 710 new SocketStreamEventRecorder(test_callback.callback())); 711 delegate->SetOnStartOpenConnection(base::Bind( 712 &SocketStreamTest::DoIOPending, base::Unretained(this))); 713 delegate->SetOnConnected(base::Bind( 714 &SocketStreamTest::DoSendWebSocketHandshake, base::Unretained(this))); 715 delegate->SetOnReceivedData(base::Bind( 716 &SocketStreamTest::DoCloseFlushPendingWriteTest, 717 base::Unretained(this))); 718 719 TestURLRequestContext context; 720 721 scoped_refptr<SocketStream> socket_stream( 722 new SocketStream(GURL("ws://example.com/demo"), delegate.get(), 723 &context, NULL)); 724 725 MockWrite data_writes[] = { 726 MockWrite(SocketStreamTest::kWebSocketHandshakeRequest), 727 MockWrite(ASYNC, "\0message1\xff", 10), 728 MockWrite(ASYNC, "\0message2\xff", 10) 729 }; 730 MockRead data_reads[] = { 731 MockRead(SocketStreamTest::kWebSocketHandshakeResponse), 732 // Server doesn't close the connection after handshake. 733 MockRead(ASYNC, ERR_IO_PENDING) 734 }; 735 AddWebSocketMessage("message1"); 736 AddWebSocketMessage("message2"); 737 738 DelayedSocketData data_provider( 739 1, data_reads, arraysize(data_reads), 740 data_writes, arraysize(data_writes)); 741 742 MockClientSocketFactory* mock_socket_factory = 743 GetMockClientSocketFactory(); 744 mock_socket_factory->AddSocketDataProvider(&data_provider); 745 746 socket_stream->SetClientSocketFactory(mock_socket_factory); 747 748 socket_stream->Connect(); 749 io_test_callback_.WaitForResult(); 750 EXPECT_EQ(SocketStream::STATE_RESOLVE_PROTOCOL_COMPLETE, 751 socket_stream->next_state_); 752 delegate->CompleteConnection(OK); 753 754 EXPECT_EQ(OK, test_callback.WaitForResult()); 755 756 EXPECT_TRUE(data_provider.at_read_eof()); 757 EXPECT_TRUE(data_provider.at_write_eof()); 758 759 const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents(); 760 ASSERT_EQ(7U, events.size()); 761 762 EXPECT_EQ(SocketStreamEvent::EVENT_START_OPEN_CONNECTION, 763 events[0].event_type); 764 EXPECT_EQ(SocketStreamEvent::EVENT_CONNECTED, events[1].event_type); 765 EXPECT_EQ(SocketStreamEvent::EVENT_SENT_DATA, events[2].event_type); 766 EXPECT_EQ(SocketStreamEvent::EVENT_RECEIVED_DATA, events[3].event_type); 767 EXPECT_EQ(SocketStreamEvent::EVENT_SENT_DATA, events[4].event_type); 768 EXPECT_EQ(SocketStreamEvent::EVENT_SENT_DATA, events[5].event_type); 769 EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE, events[6].event_type); 770 } 771 772 TEST_F(SocketStreamTest, SwitchToSpdy) { 773 TestCompletionCallback test_callback; 774 775 scoped_ptr<SocketStreamEventRecorder> delegate( 776 new SocketStreamEventRecorder(test_callback.callback())); 777 delegate->SetOnStartOpenConnection(base::Bind( 778 &SocketStreamTest::DoSwitchToSpdyTest, base::Unretained(this))); 779 780 TestURLRequestContext context; 781 782 scoped_refptr<SocketStream> socket_stream( 783 new SocketStream(GURL("ws://example.com/demo"), delegate.get(), 784 &context, NULL)); 785 786 socket_stream->Connect(); 787 788 EXPECT_EQ(ERR_PROTOCOL_SWITCHED, test_callback.WaitForResult()); 789 790 const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents(); 791 ASSERT_EQ(2U, events.size()); 792 793 EXPECT_EQ(SocketStreamEvent::EVENT_START_OPEN_CONNECTION, 794 events[0].event_type); 795 EXPECT_EQ(SocketStreamEvent::EVENT_ERROR, events[1].event_type); 796 EXPECT_EQ(ERR_PROTOCOL_SWITCHED, events[1].error_code); 797 } 798 799 TEST_F(SocketStreamTest, SwitchAfterPending) { 800 TestCompletionCallback test_callback; 801 802 scoped_ptr<SocketStreamEventRecorder> delegate( 803 new SocketStreamEventRecorder(test_callback.callback())); 804 delegate->SetOnStartOpenConnection(base::Bind( 805 &SocketStreamTest::DoIOPending, base::Unretained(this))); 806 807 TestURLRequestContext context; 808 809 scoped_refptr<SocketStream> socket_stream( 810 new SocketStream(GURL("ws://example.com/demo"), delegate.get(), 811 &context, NULL)); 812 813 socket_stream->Connect(); 814 io_test_callback_.WaitForResult(); 815 816 EXPECT_EQ(SocketStream::STATE_RESOLVE_PROTOCOL_COMPLETE, 817 socket_stream->next_state_); 818 delegate->CompleteConnection(ERR_PROTOCOL_SWITCHED); 819 820 EXPECT_EQ(ERR_PROTOCOL_SWITCHED, test_callback.WaitForResult()); 821 822 const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents(); 823 ASSERT_EQ(2U, events.size()); 824 825 EXPECT_EQ(SocketStreamEvent::EVENT_START_OPEN_CONNECTION, 826 events[0].event_type); 827 EXPECT_EQ(SocketStreamEvent::EVENT_ERROR, events[1].event_type); 828 EXPECT_EQ(ERR_PROTOCOL_SWITCHED, events[1].error_code); 829 } 830 831 // Test a connection though a secure proxy. 832 TEST_F(SocketStreamTest, SecureProxyConnectError) { 833 MockClientSocketFactory mock_socket_factory; 834 MockWrite data_writes[] = { 835 MockWrite("CONNECT example.com:80 HTTP/1.1\r\n" 836 "Host: example.com\r\n" 837 "Proxy-Connection: keep-alive\r\n\r\n") 838 }; 839 MockRead data_reads[] = { 840 MockRead("HTTP/1.1 200 Connection Established\r\n"), 841 MockRead("Proxy-agent: Apache/2.2.8\r\n"), 842 MockRead("\r\n"), 843 // SocketStream::DoClose is run asynchronously. Socket can be read after 844 // "\r\n". We have to give ERR_IO_PENDING to SocketStream then to indicate 845 // server doesn't close the connection. 846 MockRead(ASYNC, ERR_IO_PENDING) 847 }; 848 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 849 data_writes, arraysize(data_writes)); 850 mock_socket_factory.AddSocketDataProvider(&data); 851 SSLSocketDataProvider ssl(SYNCHRONOUS, ERR_SSL_PROTOCOL_ERROR); 852 mock_socket_factory.AddSSLSocketDataProvider(&ssl); 853 854 TestCompletionCallback test_callback; 855 TestURLRequestContextWithProxy context("https://myproxy:70"); 856 857 scoped_ptr<SocketStreamEventRecorder> delegate( 858 new SocketStreamEventRecorder(test_callback.callback())); 859 delegate->SetOnConnected(base::Bind(&SocketStreamEventRecorder::DoClose, 860 base::Unretained(delegate.get()))); 861 862 scoped_refptr<SocketStream> socket_stream( 863 new SocketStream(GURL("ws://example.com/demo"), delegate.get(), 864 &context, NULL)); 865 866 socket_stream->SetClientSocketFactory(&mock_socket_factory); 867 868 socket_stream->Connect(); 869 870 test_callback.WaitForResult(); 871 872 const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents(); 873 ASSERT_EQ(3U, events.size()); 874 875 EXPECT_EQ(SocketStreamEvent::EVENT_START_OPEN_CONNECTION, 876 events[0].event_type); 877 EXPECT_EQ(SocketStreamEvent::EVENT_ERROR, events[1].event_type); 878 EXPECT_EQ(ERR_SSL_PROTOCOL_ERROR, events[1].error_code); 879 EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE, events[2].event_type); 880 } 881 882 // Test a connection though a secure proxy. 883 TEST_F(SocketStreamTest, SecureProxyConnect) { 884 MockClientSocketFactory mock_socket_factory; 885 MockWrite data_writes[] = { 886 MockWrite("CONNECT example.com:80 HTTP/1.1\r\n" 887 "Host: example.com\r\n" 888 "Proxy-Connection: keep-alive\r\n\r\n") 889 }; 890 MockRead data_reads[] = { 891 MockRead("HTTP/1.1 200 Connection Established\r\n"), 892 MockRead("Proxy-agent: Apache/2.2.8\r\n"), 893 MockRead("\r\n"), 894 // SocketStream::DoClose is run asynchronously. Socket can be read after 895 // "\r\n". We have to give ERR_IO_PENDING to SocketStream then to indicate 896 // server doesn't close the connection. 897 MockRead(ASYNC, ERR_IO_PENDING) 898 }; 899 StaticSocketDataProvider data(data_reads, arraysize(data_reads), 900 data_writes, arraysize(data_writes)); 901 mock_socket_factory.AddSocketDataProvider(&data); 902 SSLSocketDataProvider ssl(SYNCHRONOUS, OK); 903 mock_socket_factory.AddSSLSocketDataProvider(&ssl); 904 905 TestCompletionCallback test_callback; 906 TestURLRequestContextWithProxy context("https://myproxy:70"); 907 908 scoped_ptr<SocketStreamEventRecorder> delegate( 909 new SocketStreamEventRecorder(test_callback.callback())); 910 delegate->SetOnConnected(base::Bind(&SocketStreamEventRecorder::DoClose, 911 base::Unretained(delegate.get()))); 912 913 scoped_refptr<SocketStream> socket_stream( 914 new SocketStream(GURL("ws://example.com/demo"), delegate.get(), 915 &context, NULL)); 916 917 socket_stream->SetClientSocketFactory(&mock_socket_factory); 918 919 socket_stream->Connect(); 920 921 test_callback.WaitForResult(); 922 923 const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents(); 924 ASSERT_EQ(4U, events.size()); 925 926 EXPECT_EQ(SocketStreamEvent::EVENT_START_OPEN_CONNECTION, 927 events[0].event_type); 928 EXPECT_EQ(SocketStreamEvent::EVENT_CONNECTED, events[1].event_type); 929 EXPECT_EQ(SocketStreamEvent::EVENT_ERROR, events[2].event_type); 930 EXPECT_EQ(ERR_ABORTED, events[2].error_code); 931 EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE, events[3].event_type); 932 } 933 934 TEST_F(SocketStreamTest, BeforeConnectFailed) { 935 TestCompletionCallback test_callback; 936 937 scoped_ptr<SocketStreamEventRecorder> delegate( 938 new SocketStreamEventRecorder(test_callback.callback())); 939 940 TestURLRequestContext context; 941 TestSocketStreamNetworkDelegate network_delegate; 942 network_delegate.SetBeforeConnectResult(ERR_ACCESS_DENIED); 943 context.set_network_delegate(&network_delegate); 944 945 scoped_refptr<SocketStream> socket_stream( 946 new SocketStream(GURL("ws://example.com/demo"), delegate.get(), 947 &context, NULL)); 948 949 socket_stream->Connect(); 950 951 test_callback.WaitForResult(); 952 953 const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents(); 954 ASSERT_EQ(2U, events.size()); 955 956 EXPECT_EQ(SocketStreamEvent::EVENT_ERROR, events[0].event_type); 957 EXPECT_EQ(ERR_ACCESS_DENIED, events[0].error_code); 958 EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE, events[1].event_type); 959 } 960 961 // Check that a connect failure, followed by the delegate calling DetachDelegate 962 // and deleting itself in the OnError callback, is handled correctly. 963 TEST_F(SocketStreamTest, OnErrorDetachDelegate) { 964 MockClientSocketFactory mock_socket_factory; 965 TestCompletionCallback test_callback; 966 967 // SelfDeletingDelegate is self-owning; we just need a pointer to it to 968 // connect it and the SocketStream. 969 SelfDeletingDelegate* delegate = 970 new SelfDeletingDelegate(test_callback.callback()); 971 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED); 972 StaticSocketDataProvider data; 973 data.set_connect_data(mock_connect); 974 mock_socket_factory.AddSocketDataProvider(&data); 975 976 TestURLRequestContext context; 977 scoped_refptr<SocketStream> socket_stream( 978 new SocketStream(GURL("ws://localhost:9998/echo"), delegate, 979 &context, NULL)); 980 socket_stream->SetClientSocketFactory(&mock_socket_factory); 981 delegate->set_socket_stream(socket_stream); 982 // The delegate pointer will become invalid during the test. Set it to NULL to 983 // avoid holding a dangling pointer. 984 delegate = NULL; 985 986 socket_stream->Connect(); 987 988 EXPECT_EQ(OK, test_callback.WaitForResult()); 989 } 990 991 TEST_F(SocketStreamTest, NullContextSocketStreamShouldNotCrash) { 992 TestCompletionCallback test_callback; 993 994 scoped_ptr<SocketStreamEventRecorder> delegate( 995 new SocketStreamEventRecorder(test_callback.callback())); 996 TestURLRequestContext context; 997 scoped_refptr<SocketStream> socket_stream( 998 new SocketStream(GURL("ws://example.com/demo"), delegate.get(), 999 &context, NULL)); 1000 delegate->SetOnStartOpenConnection(base::Bind( 1001 &SocketStreamTest::DoIOPending, base::Unretained(this))); 1002 delegate->SetOnConnected(base::Bind( 1003 &SocketStreamTest::DoSendWebSocketHandshake, base::Unretained(this))); 1004 delegate->SetOnReceivedData(base::Bind( 1005 &SocketStreamTest::DoCloseFlushPendingWriteTestWithSetContextNull, 1006 base::Unretained(this))); 1007 1008 MockWrite data_writes[] = { 1009 MockWrite(SocketStreamTest::kWebSocketHandshakeRequest), 1010 }; 1011 MockRead data_reads[] = { 1012 MockRead(SocketStreamTest::kWebSocketHandshakeResponse), 1013 }; 1014 AddWebSocketMessage("message1"); 1015 AddWebSocketMessage("message2"); 1016 1017 DelayedSocketData data_provider( 1018 1, data_reads, arraysize(data_reads), 1019 data_writes, arraysize(data_writes)); 1020 1021 MockClientSocketFactory* mock_socket_factory = GetMockClientSocketFactory(); 1022 mock_socket_factory->AddSocketDataProvider(&data_provider); 1023 socket_stream->SetClientSocketFactory(mock_socket_factory); 1024 1025 socket_stream->Connect(); 1026 io_test_callback_.WaitForResult(); 1027 delegate->CompleteConnection(OK); 1028 EXPECT_EQ(OK, test_callback.WaitForResult()); 1029 1030 EXPECT_TRUE(data_provider.at_read_eof()); 1031 EXPECT_TRUE(data_provider.at_write_eof()); 1032 1033 const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents(); 1034 ASSERT_EQ(5U, events.size()); 1035 1036 EXPECT_EQ(SocketStreamEvent::EVENT_START_OPEN_CONNECTION, 1037 events[0].event_type); 1038 EXPECT_EQ(SocketStreamEvent::EVENT_CONNECTED, events[1].event_type); 1039 EXPECT_EQ(SocketStreamEvent::EVENT_SENT_DATA, events[2].event_type); 1040 EXPECT_EQ(SocketStreamEvent::EVENT_RECEIVED_DATA, events[3].event_type); 1041 EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE, events[4].event_type); 1042 } 1043 1044 } // namespace net 1045