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 virtual ~SocketStreamEventRecorder() {}
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 virtual int OnStartOpenConnection(
93 const CompletionCallback
& callback
) OVERRIDE
{
94 connection_callback_
= callback
;
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());
102 virtual void OnConnected(SocketStream
* socket
,
103 int num_pending_send_allowed
) OVERRIDE
{
105 SocketStreamEvent(SocketStreamEvent::EVENT_CONNECTED
,
106 socket
, num_pending_send_allowed
, std::string(),
108 if (!on_connected_
.is_null())
109 on_connected_
.Run(&events_
.back());
111 virtual void OnSentData(SocketStream
* socket
,
112 int amount_sent
) OVERRIDE
{
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());
119 virtual void OnReceivedData(SocketStream
* socket
,
120 const char* data
, int len
) OVERRIDE
{
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());
127 virtual void OnClose(SocketStream
* socket
) OVERRIDE
{
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())
136 virtual void OnAuthRequired(SocketStream
* socket
,
137 AuthChallengeInfo
* auth_info
) OVERRIDE
{
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());
144 virtual void OnError(const SocketStream
* socket
, int error
) OVERRIDE
{
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
);
154 void DoClose(SocketStreamEvent
* event
) {
155 event
->socket
->Close();
157 void DoRestartWithAuth(SocketStreamEvent
* event
) {
158 VLOG(1) << "RestartWithAuth username=" << credentials_
.username()
159 << " password=" << credentials_
.password();
160 event
->socket
->RestartWithAuth(credentials_
);
162 void SetAuthInfo(const AuthCredentials
& credentials
) {
163 credentials_
= credentials
;
165 // Wakes up the SocketStream waiting for completion of OnStartOpenConnection()
167 void CompleteConnection(int result
) {
168 connection_callback_
.Run(result
);
171 const std::vector
<SocketStreamEvent
>& GetSeenEvents() const {
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_
;
188 DISALLOW_COPY_AND_ASSIGN(SocketStreamEventRecorder
);
191 // This is used for the test OnErrorDetachDelegate.
192 class SelfDeletingDelegate
: public SocketStream::Delegate
{
194 // |callback| must cause the test message loop to exit when called.
195 explicit SelfDeletingDelegate(const CompletionCallback
& callback
)
196 : socket_stream_(), callback_(callback
) {}
198 virtual ~SelfDeletingDelegate() {}
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
204 CompletionCallback callback
= callback_
;
205 socket_stream_
->DetachDelegate();
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);
217 virtual void OnConnected(SocketStream
* socket
, int max_pending_send_allowed
)
219 ADD_FAILURE() << "OnConnected() should not be called";
221 virtual void OnSentData(SocketStream
* socket
, int amount_sent
) OVERRIDE
{
222 ADD_FAILURE() << "OnSentData() should not be called";
224 virtual void OnReceivedData(SocketStream
* socket
, const char* data
, int len
)
226 ADD_FAILURE() << "OnReceivedData() should not be called";
228 virtual 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 virtual ~TestURLRequestContextWithProxy() {}
249 class TestSocketStreamNetworkDelegate
: public TestNetworkDelegate
{
251 TestSocketStreamNetworkDelegate()
252 : before_connect_result_(OK
) {}
253 virtual ~TestSocketStreamNetworkDelegate() {}
255 virtual int OnBeforeSocketStreamConnect(
256 SocketStream
* stream
,
257 const CompletionCallback
& callback
) OVERRIDE
{
258 return before_connect_result_
;
261 void SetBeforeConnectResult(int result
) {
262 before_connect_result_
= result
;
266 int before_connect_result_
;
271 class SocketStreamTest
: public PlatformTest
{
273 virtual ~SocketStreamTest() {}
274 virtual void SetUp() {
275 mock_socket_factory_
.reset();
276 handshake_request_
= kWebSocketHandshakeRequest
;
277 handshake_response_
= kWebSocketHandshakeResponse
;
279 virtual void TearDown() {
280 mock_socket_factory_
.reset();
283 virtual void SetWebSocketHandshakeMessage(
284 const char* request
, const char* response
) {
285 handshake_request_
= request
;
286 handshake_response_
= response
;
288 virtual void AddWebSocketMessage(const std::string
& message
) {
289 messages_
.push_back(message
);
292 virtual MockClientSocketFactory
* GetMockClientSocketFactory() {
293 mock_socket_factory_
.reset(new MockClientSocketFactory
);
294 return mock_socket_factory_
.get();
297 // Functions for SocketStreamEventRecorder to handle calls to the
298 // SocketStream::Delegate methods from the SocketStream.
300 virtual void DoSendWebSocketHandshake(SocketStreamEvent
* event
) {
301 event
->socket
->SendData(
302 handshake_request_
.data(), handshake_request_
.size());
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()));
314 // Actual StreamSocket close must happen after all frames queued by
315 // SendData above are sent out.
316 event
->socket
->Close();
319 virtual void DoCloseFlushPendingWriteTestWithSetContextNull(
320 SocketStreamEvent
* event
) {
321 event
->socket
->set_context(NULL
);
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()));
330 // Actual StreamSocket close must happen after all frames queued by
331 // SendData above are sent out.
332 event
->socket
->Close();
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();
342 virtual int DoSwitchToSpdyTest(SocketStreamEvent
* event
) {
343 return ERR_PROTOCOL_SWITCHED
;
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
;
353 static const char kWebSocketHandshakeRequest
[];
354 static const char kWebSocketHandshakeResponse
[];
357 TestCompletionCallback io_test_callback_
;
360 std::string handshake_request_
;
361 std::string handshake_response_
;
362 std::vector
<std::string
> messages_
;
364 scoped_ptr
<MockClientSocketFactory
> mock_socket_factory_
;
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"
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"
389 TEST_F(SocketStreamTest
, CloseFlushPendingWrite
) {
390 TestCompletionCallback test_callback
;
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)));
400 TestURLRequestContext context
;
402 scoped_refptr
<SocketStream
> socket_stream(
403 new SocketStream(GURL("ws://example.com/demo"), delegate
.get()));
405 socket_stream
->set_context(&context
);
407 MockWrite data_writes
[] = {
408 MockWrite(SocketStreamTest::kWebSocketHandshakeRequest
),
409 MockWrite(ASYNC
, "\0message1\xff", 10),
410 MockWrite(ASYNC
, "\0message2\xff", 10)
412 MockRead data_reads
[] = {
413 MockRead(SocketStreamTest::kWebSocketHandshakeResponse
),
414 // Server doesn't close the connection after handshake.
415 MockRead(ASYNC
, ERR_IO_PENDING
)
417 AddWebSocketMessage("message1");
418 AddWebSocketMessage("message2");
420 DelayedSocketData
data_provider(
421 1, data_reads
, arraysize(data_reads
),
422 data_writes
, arraysize(data_writes
));
424 MockClientSocketFactory
* mock_socket_factory
=
425 GetMockClientSocketFactory();
426 mock_socket_factory
->AddSocketDataProvider(&data_provider
);
428 socket_stream
->SetClientSocketFactory(mock_socket_factory
);
430 socket_stream
->Connect();
432 test_callback
.WaitForResult();
434 EXPECT_TRUE(data_provider
.at_read_eof());
435 EXPECT_TRUE(data_provider
.at_write_eof());
437 const std::vector
<SocketStreamEvent
>& events
= delegate
->GetSeenEvents();
438 ASSERT_EQ(7U, events
.size());
440 EXPECT_EQ(SocketStreamEvent::EVENT_START_OPEN_CONNECTION
,
441 events
[0].event_type
);
442 EXPECT_EQ(SocketStreamEvent::EVENT_CONNECTED
, events
[1].event_type
);
443 EXPECT_EQ(SocketStreamEvent::EVENT_SENT_DATA
, events
[2].event_type
);
444 EXPECT_EQ(SocketStreamEvent::EVENT_RECEIVED_DATA
, events
[3].event_type
);
445 EXPECT_EQ(SocketStreamEvent::EVENT_SENT_DATA
, events
[4].event_type
);
446 EXPECT_EQ(SocketStreamEvent::EVENT_SENT_DATA
, events
[5].event_type
);
447 EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE
, events
[6].event_type
);
450 TEST_F(SocketStreamTest
, ResolveFailure
) {
451 TestCompletionCallback test_callback
;
453 scoped_ptr
<SocketStreamEventRecorder
> delegate(
454 new SocketStreamEventRecorder(test_callback
.callback()));
456 scoped_refptr
<SocketStream
> socket_stream(
457 new SocketStream(GURL("ws://example.com/demo"), delegate
.get()));
459 // Make resolver fail.
460 TestURLRequestContext context
;
461 scoped_ptr
<MockHostResolver
> mock_host_resolver(
462 new MockHostResolver());
463 mock_host_resolver
->rules()->AddSimulatedFailure("example.com");
464 context
.set_host_resolver(mock_host_resolver
.get());
465 socket_stream
->set_context(&context
);
467 // No read/write on socket is expected.
468 StaticSocketDataProvider
data_provider(NULL
, 0, NULL
, 0);
469 MockClientSocketFactory
* mock_socket_factory
=
470 GetMockClientSocketFactory();
471 mock_socket_factory
->AddSocketDataProvider(&data_provider
);
472 socket_stream
->SetClientSocketFactory(mock_socket_factory
);
474 socket_stream
->Connect();
476 test_callback
.WaitForResult();
478 const std::vector
<SocketStreamEvent
>& events
= delegate
->GetSeenEvents();
479 ASSERT_EQ(2U, events
.size());
481 EXPECT_EQ(SocketStreamEvent::EVENT_ERROR
, events
[0].event_type
);
482 EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE
, events
[1].event_type
);
485 TEST_F(SocketStreamTest
, ExceedMaxPendingSendAllowed
) {
486 TestCompletionCallback test_callback
;
488 scoped_ptr
<SocketStreamEventRecorder
> delegate(
489 new SocketStreamEventRecorder(test_callback
.callback()));
490 delegate
->SetOnConnected(base::Bind(
491 &SocketStreamTest::DoFailByTooBigDataAndClose
, base::Unretained(this)));
493 TestURLRequestContext context
;
495 scoped_refptr
<SocketStream
> socket_stream(
496 new SocketStream(GURL("ws://example.com/demo"), delegate
.get()));
498 socket_stream
->set_context(&context
);
500 DelayedSocketData
data_provider(1, NULL
, 0, NULL
, 0);
502 MockClientSocketFactory
* mock_socket_factory
=
503 GetMockClientSocketFactory();
504 mock_socket_factory
->AddSocketDataProvider(&data_provider
);
506 socket_stream
->SetClientSocketFactory(mock_socket_factory
);
508 socket_stream
->Connect();
510 test_callback
.WaitForResult();
512 const std::vector
<SocketStreamEvent
>& events
= delegate
->GetSeenEvents();
513 ASSERT_EQ(4U, events
.size());
515 EXPECT_EQ(SocketStreamEvent::EVENT_START_OPEN_CONNECTION
,
516 events
[0].event_type
);
517 EXPECT_EQ(SocketStreamEvent::EVENT_CONNECTED
, events
[1].event_type
);
518 EXPECT_EQ(SocketStreamEvent::EVENT_ERROR
, events
[2].event_type
);
519 EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE
, events
[3].event_type
);
522 TEST_F(SocketStreamTest
, BasicAuthProxy
) {
523 MockClientSocketFactory mock_socket_factory
;
524 MockWrite data_writes1
[] = {
525 MockWrite("CONNECT example.com:80 HTTP/1.1\r\n"
526 "Host: example.com\r\n"
527 "Proxy-Connection: keep-alive\r\n\r\n"),
529 MockRead data_reads1
[] = {
530 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
531 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
534 StaticSocketDataProvider
data1(data_reads1
, arraysize(data_reads1
),
535 data_writes1
, arraysize(data_writes1
));
536 mock_socket_factory
.AddSocketDataProvider(&data1
);
538 MockWrite data_writes2
[] = {
539 MockWrite("CONNECT example.com:80 HTTP/1.1\r\n"
540 "Host: example.com\r\n"
541 "Proxy-Connection: keep-alive\r\n"
542 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
544 MockRead data_reads2
[] = {
545 MockRead("HTTP/1.1 200 Connection Established\r\n"),
546 MockRead("Proxy-agent: Apache/2.2.8\r\n"),
548 // SocketStream::DoClose is run asynchronously. Socket can be read after
549 // "\r\n". We have to give ERR_IO_PENDING to SocketStream then to indicate
550 // server doesn't close the connection.
551 MockRead(ASYNC
, ERR_IO_PENDING
)
553 StaticSocketDataProvider
data2(data_reads2
, arraysize(data_reads2
),
554 data_writes2
, arraysize(data_writes2
));
555 mock_socket_factory
.AddSocketDataProvider(&data2
);
557 TestCompletionCallback test_callback
;
559 scoped_ptr
<SocketStreamEventRecorder
> delegate(
560 new SocketStreamEventRecorder(test_callback
.callback()));
561 delegate
->SetOnConnected(base::Bind(&SocketStreamEventRecorder::DoClose
,
562 base::Unretained(delegate
.get())));
563 delegate
->SetAuthInfo(AuthCredentials(ASCIIToUTF16("foo"),
564 ASCIIToUTF16("bar")));
565 delegate
->SetOnAuthRequired(base::Bind(
566 &SocketStreamEventRecorder::DoRestartWithAuth
,
567 base::Unretained(delegate
.get())));
569 scoped_refptr
<SocketStream
> socket_stream(
570 new SocketStream(GURL("ws://example.com/demo"), delegate
.get()));
572 TestURLRequestContextWithProxy
context("myproxy:70");
574 socket_stream
->set_context(&context
);
575 socket_stream
->SetClientSocketFactory(&mock_socket_factory
);
577 socket_stream
->Connect();
579 test_callback
.WaitForResult();
581 const std::vector
<SocketStreamEvent
>& events
= delegate
->GetSeenEvents();
582 ASSERT_EQ(5U, events
.size());
584 EXPECT_EQ(SocketStreamEvent::EVENT_START_OPEN_CONNECTION
,
585 events
[0].event_type
);
586 EXPECT_EQ(SocketStreamEvent::EVENT_AUTH_REQUIRED
, events
[1].event_type
);
587 EXPECT_EQ(SocketStreamEvent::EVENT_CONNECTED
, events
[2].event_type
);
588 EXPECT_EQ(SocketStreamEvent::EVENT_ERROR
, events
[3].event_type
);
589 EXPECT_EQ(ERR_ABORTED
, events
[3].error_code
);
590 EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE
, events
[4].event_type
);
592 // TODO(eroman): Add back NetLogTest here...
595 TEST_F(SocketStreamTest
, BasicAuthProxyWithAuthCache
) {
596 MockClientSocketFactory mock_socket_factory
;
597 MockWrite data_writes
[] = {
598 // WebSocket(SocketStream) always uses CONNECT when it is configured to use
599 // proxy so the port may not be 443.
600 MockWrite("CONNECT example.com:80 HTTP/1.1\r\n"
601 "Host: example.com\r\n"
602 "Proxy-Connection: keep-alive\r\n"
603 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
605 MockRead data_reads
[] = {
606 MockRead("HTTP/1.1 200 Connection Established\r\n"),
607 MockRead("Proxy-agent: Apache/2.2.8\r\n"),
609 MockRead(ASYNC
, ERR_IO_PENDING
)
611 StaticSocketDataProvider
data(data_reads
, arraysize(data_reads
),
612 data_writes
, arraysize(data_writes
));
613 mock_socket_factory
.AddSocketDataProvider(&data
);
615 TestCompletionCallback test_callback
;
616 scoped_ptr
<SocketStreamEventRecorder
> delegate(
617 new SocketStreamEventRecorder(test_callback
.callback()));
618 delegate
->SetOnConnected(base::Bind(&SocketStreamEventRecorder::DoClose
,
619 base::Unretained(delegate
.get())));
621 scoped_refptr
<SocketStream
> socket_stream(
622 new SocketStream(GURL("ws://example.com/demo"), delegate
.get()));
624 TestURLRequestContextWithProxy
context("myproxy:70");
625 HttpAuthCache
* auth_cache
=
626 context
.http_transaction_factory()->GetSession()->http_auth_cache();
627 auth_cache
->Add(GURL("http://myproxy:70"),
629 HttpAuth::AUTH_SCHEME_BASIC
,
630 "Basic realm=MyRealm1",
631 AuthCredentials(ASCIIToUTF16("foo"),
632 ASCIIToUTF16("bar")),
635 socket_stream
->set_context(&context
);
636 socket_stream
->SetClientSocketFactory(&mock_socket_factory
);
638 socket_stream
->Connect();
640 test_callback
.WaitForResult();
642 const std::vector
<SocketStreamEvent
>& events
= delegate
->GetSeenEvents();
643 ASSERT_EQ(4U, events
.size());
644 EXPECT_EQ(SocketStreamEvent::EVENT_START_OPEN_CONNECTION
,
645 events
[0].event_type
);
646 EXPECT_EQ(SocketStreamEvent::EVENT_CONNECTED
, events
[1].event_type
);
647 EXPECT_EQ(ERR_ABORTED
, events
[2].error_code
);
648 EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE
, events
[3].event_type
);
651 TEST_F(SocketStreamTest
, WSSBasicAuthProxyWithAuthCache
) {
652 MockClientSocketFactory mock_socket_factory
;
653 MockWrite data_writes1
[] = {
654 MockWrite("CONNECT example.com:443 HTTP/1.1\r\n"
655 "Host: example.com\r\n"
656 "Proxy-Connection: keep-alive\r\n"
657 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
659 MockRead data_reads1
[] = {
660 MockRead("HTTP/1.1 200 Connection Established\r\n"),
661 MockRead("Proxy-agent: Apache/2.2.8\r\n"),
663 MockRead(ASYNC
, ERR_IO_PENDING
)
665 StaticSocketDataProvider
data1(data_reads1
, arraysize(data_reads1
),
666 data_writes1
, arraysize(data_writes1
));
667 mock_socket_factory
.AddSocketDataProvider(&data1
);
669 SSLSocketDataProvider
data2(ASYNC
, OK
);
670 mock_socket_factory
.AddSSLSocketDataProvider(&data2
);
672 TestCompletionCallback test_callback
;
673 scoped_ptr
<SocketStreamEventRecorder
> delegate(
674 new SocketStreamEventRecorder(test_callback
.callback()));
675 delegate
->SetOnConnected(base::Bind(&SocketStreamEventRecorder::DoClose
,
676 base::Unretained(delegate
.get())));
678 scoped_refptr
<SocketStream
> socket_stream(
679 new SocketStream(GURL("wss://example.com/demo"), delegate
.get()));
681 TestURLRequestContextWithProxy
context("myproxy:70");
682 HttpAuthCache
* auth_cache
=
683 context
.http_transaction_factory()->GetSession()->http_auth_cache();
684 auth_cache
->Add(GURL("http://myproxy:70"),
686 HttpAuth::AUTH_SCHEME_BASIC
,
687 "Basic realm=MyRealm1",
688 AuthCredentials(ASCIIToUTF16("foo"),
689 ASCIIToUTF16("bar")),
692 socket_stream
->set_context(&context
);
693 socket_stream
->SetClientSocketFactory(&mock_socket_factory
);
695 socket_stream
->Connect();
697 test_callback
.WaitForResult();
699 const std::vector
<SocketStreamEvent
>& events
= delegate
->GetSeenEvents();
700 ASSERT_EQ(4U, events
.size());
701 EXPECT_EQ(SocketStreamEvent::EVENT_START_OPEN_CONNECTION
,
702 events
[0].event_type
);
703 EXPECT_EQ(SocketStreamEvent::EVENT_CONNECTED
, events
[1].event_type
);
704 EXPECT_EQ(ERR_ABORTED
, events
[2].error_code
);
705 EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE
, events
[3].event_type
);
708 TEST_F(SocketStreamTest
, IOPending
) {
709 TestCompletionCallback test_callback
;
711 scoped_ptr
<SocketStreamEventRecorder
> delegate(
712 new SocketStreamEventRecorder(test_callback
.callback()));
713 delegate
->SetOnStartOpenConnection(base::Bind(
714 &SocketStreamTest::DoIOPending
, base::Unretained(this)));
715 delegate
->SetOnConnected(base::Bind(
716 &SocketStreamTest::DoSendWebSocketHandshake
, base::Unretained(this)));
717 delegate
->SetOnReceivedData(base::Bind(
718 &SocketStreamTest::DoCloseFlushPendingWriteTest
,
719 base::Unretained(this)));
721 TestURLRequestContext context
;
723 scoped_refptr
<SocketStream
> socket_stream(
724 new SocketStream(GURL("ws://example.com/demo"), delegate
.get()));
726 socket_stream
->set_context(&context
);
728 MockWrite data_writes
[] = {
729 MockWrite(SocketStreamTest::kWebSocketHandshakeRequest
),
730 MockWrite(ASYNC
, "\0message1\xff", 10),
731 MockWrite(ASYNC
, "\0message2\xff", 10)
733 MockRead data_reads
[] = {
734 MockRead(SocketStreamTest::kWebSocketHandshakeResponse
),
735 // Server doesn't close the connection after handshake.
736 MockRead(ASYNC
, ERR_IO_PENDING
)
738 AddWebSocketMessage("message1");
739 AddWebSocketMessage("message2");
741 DelayedSocketData
data_provider(
742 1, data_reads
, arraysize(data_reads
),
743 data_writes
, arraysize(data_writes
));
745 MockClientSocketFactory
* mock_socket_factory
=
746 GetMockClientSocketFactory();
747 mock_socket_factory
->AddSocketDataProvider(&data_provider
);
749 socket_stream
->SetClientSocketFactory(mock_socket_factory
);
751 socket_stream
->Connect();
752 io_test_callback_
.WaitForResult();
753 EXPECT_EQ(SocketStream::STATE_RESOLVE_PROTOCOL_COMPLETE
,
754 socket_stream
->next_state_
);
755 delegate
->CompleteConnection(OK
);
757 EXPECT_EQ(OK
, test_callback
.WaitForResult());
759 EXPECT_TRUE(data_provider
.at_read_eof());
760 EXPECT_TRUE(data_provider
.at_write_eof());
762 const std::vector
<SocketStreamEvent
>& events
= delegate
->GetSeenEvents();
763 ASSERT_EQ(7U, events
.size());
765 EXPECT_EQ(SocketStreamEvent::EVENT_START_OPEN_CONNECTION
,
766 events
[0].event_type
);
767 EXPECT_EQ(SocketStreamEvent::EVENT_CONNECTED
, events
[1].event_type
);
768 EXPECT_EQ(SocketStreamEvent::EVENT_SENT_DATA
, events
[2].event_type
);
769 EXPECT_EQ(SocketStreamEvent::EVENT_RECEIVED_DATA
, events
[3].event_type
);
770 EXPECT_EQ(SocketStreamEvent::EVENT_SENT_DATA
, events
[4].event_type
);
771 EXPECT_EQ(SocketStreamEvent::EVENT_SENT_DATA
, events
[5].event_type
);
772 EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE
, events
[6].event_type
);
775 TEST_F(SocketStreamTest
, SwitchToSpdy
) {
776 TestCompletionCallback test_callback
;
778 scoped_ptr
<SocketStreamEventRecorder
> delegate(
779 new SocketStreamEventRecorder(test_callback
.callback()));
780 delegate
->SetOnStartOpenConnection(base::Bind(
781 &SocketStreamTest::DoSwitchToSpdyTest
, base::Unretained(this)));
783 TestURLRequestContext context
;
785 scoped_refptr
<SocketStream
> socket_stream(
786 new SocketStream(GURL("ws://example.com/demo"), delegate
.get()));
788 socket_stream
->set_context(&context
);
790 socket_stream
->Connect();
792 EXPECT_EQ(ERR_PROTOCOL_SWITCHED
, test_callback
.WaitForResult());
794 const std::vector
<SocketStreamEvent
>& events
= delegate
->GetSeenEvents();
795 ASSERT_EQ(2U, events
.size());
797 EXPECT_EQ(SocketStreamEvent::EVENT_START_OPEN_CONNECTION
,
798 events
[0].event_type
);
799 EXPECT_EQ(SocketStreamEvent::EVENT_ERROR
, events
[1].event_type
);
800 EXPECT_EQ(ERR_PROTOCOL_SWITCHED
, events
[1].error_code
);
803 TEST_F(SocketStreamTest
, SwitchAfterPending
) {
804 TestCompletionCallback test_callback
;
806 scoped_ptr
<SocketStreamEventRecorder
> delegate(
807 new SocketStreamEventRecorder(test_callback
.callback()));
808 delegate
->SetOnStartOpenConnection(base::Bind(
809 &SocketStreamTest::DoIOPending
, base::Unretained(this)));
811 TestURLRequestContext context
;
813 scoped_refptr
<SocketStream
> socket_stream(
814 new SocketStream(GURL("ws://example.com/demo"), delegate
.get()));
816 socket_stream
->set_context(&context
);
818 socket_stream
->Connect();
819 io_test_callback_
.WaitForResult();
821 EXPECT_EQ(SocketStream::STATE_RESOLVE_PROTOCOL_COMPLETE
,
822 socket_stream
->next_state_
);
823 delegate
->CompleteConnection(ERR_PROTOCOL_SWITCHED
);
825 EXPECT_EQ(ERR_PROTOCOL_SWITCHED
, test_callback
.WaitForResult());
827 const std::vector
<SocketStreamEvent
>& events
= delegate
->GetSeenEvents();
828 ASSERT_EQ(2U, events
.size());
830 EXPECT_EQ(SocketStreamEvent::EVENT_START_OPEN_CONNECTION
,
831 events
[0].event_type
);
832 EXPECT_EQ(SocketStreamEvent::EVENT_ERROR
, events
[1].event_type
);
833 EXPECT_EQ(ERR_PROTOCOL_SWITCHED
, events
[1].error_code
);
836 // Test a connection though a secure proxy.
837 TEST_F(SocketStreamTest
, SecureProxyConnectError
) {
838 MockClientSocketFactory mock_socket_factory
;
839 MockWrite data_writes
[] = {
840 MockWrite("CONNECT example.com:80 HTTP/1.1\r\n"
841 "Host: example.com\r\n"
842 "Proxy-Connection: keep-alive\r\n\r\n")
844 MockRead data_reads
[] = {
845 MockRead("HTTP/1.1 200 Connection Established\r\n"),
846 MockRead("Proxy-agent: Apache/2.2.8\r\n"),
848 // SocketStream::DoClose is run asynchronously. Socket can be read after
849 // "\r\n". We have to give ERR_IO_PENDING to SocketStream then to indicate
850 // server doesn't close the connection.
851 MockRead(ASYNC
, ERR_IO_PENDING
)
853 StaticSocketDataProvider
data(data_reads
, arraysize(data_reads
),
854 data_writes
, arraysize(data_writes
));
855 mock_socket_factory
.AddSocketDataProvider(&data
);
856 SSLSocketDataProvider
ssl(SYNCHRONOUS
, ERR_SSL_PROTOCOL_ERROR
);
857 mock_socket_factory
.AddSSLSocketDataProvider(&ssl
);
859 TestCompletionCallback test_callback
;
860 TestURLRequestContextWithProxy
context("https://myproxy:70");
862 scoped_ptr
<SocketStreamEventRecorder
> delegate(
863 new SocketStreamEventRecorder(test_callback
.callback()));
864 delegate
->SetOnConnected(base::Bind(&SocketStreamEventRecorder::DoClose
,
865 base::Unretained(delegate
.get())));
867 scoped_refptr
<SocketStream
> socket_stream(
868 new SocketStream(GURL("ws://example.com/demo"), delegate
.get()));
870 socket_stream
->set_context(&context
);
871 socket_stream
->SetClientSocketFactory(&mock_socket_factory
);
873 socket_stream
->Connect();
875 test_callback
.WaitForResult();
877 const std::vector
<SocketStreamEvent
>& events
= delegate
->GetSeenEvents();
878 ASSERT_EQ(3U, events
.size());
880 EXPECT_EQ(SocketStreamEvent::EVENT_START_OPEN_CONNECTION
,
881 events
[0].event_type
);
882 EXPECT_EQ(SocketStreamEvent::EVENT_ERROR
, events
[1].event_type
);
883 EXPECT_EQ(ERR_SSL_PROTOCOL_ERROR
, events
[1].error_code
);
884 EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE
, events
[2].event_type
);
887 // Test a connection though a secure proxy.
888 TEST_F(SocketStreamTest
, SecureProxyConnect
) {
889 MockClientSocketFactory mock_socket_factory
;
890 MockWrite data_writes
[] = {
891 MockWrite("CONNECT example.com:80 HTTP/1.1\r\n"
892 "Host: example.com\r\n"
893 "Proxy-Connection: keep-alive\r\n\r\n")
895 MockRead data_reads
[] = {
896 MockRead("HTTP/1.1 200 Connection Established\r\n"),
897 MockRead("Proxy-agent: Apache/2.2.8\r\n"),
899 // SocketStream::DoClose is run asynchronously. Socket can be read after
900 // "\r\n". We have to give ERR_IO_PENDING to SocketStream then to indicate
901 // server doesn't close the connection.
902 MockRead(ASYNC
, ERR_IO_PENDING
)
904 StaticSocketDataProvider
data(data_reads
, arraysize(data_reads
),
905 data_writes
, arraysize(data_writes
));
906 mock_socket_factory
.AddSocketDataProvider(&data
);
907 SSLSocketDataProvider
ssl(SYNCHRONOUS
, OK
);
908 mock_socket_factory
.AddSSLSocketDataProvider(&ssl
);
910 TestCompletionCallback test_callback
;
911 TestURLRequestContextWithProxy
context("https://myproxy:70");
913 scoped_ptr
<SocketStreamEventRecorder
> delegate(
914 new SocketStreamEventRecorder(test_callback
.callback()));
915 delegate
->SetOnConnected(base::Bind(&SocketStreamEventRecorder::DoClose
,
916 base::Unretained(delegate
.get())));
918 scoped_refptr
<SocketStream
> socket_stream(
919 new SocketStream(GURL("ws://example.com/demo"), delegate
.get()));
921 socket_stream
->set_context(&context
);
922 socket_stream
->SetClientSocketFactory(&mock_socket_factory
);
924 socket_stream
->Connect();
926 test_callback
.WaitForResult();
928 const std::vector
<SocketStreamEvent
>& events
= delegate
->GetSeenEvents();
929 ASSERT_EQ(4U, events
.size());
931 EXPECT_EQ(SocketStreamEvent::EVENT_START_OPEN_CONNECTION
,
932 events
[0].event_type
);
933 EXPECT_EQ(SocketStreamEvent::EVENT_CONNECTED
, events
[1].event_type
);
934 EXPECT_EQ(SocketStreamEvent::EVENT_ERROR
, events
[2].event_type
);
935 EXPECT_EQ(ERR_ABORTED
, events
[2].error_code
);
936 EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE
, events
[3].event_type
);
939 TEST_F(SocketStreamTest
, BeforeConnectFailed
) {
940 TestCompletionCallback test_callback
;
942 scoped_ptr
<SocketStreamEventRecorder
> delegate(
943 new SocketStreamEventRecorder(test_callback
.callback()));
945 TestURLRequestContext context
;
946 TestSocketStreamNetworkDelegate network_delegate
;
947 network_delegate
.SetBeforeConnectResult(ERR_ACCESS_DENIED
);
948 context
.set_network_delegate(&network_delegate
);
950 scoped_refptr
<SocketStream
> socket_stream(
951 new SocketStream(GURL("ws://example.com/demo"), delegate
.get()));
953 socket_stream
->set_context(&context
);
955 socket_stream
->Connect();
957 test_callback
.WaitForResult();
959 const std::vector
<SocketStreamEvent
>& events
= delegate
->GetSeenEvents();
960 ASSERT_EQ(2U, events
.size());
962 EXPECT_EQ(SocketStreamEvent::EVENT_ERROR
, events
[0].event_type
);
963 EXPECT_EQ(ERR_ACCESS_DENIED
, events
[0].error_code
);
964 EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE
, events
[1].event_type
);
967 // Check that a connect failure, followed by the delegate calling DetachDelegate
968 // and deleting itself in the OnError callback, is handled correctly.
969 TEST_F(SocketStreamTest
, OnErrorDetachDelegate
) {
970 MockClientSocketFactory mock_socket_factory
;
971 TestCompletionCallback test_callback
;
973 // SelfDeletingDelegate is self-owning; we just need a pointer to it to
974 // connect it and the SocketStream.
975 SelfDeletingDelegate
* delegate
=
976 new SelfDeletingDelegate(test_callback
.callback());
977 MockConnect
mock_connect(ASYNC
, ERR_CONNECTION_REFUSED
);
978 StaticSocketDataProvider data
;
979 data
.set_connect_data(mock_connect
);
980 mock_socket_factory
.AddSocketDataProvider(&data
);
982 TestURLRequestContext context
;
983 scoped_refptr
<SocketStream
> socket_stream(
984 new SocketStream(GURL("ws://localhost:9998/echo"), delegate
));
985 socket_stream
->set_context(&context
);
986 socket_stream
->SetClientSocketFactory(&mock_socket_factory
);
987 delegate
->set_socket_stream(socket_stream
);
988 // The delegate pointer will become invalid during the test. Set it to NULL to
989 // avoid holding a dangling pointer.
992 socket_stream
->Connect();
994 EXPECT_EQ(OK
, test_callback
.WaitForResult());
997 TEST_F(SocketStreamTest
, NullContextSocketStreamShouldNotCrash
) {
998 TestCompletionCallback test_callback
;
1000 scoped_ptr
<SocketStreamEventRecorder
> delegate(
1001 new SocketStreamEventRecorder(test_callback
.callback()));
1002 TestURLRequestContext context
;
1003 scoped_refptr
<SocketStream
> socket_stream(
1004 new SocketStream(GURL("ws://example.com/demo"), delegate
.get()));
1005 delegate
->SetOnStartOpenConnection(base::Bind(
1006 &SocketStreamTest::DoIOPending
, base::Unretained(this)));
1007 delegate
->SetOnConnected(base::Bind(
1008 &SocketStreamTest::DoSendWebSocketHandshake
, base::Unretained(this)));
1009 delegate
->SetOnReceivedData(base::Bind(
1010 &SocketStreamTest::DoCloseFlushPendingWriteTestWithSetContextNull
,
1011 base::Unretained(this)));
1013 socket_stream
->set_context(&context
);
1015 MockWrite data_writes
[] = {
1016 MockWrite(SocketStreamTest::kWebSocketHandshakeRequest
),
1018 MockRead data_reads
[] = {
1019 MockRead(SocketStreamTest::kWebSocketHandshakeResponse
),
1021 AddWebSocketMessage("message1");
1022 AddWebSocketMessage("message2");
1024 DelayedSocketData
data_provider(
1025 1, data_reads
, arraysize(data_reads
),
1026 data_writes
, arraysize(data_writes
));
1028 MockClientSocketFactory
* mock_socket_factory
= GetMockClientSocketFactory();
1029 mock_socket_factory
->AddSocketDataProvider(&data_provider
);
1030 socket_stream
->SetClientSocketFactory(mock_socket_factory
);
1032 socket_stream
->Connect();
1033 io_test_callback_
.WaitForResult();
1034 delegate
->CompleteConnection(OK
);
1035 EXPECT_EQ(OK
, test_callback
.WaitForResult());
1037 EXPECT_TRUE(data_provider
.at_read_eof());
1038 EXPECT_TRUE(data_provider
.at_write_eof());
1040 const std::vector
<SocketStreamEvent
>& events
= delegate
->GetSeenEvents();
1041 ASSERT_EQ(5U, events
.size());
1043 EXPECT_EQ(SocketStreamEvent::EVENT_START_OPEN_CONNECTION
,
1044 events
[0].event_type
);
1045 EXPECT_EQ(SocketStreamEvent::EVENT_CONNECTED
, events
[1].event_type
);
1046 EXPECT_EQ(SocketStreamEvent::EVENT_SENT_DATA
, events
[2].event_type
);
1047 EXPECT_EQ(SocketStreamEvent::EVENT_RECEIVED_DATA
, events
[3].event_type
);
1048 EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE
, events
[4].event_type
);