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.
5 #include "net/socket_stream/socket_stream.h"
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"
26 using base::ASCIIToUTF16;
32 struct SocketStreamEvent {
34 EVENT_START_OPEN_CONNECTION, EVENT_CONNECTED, EVENT_SENT_DATA,
35 EVENT_RECEIVED_DATA, EVENT_CLOSE, EVENT_AUTH_REQUIRED, EVENT_ERROR,
38 SocketStreamEvent(EventType type,
39 SocketStream* socket_stream,
41 const std::string& str,
42 AuthChallengeInfo* auth_challenge_info,
44 : event_type(type), socket(socket_stream), number(num), data(str),
45 auth_info(auth_challenge_info), error_code(error) {}
51 scoped_refptr<AuthChallengeInfo> auth_info;
55 class SocketStreamEventRecorder : public SocketStream::Delegate {
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 ~SocketStreamEventRecorder() override {}
64 void SetOnStartOpenConnection(
65 const base::Callback<int(SocketStreamEvent*)>& callback) {
66 on_start_open_connection_ = callback;
69 const base::Callback<void(SocketStreamEvent*)>& callback) {
70 on_connected_ = callback;
73 const base::Callback<void(SocketStreamEvent*)>& callback) {
74 on_sent_data_ = callback;
76 void SetOnReceivedData(
77 const base::Callback<void(SocketStreamEvent*)>& callback) {
78 on_received_data_ = callback;
80 void SetOnClose(const base::Callback<void(SocketStreamEvent*)>& callback) {
83 void SetOnAuthRequired(
84 const base::Callback<void(SocketStreamEvent*)>& callback) {
85 on_auth_required_ = callback;
87 void SetOnError(const base::Callback<void(SocketStreamEvent*)>& callback) {
91 int OnStartOpenConnection(SocketStream* socket,
92 const CompletionCallback& callback) override {
93 connection_callback_ = callback;
95 SocketStreamEvent(SocketStreamEvent::EVENT_START_OPEN_CONNECTION,
96 socket, 0, std::string(), NULL, OK));
97 if (!on_start_open_connection_.is_null())
98 return on_start_open_connection_.Run(&events_.back());
101 void OnConnected(SocketStream* socket,
102 int num_pending_send_allowed) override {
104 SocketStreamEvent(SocketStreamEvent::EVENT_CONNECTED,
105 socket, num_pending_send_allowed, std::string(),
107 if (!on_connected_.is_null())
108 on_connected_.Run(&events_.back());
110 void OnSentData(SocketStream* socket, int amount_sent) override {
112 SocketStreamEvent(SocketStreamEvent::EVENT_SENT_DATA, socket,
113 amount_sent, std::string(), NULL, OK));
114 if (!on_sent_data_.is_null())
115 on_sent_data_.Run(&events_.back());
117 void OnReceivedData(SocketStream* socket,
121 SocketStreamEvent(SocketStreamEvent::EVENT_RECEIVED_DATA, socket, len,
122 std::string(data, len), NULL, OK));
123 if (!on_received_data_.is_null())
124 on_received_data_.Run(&events_.back());
126 void OnClose(SocketStream* socket) override {
128 SocketStreamEvent(SocketStreamEvent::EVENT_CLOSE, socket, 0,
129 std::string(), NULL, OK));
130 if (!on_close_.is_null())
131 on_close_.Run(&events_.back());
132 if (!callback_.is_null())
135 void OnAuthRequired(SocketStream* socket,
136 AuthChallengeInfo* auth_info) override {
138 SocketStreamEvent(SocketStreamEvent::EVENT_AUTH_REQUIRED, socket, 0,
139 std::string(), auth_info, OK));
140 if (!on_auth_required_.is_null())
141 on_auth_required_.Run(&events_.back());
143 void OnError(const SocketStream* socket, int error) override {
145 SocketStreamEvent(SocketStreamEvent::EVENT_ERROR, NULL, 0,
146 std::string(), NULL, error));
147 if (!on_error_.is_null())
148 on_error_.Run(&events_.back());
149 if (!callback_.is_null())
150 callback_.Run(error);
153 void DoClose(SocketStreamEvent* event) {
154 event->socket->Close();
156 void DoRestartWithAuth(SocketStreamEvent* event) {
157 VLOG(1) << "RestartWithAuth username=" << credentials_.username()
158 << " password=" << credentials_.password();
159 event->socket->RestartWithAuth(credentials_);
161 void SetAuthInfo(const AuthCredentials& credentials) {
162 credentials_ = credentials;
164 // Wakes up the SocketStream waiting for completion of OnStartOpenConnection()
166 void CompleteConnection(int result) {
167 connection_callback_.Run(result);
170 const std::vector<SocketStreamEvent>& GetSeenEvents() const {
175 std::vector<SocketStreamEvent> events_;
176 base::Callback<int(SocketStreamEvent*)> on_start_open_connection_;
177 base::Callback<void(SocketStreamEvent*)> on_connected_;
178 base::Callback<void(SocketStreamEvent*)> on_sent_data_;
179 base::Callback<void(SocketStreamEvent*)> on_received_data_;
180 base::Callback<void(SocketStreamEvent*)> on_close_;
181 base::Callback<void(SocketStreamEvent*)> on_auth_required_;
182 base::Callback<void(SocketStreamEvent*)> on_error_;
183 const CompletionCallback callback_;
184 CompletionCallback connection_callback_;
185 AuthCredentials credentials_;
187 DISALLOW_COPY_AND_ASSIGN(SocketStreamEventRecorder);
190 // This is used for the test OnErrorDetachDelegate.
191 class SelfDeletingDelegate : public SocketStream::Delegate {
193 // |callback| must cause the test message loop to exit when called.
194 explicit SelfDeletingDelegate(const CompletionCallback& callback)
195 : socket_stream_(), callback_(callback) {}
197 ~SelfDeletingDelegate() override {}
199 // Call DetachDelegate(), delete |this|, then run the callback.
200 void OnError(const SocketStream* socket, int error) override {
201 // callback_ will be deleted when we delete |this|, so copy it to call it
203 CompletionCallback callback = callback_;
204 socket_stream_->DetachDelegate();
209 // This can't be passed in the constructor because this object needs to be
210 // created before SocketStream.
211 void set_socket_stream(const scoped_refptr<SocketStream>& socket_stream) {
212 socket_stream_ = socket_stream;
213 EXPECT_EQ(socket_stream_->delegate(), this);
216 void OnConnected(SocketStream* socket,
217 int max_pending_send_allowed) override {
218 ADD_FAILURE() << "OnConnected() should not be called";
220 void OnSentData(SocketStream* socket, int amount_sent) override {
221 ADD_FAILURE() << "OnSentData() should not be called";
223 void OnReceivedData(SocketStream* socket,
226 ADD_FAILURE() << "OnReceivedData() should not be called";
228 void OnClose(SocketStream* socket) override {
229 ADD_FAILURE() << "OnClose() should not be called";
233 scoped_refptr<SocketStream> socket_stream_;
234 const CompletionCallback callback_;
236 DISALLOW_COPY_AND_ASSIGN(SelfDeletingDelegate);
239 class TestURLRequestContextWithProxy : public TestURLRequestContext {
241 explicit TestURLRequestContextWithProxy(const std::string& proxy)
242 : TestURLRequestContext(true) {
243 context_storage_.set_proxy_service(ProxyService::CreateFixed(proxy));
246 ~TestURLRequestContextWithProxy() override {}
249 class TestSocketStreamNetworkDelegate : public TestNetworkDelegate {
251 TestSocketStreamNetworkDelegate()
252 : before_connect_result_(OK) {}
253 ~TestSocketStreamNetworkDelegate() override {}
255 int OnBeforeSocketStreamConnect(SocketStream* stream,
256 const CompletionCallback& callback) override {
257 return before_connect_result_;
260 void SetBeforeConnectResult(int result) {
261 before_connect_result_ = result;
265 int before_connect_result_;
270 class SocketStreamTest : public PlatformTest {
272 ~SocketStreamTest() override {}
273 void SetUp() override {
274 mock_socket_factory_.reset();
275 handshake_request_ = kWebSocketHandshakeRequest;
276 handshake_response_ = kWebSocketHandshakeResponse;
278 void TearDown() override { mock_socket_factory_.reset(); }
280 virtual void SetWebSocketHandshakeMessage(
281 const char* request, const char* response) {
282 handshake_request_ = request;
283 handshake_response_ = response;
285 virtual void AddWebSocketMessage(const std::string& message) {
286 messages_.push_back(message);
289 virtual MockClientSocketFactory* GetMockClientSocketFactory() {
290 mock_socket_factory_.reset(new MockClientSocketFactory);
291 return mock_socket_factory_.get();
294 // Functions for SocketStreamEventRecorder to handle calls to the
295 // SocketStream::Delegate methods from the SocketStream.
297 virtual void DoSendWebSocketHandshake(SocketStreamEvent* event) {
298 event->socket->SendData(
299 handshake_request_.data(), handshake_request_.size());
302 virtual void DoCloseFlushPendingWriteTest(SocketStreamEvent* event) {
303 // handshake response received.
304 for (size_t i = 0; i < messages_.size(); i++) {
305 std::vector<char> frame;
306 frame.push_back('\0');
307 frame.insert(frame.end(), messages_[i].begin(), messages_[i].end());
308 frame.push_back('\xff');
309 EXPECT_TRUE(event->socket->SendData(&frame[0], frame.size()));
311 // Actual StreamSocket close must happen after all frames queued by
312 // SendData above are sent out.
313 event->socket->Close();
316 virtual void DoCloseFlushPendingWriteTestWithSetContextNull(
317 SocketStreamEvent* event) {
318 event->socket->DetachContext();
319 // handshake response received.
320 for (size_t i = 0; i < messages_.size(); i++) {
321 std::vector<char> frame;
322 frame.push_back('\0');
323 frame.insert(frame.end(), messages_[i].begin(), messages_[i].end());
324 frame.push_back('\xff');
325 EXPECT_TRUE(event->socket->SendData(&frame[0], frame.size()));
327 // Actual StreamSocket close must happen after all frames queued by
328 // SendData above are sent out.
329 event->socket->Close();
332 virtual void DoFailByTooBigDataAndClose(SocketStreamEvent* event) {
333 std::string frame(event->number + 1, 0x00);
334 VLOG(1) << event->number;
335 EXPECT_FALSE(event->socket->SendData(&frame[0], frame.size()));
336 event->socket->Close();
339 virtual int DoSwitchToSpdyTest(SocketStreamEvent* event) {
340 return ERR_PROTOCOL_SWITCHED;
343 // Notifies |io_test_callback_| of that this method is called, and keeps the
344 // SocketStream waiting.
345 virtual int DoIOPending(SocketStreamEvent* event) {
346 io_test_callback_.callback().Run(OK);
347 return ERR_IO_PENDING;
350 static const char kWebSocketHandshakeRequest[];
351 static const char kWebSocketHandshakeResponse[];
354 TestCompletionCallback io_test_callback_;
357 std::string handshake_request_;
358 std::string handshake_response_;
359 std::vector<std::string> messages_;
361 scoped_ptr<MockClientSocketFactory> mock_socket_factory_;
364 const char SocketStreamTest::kWebSocketHandshakeRequest[] =
365 "GET /demo HTTP/1.1\r\n"
366 "Host: example.com\r\n"
367 "Connection: Upgrade\r\n"
368 "Sec-WebSocket-Key2: 12998 5 Y3 1 .P00\r\n"
369 "Sec-WebSocket-Protocol: sample\r\n"
370 "Upgrade: WebSocket\r\n"
371 "Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5\r\n"
372 "Origin: http://example.com\r\n"
376 const char SocketStreamTest::kWebSocketHandshakeResponse[] =
377 "HTTP/1.1 101 WebSocket Protocol Handshake\r\n"
378 "Upgrade: WebSocket\r\n"
379 "Connection: Upgrade\r\n"
380 "Sec-WebSocket-Origin: http://example.com\r\n"
381 "Sec-WebSocket-Location: ws://example.com/demo\r\n"
382 "Sec-WebSocket-Protocol: sample\r\n"
386 TEST_F(SocketStreamTest, CloseFlushPendingWrite) {
387 TestCompletionCallback test_callback;
389 scoped_ptr<SocketStreamEventRecorder> delegate(
390 new SocketStreamEventRecorder(test_callback.callback()));
391 delegate->SetOnConnected(base::Bind(
392 &SocketStreamTest::DoSendWebSocketHandshake, base::Unretained(this)));
393 delegate->SetOnReceivedData(base::Bind(
394 &SocketStreamTest::DoCloseFlushPendingWriteTest,
395 base::Unretained(this)));
397 TestURLRequestContext context;
399 scoped_refptr<SocketStream> socket_stream(
400 new SocketStream(GURL("ws://example.com/demo"), delegate.get(),
403 MockWrite data_writes[] = {
404 MockWrite(SocketStreamTest::kWebSocketHandshakeRequest),
405 MockWrite(ASYNC, "\0message1\xff", 10),
406 MockWrite(ASYNC, "\0message2\xff", 10)
408 MockRead data_reads[] = {
409 MockRead(SocketStreamTest::kWebSocketHandshakeResponse),
410 // Server doesn't close the connection after handshake.
411 MockRead(ASYNC, ERR_IO_PENDING)
413 AddWebSocketMessage("message1");
414 AddWebSocketMessage("message2");
416 DelayedSocketData data_provider(
417 1, data_reads, arraysize(data_reads),
418 data_writes, arraysize(data_writes));
420 MockClientSocketFactory* mock_socket_factory =
421 GetMockClientSocketFactory();
422 mock_socket_factory->AddSocketDataProvider(&data_provider);
424 socket_stream->SetClientSocketFactory(mock_socket_factory);
426 socket_stream->Connect();
428 test_callback.WaitForResult();
430 EXPECT_TRUE(data_provider.at_read_eof());
431 EXPECT_TRUE(data_provider.at_write_eof());
433 const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents();
434 ASSERT_EQ(7U, events.size());
436 EXPECT_EQ(SocketStreamEvent::EVENT_START_OPEN_CONNECTION,
437 events[0].event_type);
438 EXPECT_EQ(SocketStreamEvent::EVENT_CONNECTED, events[1].event_type);
439 EXPECT_EQ(SocketStreamEvent::EVENT_SENT_DATA, events[2].event_type);
440 EXPECT_EQ(SocketStreamEvent::EVENT_RECEIVED_DATA, events[3].event_type);
441 EXPECT_EQ(SocketStreamEvent::EVENT_SENT_DATA, events[4].event_type);
442 EXPECT_EQ(SocketStreamEvent::EVENT_SENT_DATA, events[5].event_type);
443 EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE, events[6].event_type);
446 TEST_F(SocketStreamTest, ResolveFailure) {
447 TestCompletionCallback test_callback;
449 scoped_ptr<SocketStreamEventRecorder> delegate(
450 new SocketStreamEventRecorder(test_callback.callback()));
452 // Make resolver fail.
453 TestURLRequestContext context;
454 scoped_ptr<MockHostResolver> mock_host_resolver(
455 new MockHostResolver());
456 mock_host_resolver->rules()->AddSimulatedFailure("example.com");
457 context.set_host_resolver(mock_host_resolver.get());
459 scoped_refptr<SocketStream> socket_stream(
460 new SocketStream(GURL("ws://example.com/demo"), delegate.get(),
463 // No read/write on socket is expected.
464 StaticSocketDataProvider data_provider(NULL, 0, NULL, 0);
465 MockClientSocketFactory* mock_socket_factory =
466 GetMockClientSocketFactory();
467 mock_socket_factory->AddSocketDataProvider(&data_provider);
468 socket_stream->SetClientSocketFactory(mock_socket_factory);
470 socket_stream->Connect();
472 test_callback.WaitForResult();
474 const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents();
475 ASSERT_EQ(2U, events.size());
477 EXPECT_EQ(SocketStreamEvent::EVENT_ERROR, events[0].event_type);
478 EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE, events[1].event_type);
481 TEST_F(SocketStreamTest, ExceedMaxPendingSendAllowed) {
482 TestCompletionCallback test_callback;
484 scoped_ptr<SocketStreamEventRecorder> delegate(
485 new SocketStreamEventRecorder(test_callback.callback()));
486 delegate->SetOnConnected(base::Bind(
487 &SocketStreamTest::DoFailByTooBigDataAndClose, base::Unretained(this)));
489 TestURLRequestContext context;
491 scoped_refptr<SocketStream> socket_stream(
492 new SocketStream(GURL("ws://example.com/demo"), delegate.get(),
495 DelayedSocketData data_provider(1, NULL, 0, NULL, 0);
497 MockClientSocketFactory* mock_socket_factory =
498 GetMockClientSocketFactory();
499 mock_socket_factory->AddSocketDataProvider(&data_provider);
501 socket_stream->SetClientSocketFactory(mock_socket_factory);
503 socket_stream->Connect();
505 test_callback.WaitForResult();
507 const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents();
508 ASSERT_EQ(4U, events.size());
510 EXPECT_EQ(SocketStreamEvent::EVENT_START_OPEN_CONNECTION,
511 events[0].event_type);
512 EXPECT_EQ(SocketStreamEvent::EVENT_CONNECTED, events[1].event_type);
513 EXPECT_EQ(SocketStreamEvent::EVENT_ERROR, events[2].event_type);
514 EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE, events[3].event_type);
517 TEST_F(SocketStreamTest, BasicAuthProxy) {
518 MockClientSocketFactory mock_socket_factory;
519 MockWrite data_writes1[] = {
520 MockWrite("CONNECT example.com:80 HTTP/1.1\r\n"
521 "Host: example.com\r\n"
522 "Proxy-Connection: keep-alive\r\n\r\n"),
524 MockRead data_reads1[] = {
525 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
526 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
529 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
530 data_writes1, arraysize(data_writes1));
531 mock_socket_factory.AddSocketDataProvider(&data1);
533 MockWrite data_writes2[] = {
534 MockWrite("CONNECT example.com:80 HTTP/1.1\r\n"
535 "Host: example.com\r\n"
536 "Proxy-Connection: keep-alive\r\n"
537 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
539 MockRead data_reads2[] = {
540 MockRead("HTTP/1.1 200 Connection Established\r\n"),
541 MockRead("Proxy-agent: Apache/2.2.8\r\n"),
543 // SocketStream::DoClose is run asynchronously. Socket can be read after
544 // "\r\n". We have to give ERR_IO_PENDING to SocketStream then to indicate
545 // server doesn't close the connection.
546 MockRead(ASYNC, ERR_IO_PENDING)
548 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
549 data_writes2, arraysize(data_writes2));
550 mock_socket_factory.AddSocketDataProvider(&data2);
552 TestCompletionCallback test_callback;
554 scoped_ptr<SocketStreamEventRecorder> delegate(
555 new SocketStreamEventRecorder(test_callback.callback()));
556 delegate->SetOnConnected(base::Bind(&SocketStreamEventRecorder::DoClose,
557 base::Unretained(delegate.get())));
558 delegate->SetAuthInfo(AuthCredentials(ASCIIToUTF16("foo"),
559 ASCIIToUTF16("bar")));
560 delegate->SetOnAuthRequired(base::Bind(
561 &SocketStreamEventRecorder::DoRestartWithAuth,
562 base::Unretained(delegate.get())));
564 TestURLRequestContextWithProxy context("myproxy:70");
566 scoped_refptr<SocketStream> socket_stream(
567 new SocketStream(GURL("ws://example.com/demo"), delegate.get(),
570 socket_stream->SetClientSocketFactory(&mock_socket_factory);
572 socket_stream->Connect();
574 test_callback.WaitForResult();
576 const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents();
577 ASSERT_EQ(5U, events.size());
579 EXPECT_EQ(SocketStreamEvent::EVENT_START_OPEN_CONNECTION,
580 events[0].event_type);
581 EXPECT_EQ(SocketStreamEvent::EVENT_AUTH_REQUIRED, events[1].event_type);
582 EXPECT_EQ(SocketStreamEvent::EVENT_CONNECTED, events[2].event_type);
583 EXPECT_EQ(SocketStreamEvent::EVENT_ERROR, events[3].event_type);
584 EXPECT_EQ(ERR_ABORTED, events[3].error_code);
585 EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE, events[4].event_type);
587 // TODO(eroman): Add back NetLogTest here...
590 TEST_F(SocketStreamTest, BasicAuthProxyWithAuthCache) {
591 MockClientSocketFactory mock_socket_factory;
592 MockWrite data_writes[] = {
593 // WebSocket(SocketStream) always uses CONNECT when it is configured to use
594 // proxy so the port may not be 443.
595 MockWrite("CONNECT example.com:80 HTTP/1.1\r\n"
596 "Host: example.com\r\n"
597 "Proxy-Connection: keep-alive\r\n"
598 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
600 MockRead data_reads[] = {
601 MockRead("HTTP/1.1 200 Connection Established\r\n"),
602 MockRead("Proxy-agent: Apache/2.2.8\r\n"),
604 MockRead(ASYNC, ERR_IO_PENDING)
606 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
607 data_writes, arraysize(data_writes));
608 mock_socket_factory.AddSocketDataProvider(&data);
610 TestCompletionCallback test_callback;
611 scoped_ptr<SocketStreamEventRecorder> delegate(
612 new SocketStreamEventRecorder(test_callback.callback()));
613 delegate->SetOnConnected(base::Bind(&SocketStreamEventRecorder::DoClose,
614 base::Unretained(delegate.get())));
616 TestURLRequestContextWithProxy context("myproxy:70");
617 HttpAuthCache* auth_cache =
618 context.http_transaction_factory()->GetSession()->http_auth_cache();
619 auth_cache->Add(GURL("http://myproxy:70"),
621 HttpAuth::AUTH_SCHEME_BASIC,
622 "Basic realm=MyRealm1",
623 AuthCredentials(ASCIIToUTF16("foo"),
624 ASCIIToUTF16("bar")),
627 scoped_refptr<SocketStream> socket_stream(
628 new SocketStream(GURL("ws://example.com/demo"), delegate.get(),
631 socket_stream->SetClientSocketFactory(&mock_socket_factory);
633 socket_stream->Connect();
635 test_callback.WaitForResult();
637 const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents();
638 ASSERT_EQ(4U, events.size());
639 EXPECT_EQ(SocketStreamEvent::EVENT_START_OPEN_CONNECTION,
640 events[0].event_type);
641 EXPECT_EQ(SocketStreamEvent::EVENT_CONNECTED, events[1].event_type);
642 EXPECT_EQ(ERR_ABORTED, events[2].error_code);
643 EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE, events[3].event_type);
646 TEST_F(SocketStreamTest, WSSBasicAuthProxyWithAuthCache) {
647 MockClientSocketFactory mock_socket_factory;
648 MockWrite data_writes1[] = {
649 MockWrite("CONNECT example.com:443 HTTP/1.1\r\n"
650 "Host: example.com\r\n"
651 "Proxy-Connection: keep-alive\r\n"
652 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
654 MockRead data_reads1[] = {
655 MockRead("HTTP/1.1 200 Connection Established\r\n"),
656 MockRead("Proxy-agent: Apache/2.2.8\r\n"),
658 MockRead(ASYNC, ERR_IO_PENDING)
660 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
661 data_writes1, arraysize(data_writes1));
662 mock_socket_factory.AddSocketDataProvider(&data1);
664 SSLSocketDataProvider data2(ASYNC, OK);
665 mock_socket_factory.AddSSLSocketDataProvider(&data2);
667 TestCompletionCallback test_callback;
668 scoped_ptr<SocketStreamEventRecorder> delegate(
669 new SocketStreamEventRecorder(test_callback.callback()));
670 delegate->SetOnConnected(base::Bind(&SocketStreamEventRecorder::DoClose,
671 base::Unretained(delegate.get())));
673 TestURLRequestContextWithProxy context("myproxy:70");
674 HttpAuthCache* auth_cache =
675 context.http_transaction_factory()->GetSession()->http_auth_cache();
676 auth_cache->Add(GURL("http://myproxy:70"),
678 HttpAuth::AUTH_SCHEME_BASIC,
679 "Basic realm=MyRealm1",
680 AuthCredentials(ASCIIToUTF16("foo"),
681 ASCIIToUTF16("bar")),
684 scoped_refptr<SocketStream> socket_stream(
685 new SocketStream(GURL("wss://example.com/demo"), delegate.get(),
688 socket_stream->SetClientSocketFactory(&mock_socket_factory);
690 socket_stream->Connect();
692 test_callback.WaitForResult();
694 const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents();
695 ASSERT_EQ(4U, events.size());
696 EXPECT_EQ(SocketStreamEvent::EVENT_START_OPEN_CONNECTION,
697 events[0].event_type);
698 EXPECT_EQ(SocketStreamEvent::EVENT_CONNECTED, events[1].event_type);
699 EXPECT_EQ(ERR_ABORTED, events[2].error_code);
700 EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE, events[3].event_type);
703 TEST_F(SocketStreamTest, IOPending) {
704 TestCompletionCallback test_callback;
706 scoped_ptr<SocketStreamEventRecorder> delegate(
707 new SocketStreamEventRecorder(test_callback.callback()));
708 delegate->SetOnStartOpenConnection(base::Bind(
709 &SocketStreamTest::DoIOPending, base::Unretained(this)));
710 delegate->SetOnConnected(base::Bind(
711 &SocketStreamTest::DoSendWebSocketHandshake, base::Unretained(this)));
712 delegate->SetOnReceivedData(base::Bind(
713 &SocketStreamTest::DoCloseFlushPendingWriteTest,
714 base::Unretained(this)));
716 TestURLRequestContext context;
718 scoped_refptr<SocketStream> socket_stream(
719 new SocketStream(GURL("ws://example.com/demo"), delegate.get(),
722 MockWrite data_writes[] = {
723 MockWrite(SocketStreamTest::kWebSocketHandshakeRequest),
724 MockWrite(ASYNC, "\0message1\xff", 10),
725 MockWrite(ASYNC, "\0message2\xff", 10)
727 MockRead data_reads[] = {
728 MockRead(SocketStreamTest::kWebSocketHandshakeResponse),
729 // Server doesn't close the connection after handshake.
730 MockRead(ASYNC, ERR_IO_PENDING)
732 AddWebSocketMessage("message1");
733 AddWebSocketMessage("message2");
735 DelayedSocketData data_provider(
736 1, data_reads, arraysize(data_reads),
737 data_writes, arraysize(data_writes));
739 MockClientSocketFactory* mock_socket_factory =
740 GetMockClientSocketFactory();
741 mock_socket_factory->AddSocketDataProvider(&data_provider);
743 socket_stream->SetClientSocketFactory(mock_socket_factory);
745 socket_stream->Connect();
746 io_test_callback_.WaitForResult();
747 EXPECT_EQ(SocketStream::STATE_RESOLVE_PROTOCOL_COMPLETE,
748 socket_stream->next_state_);
749 delegate->CompleteConnection(OK);
751 EXPECT_EQ(OK, test_callback.WaitForResult());
753 EXPECT_TRUE(data_provider.at_read_eof());
754 EXPECT_TRUE(data_provider.at_write_eof());
756 const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents();
757 ASSERT_EQ(7U, events.size());
759 EXPECT_EQ(SocketStreamEvent::EVENT_START_OPEN_CONNECTION,
760 events[0].event_type);
761 EXPECT_EQ(SocketStreamEvent::EVENT_CONNECTED, events[1].event_type);
762 EXPECT_EQ(SocketStreamEvent::EVENT_SENT_DATA, events[2].event_type);
763 EXPECT_EQ(SocketStreamEvent::EVENT_RECEIVED_DATA, events[3].event_type);
764 EXPECT_EQ(SocketStreamEvent::EVENT_SENT_DATA, events[4].event_type);
765 EXPECT_EQ(SocketStreamEvent::EVENT_SENT_DATA, events[5].event_type);
766 EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE, events[6].event_type);
769 TEST_F(SocketStreamTest, SwitchToSpdy) {
770 TestCompletionCallback test_callback;
772 scoped_ptr<SocketStreamEventRecorder> delegate(
773 new SocketStreamEventRecorder(test_callback.callback()));
774 delegate->SetOnStartOpenConnection(base::Bind(
775 &SocketStreamTest::DoSwitchToSpdyTest, base::Unretained(this)));
777 TestURLRequestContext context;
779 scoped_refptr<SocketStream> socket_stream(
780 new SocketStream(GURL("ws://example.com/demo"), delegate.get(),
783 socket_stream->Connect();
785 EXPECT_EQ(ERR_PROTOCOL_SWITCHED, test_callback.WaitForResult());
787 const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents();
788 ASSERT_EQ(2U, events.size());
790 EXPECT_EQ(SocketStreamEvent::EVENT_START_OPEN_CONNECTION,
791 events[0].event_type);
792 EXPECT_EQ(SocketStreamEvent::EVENT_ERROR, events[1].event_type);
793 EXPECT_EQ(ERR_PROTOCOL_SWITCHED, events[1].error_code);
796 TEST_F(SocketStreamTest, SwitchAfterPending) {
797 TestCompletionCallback test_callback;
799 scoped_ptr<SocketStreamEventRecorder> delegate(
800 new SocketStreamEventRecorder(test_callback.callback()));
801 delegate->SetOnStartOpenConnection(base::Bind(
802 &SocketStreamTest::DoIOPending, base::Unretained(this)));
804 TestURLRequestContext context;
806 scoped_refptr<SocketStream> socket_stream(
807 new SocketStream(GURL("ws://example.com/demo"), delegate.get(),
810 socket_stream->Connect();
811 io_test_callback_.WaitForResult();
813 EXPECT_EQ(SocketStream::STATE_RESOLVE_PROTOCOL_COMPLETE,
814 socket_stream->next_state_);
815 delegate->CompleteConnection(ERR_PROTOCOL_SWITCHED);
817 EXPECT_EQ(ERR_PROTOCOL_SWITCHED, test_callback.WaitForResult());
819 const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents();
820 ASSERT_EQ(2U, events.size());
822 EXPECT_EQ(SocketStreamEvent::EVENT_START_OPEN_CONNECTION,
823 events[0].event_type);
824 EXPECT_EQ(SocketStreamEvent::EVENT_ERROR, events[1].event_type);
825 EXPECT_EQ(ERR_PROTOCOL_SWITCHED, events[1].error_code);
828 // Test a connection though a secure proxy.
829 TEST_F(SocketStreamTest, SecureProxyConnectError) {
830 MockClientSocketFactory mock_socket_factory;
831 MockWrite data_writes[] = {
832 MockWrite("CONNECT example.com:80 HTTP/1.1\r\n"
833 "Host: example.com\r\n"
834 "Proxy-Connection: keep-alive\r\n\r\n")
836 MockRead data_reads[] = {
837 MockRead("HTTP/1.1 200 Connection Established\r\n"),
838 MockRead("Proxy-agent: Apache/2.2.8\r\n"),
840 // SocketStream::DoClose is run asynchronously. Socket can be read after
841 // "\r\n". We have to give ERR_IO_PENDING to SocketStream then to indicate
842 // server doesn't close the connection.
843 MockRead(ASYNC, ERR_IO_PENDING)
845 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
846 data_writes, arraysize(data_writes));
847 mock_socket_factory.AddSocketDataProvider(&data);
848 SSLSocketDataProvider ssl(SYNCHRONOUS, ERR_SSL_PROTOCOL_ERROR);
849 mock_socket_factory.AddSSLSocketDataProvider(&ssl);
851 TestCompletionCallback test_callback;
852 TestURLRequestContextWithProxy context("https://myproxy:70");
854 scoped_ptr<SocketStreamEventRecorder> delegate(
855 new SocketStreamEventRecorder(test_callback.callback()));
856 delegate->SetOnConnected(base::Bind(&SocketStreamEventRecorder::DoClose,
857 base::Unretained(delegate.get())));
859 scoped_refptr<SocketStream> socket_stream(
860 new SocketStream(GURL("ws://example.com/demo"), delegate.get(),
863 socket_stream->SetClientSocketFactory(&mock_socket_factory);
865 socket_stream->Connect();
867 test_callback.WaitForResult();
869 const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents();
870 ASSERT_EQ(3U, events.size());
872 EXPECT_EQ(SocketStreamEvent::EVENT_START_OPEN_CONNECTION,
873 events[0].event_type);
874 EXPECT_EQ(SocketStreamEvent::EVENT_ERROR, events[1].event_type);
875 EXPECT_EQ(ERR_SSL_PROTOCOL_ERROR, events[1].error_code);
876 EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE, events[2].event_type);
879 // Test a connection though a secure proxy.
880 TEST_F(SocketStreamTest, SecureProxyConnect) {
881 MockClientSocketFactory mock_socket_factory;
882 MockWrite data_writes[] = {
883 MockWrite("CONNECT example.com:80 HTTP/1.1\r\n"
884 "Host: example.com\r\n"
885 "Proxy-Connection: keep-alive\r\n\r\n")
887 MockRead data_reads[] = {
888 MockRead("HTTP/1.1 200 Connection Established\r\n"),
889 MockRead("Proxy-agent: Apache/2.2.8\r\n"),
891 // SocketStream::DoClose is run asynchronously. Socket can be read after
892 // "\r\n". We have to give ERR_IO_PENDING to SocketStream then to indicate
893 // server doesn't close the connection.
894 MockRead(ASYNC, ERR_IO_PENDING)
896 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
897 data_writes, arraysize(data_writes));
898 mock_socket_factory.AddSocketDataProvider(&data);
899 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
900 mock_socket_factory.AddSSLSocketDataProvider(&ssl);
902 TestCompletionCallback test_callback;
903 TestURLRequestContextWithProxy context("https://myproxy:70");
905 scoped_ptr<SocketStreamEventRecorder> delegate(
906 new SocketStreamEventRecorder(test_callback.callback()));
907 delegate->SetOnConnected(base::Bind(&SocketStreamEventRecorder::DoClose,
908 base::Unretained(delegate.get())));
910 scoped_refptr<SocketStream> socket_stream(
911 new SocketStream(GURL("ws://example.com/demo"), delegate.get(),
914 socket_stream->SetClientSocketFactory(&mock_socket_factory);
916 socket_stream->Connect();
918 test_callback.WaitForResult();
920 const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents();
921 ASSERT_EQ(4U, events.size());
923 EXPECT_EQ(SocketStreamEvent::EVENT_START_OPEN_CONNECTION,
924 events[0].event_type);
925 EXPECT_EQ(SocketStreamEvent::EVENT_CONNECTED, events[1].event_type);
926 EXPECT_EQ(SocketStreamEvent::EVENT_ERROR, events[2].event_type);
927 EXPECT_EQ(ERR_ABORTED, events[2].error_code);
928 EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE, events[3].event_type);
931 TEST_F(SocketStreamTest, BeforeConnectFailed) {
932 TestCompletionCallback test_callback;
934 scoped_ptr<SocketStreamEventRecorder> delegate(
935 new SocketStreamEventRecorder(test_callback.callback()));
937 TestURLRequestContext context;
938 TestSocketStreamNetworkDelegate network_delegate;
939 network_delegate.SetBeforeConnectResult(ERR_ACCESS_DENIED);
940 context.set_network_delegate(&network_delegate);
942 scoped_refptr<SocketStream> socket_stream(
943 new SocketStream(GURL("ws://example.com/demo"), delegate.get(),
946 socket_stream->Connect();
948 test_callback.WaitForResult();
950 const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents();
951 ASSERT_EQ(2U, events.size());
953 EXPECT_EQ(SocketStreamEvent::EVENT_ERROR, events[0].event_type);
954 EXPECT_EQ(ERR_ACCESS_DENIED, events[0].error_code);
955 EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE, events[1].event_type);
958 // Check that a connect failure, followed by the delegate calling DetachDelegate
959 // and deleting itself in the OnError callback, is handled correctly.
960 TEST_F(SocketStreamTest, OnErrorDetachDelegate) {
961 MockClientSocketFactory mock_socket_factory;
962 TestCompletionCallback test_callback;
964 // SelfDeletingDelegate is self-owning; we just need a pointer to it to
965 // connect it and the SocketStream.
966 SelfDeletingDelegate* delegate =
967 new SelfDeletingDelegate(test_callback.callback());
968 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
969 StaticSocketDataProvider data;
970 data.set_connect_data(mock_connect);
971 mock_socket_factory.AddSocketDataProvider(&data);
973 TestURLRequestContext context;
974 scoped_refptr<SocketStream> socket_stream(
975 new SocketStream(GURL("ws://localhost:9998/echo"), delegate,
977 socket_stream->SetClientSocketFactory(&mock_socket_factory);
978 delegate->set_socket_stream(socket_stream);
979 // The delegate pointer will become invalid during the test. Set it to NULL to
980 // avoid holding a dangling pointer.
983 socket_stream->Connect();
985 EXPECT_EQ(OK, test_callback.WaitForResult());
988 TEST_F(SocketStreamTest, NullContextSocketStreamShouldNotCrash) {
989 TestCompletionCallback test_callback;
991 scoped_ptr<SocketStreamEventRecorder> delegate(
992 new SocketStreamEventRecorder(test_callback.callback()));
993 TestURLRequestContext context;
994 scoped_refptr<SocketStream> socket_stream(
995 new SocketStream(GURL("ws://example.com/demo"), delegate.get(),
997 delegate->SetOnStartOpenConnection(base::Bind(
998 &SocketStreamTest::DoIOPending, base::Unretained(this)));
999 delegate->SetOnConnected(base::Bind(
1000 &SocketStreamTest::DoSendWebSocketHandshake, base::Unretained(this)));
1001 delegate->SetOnReceivedData(base::Bind(
1002 &SocketStreamTest::DoCloseFlushPendingWriteTestWithSetContextNull,
1003 base::Unretained(this)));
1005 MockWrite data_writes[] = {
1006 MockWrite(SocketStreamTest::kWebSocketHandshakeRequest),
1008 MockRead data_reads[] = {
1009 MockRead(SocketStreamTest::kWebSocketHandshakeResponse),
1011 AddWebSocketMessage("message1");
1012 AddWebSocketMessage("message2");
1014 DelayedSocketData data_provider(
1015 1, data_reads, arraysize(data_reads),
1016 data_writes, arraysize(data_writes));
1018 MockClientSocketFactory* mock_socket_factory = GetMockClientSocketFactory();
1019 mock_socket_factory->AddSocketDataProvider(&data_provider);
1020 socket_stream->SetClientSocketFactory(mock_socket_factory);
1022 socket_stream->Connect();
1023 io_test_callback_.WaitForResult();
1024 delegate->CompleteConnection(OK);
1025 EXPECT_EQ(OK, test_callback.WaitForResult());
1027 EXPECT_TRUE(data_provider.at_read_eof());
1028 EXPECT_TRUE(data_provider.at_write_eof());
1030 const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents();
1031 ASSERT_EQ(5U, events.size());
1033 EXPECT_EQ(SocketStreamEvent::EVENT_START_OPEN_CONNECTION,
1034 events[0].event_type);
1035 EXPECT_EQ(SocketStreamEvent::EVENT_CONNECTED, events[1].event_type);
1036 EXPECT_EQ(SocketStreamEvent::EVENT_SENT_DATA, events[2].event_type);
1037 EXPECT_EQ(SocketStreamEvent::EVENT_RECEIVED_DATA, events[3].event_type);
1038 EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE, events[4].event_type);