Fix the menu alignment for the three button menu.
[chromium-blink-merge.git] / net / socket_stream / socket_stream_unittest.cc
blob069f92eb9ed53bd2fa2e7168eacd48ebfe920e34
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"
7 #include <string>
8 #include <vector>
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;
28 namespace net {
30 namespace {
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,
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) {}
47 EventType event_type;
48 SocketStream* socket;
49 int number;
50 std::string data;
51 scoped_refptr<AuthChallengeInfo> auth_info;
52 int error_code;
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() {}
64 void SetOnStartOpenConnection(
65 const base::Callback<int(SocketStreamEvent*)>& callback) {
66 on_start_open_connection_ = callback;
68 void SetOnConnected(
69 const base::Callback<void(SocketStreamEvent*)>& callback) {
70 on_connected_ = callback;
72 void SetOnSentData(
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) {
81 on_close_ = 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) {
88 on_error_ = callback;
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;
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());
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());
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());
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);
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());
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);
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()
166 // of its delegate.
167 void CompleteConnection(int result) {
168 connection_callback_.Run(result);
171 const std::vector<SocketStreamEvent>& GetSeenEvents() const {
172 return events_;
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_;
188 DISALLOW_COPY_AND_ASSIGN(SocketStreamEventRecorder);
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) {}
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
203 // afterwards.
204 CompletionCallback callback = callback_;
205 socket_stream_->DetachDelegate();
206 delete this;
207 callback.Run(OK);
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)
218 OVERRIDE {
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)
225 OVERRIDE {
226 ADD_FAILURE() << "OnReceivedData() should not be called";
228 virtual void OnClose(SocketStream* socket) OVERRIDE {
229 ADD_FAILURE() << "OnClose() should not be called";
232 private:
233 scoped_refptr<SocketStream> socket_stream_;
234 const CompletionCallback callback_;
236 DISALLOW_COPY_AND_ASSIGN(SelfDeletingDelegate);
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();
246 virtual ~TestURLRequestContextWithProxy() {}
249 class TestSocketStreamNetworkDelegate : public TestNetworkDelegate {
250 public:
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;
265 private:
266 int before_connect_result_;
269 } // namespace
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;
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->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()));
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[];
356 protected:
357 TestCompletionCallback io_test_callback_;
359 private:
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"
376 "\r\n"
377 "^n:ds[4U";
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-";
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(),
404 &context, NULL));
406 MockWrite data_writes[] = {
407 MockWrite(SocketStreamTest::kWebSocketHandshakeRequest),
408 MockWrite(ASYNC, "\0message1\xff", 10),
409 MockWrite(ASYNC, "\0message2\xff", 10)
411 MockRead data_reads[] = {
412 MockRead(SocketStreamTest::kWebSocketHandshakeResponse),
413 // Server doesn't close the connection after handshake.
414 MockRead(ASYNC, ERR_IO_PENDING)
416 AddWebSocketMessage("message1");
417 AddWebSocketMessage("message2");
419 DelayedSocketData data_provider(
420 1, data_reads, arraysize(data_reads),
421 data_writes, arraysize(data_writes));
423 MockClientSocketFactory* mock_socket_factory =
424 GetMockClientSocketFactory();
425 mock_socket_factory->AddSocketDataProvider(&data_provider);
427 socket_stream->SetClientSocketFactory(mock_socket_factory);
429 socket_stream->Connect();
431 test_callback.WaitForResult();
433 EXPECT_TRUE(data_provider.at_read_eof());
434 EXPECT_TRUE(data_provider.at_write_eof());
436 const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents();
437 ASSERT_EQ(7U, events.size());
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);
449 TEST_F(SocketStreamTest, ResolveFailure) {
450 TestCompletionCallback test_callback;
452 scoped_ptr<SocketStreamEventRecorder> delegate(
453 new SocketStreamEventRecorder(test_callback.callback()));
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());
462 scoped_refptr<SocketStream> socket_stream(
463 new SocketStream(GURL("ws://example.com/demo"), delegate.get(),
464 &context, NULL));
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);
473 socket_stream->Connect();
475 test_callback.WaitForResult();
477 const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents();
478 ASSERT_EQ(2U, events.size());
480 EXPECT_EQ(SocketStreamEvent::EVENT_ERROR, events[0].event_type);
481 EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE, events[1].event_type);
484 TEST_F(SocketStreamTest, ExceedMaxPendingSendAllowed) {
485 TestCompletionCallback test_callback;
487 scoped_ptr<SocketStreamEventRecorder> delegate(
488 new SocketStreamEventRecorder(test_callback.callback()));
489 delegate->SetOnConnected(base::Bind(
490 &SocketStreamTest::DoFailByTooBigDataAndClose, base::Unretained(this)));
492 TestURLRequestContext context;
494 scoped_refptr<SocketStream> socket_stream(
495 new SocketStream(GURL("ws://example.com/demo"), delegate.get(),
496 &context, NULL));
498 DelayedSocketData data_provider(1, NULL, 0, NULL, 0);
500 MockClientSocketFactory* mock_socket_factory =
501 GetMockClientSocketFactory();
502 mock_socket_factory->AddSocketDataProvider(&data_provider);
504 socket_stream->SetClientSocketFactory(mock_socket_factory);
506 socket_stream->Connect();
508 test_callback.WaitForResult();
510 const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents();
511 ASSERT_EQ(4U, events.size());
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);
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"),
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"),
532 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
533 data_writes1, arraysize(data_writes1));
534 mock_socket_factory.AddSocketDataProvider(&data1);
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"),
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)
551 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
552 data_writes2, arraysize(data_writes2));
553 mock_socket_factory.AddSocketDataProvider(&data2);
555 TestCompletionCallback test_callback;
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())));
567 TestURLRequestContextWithProxy context("myproxy:70");
569 scoped_refptr<SocketStream> socket_stream(
570 new SocketStream(GURL("ws://example.com/demo"), delegate.get(),
571 &context, NULL));
573 socket_stream->SetClientSocketFactory(&mock_socket_factory);
575 socket_stream->Connect();
577 test_callback.WaitForResult();
579 const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents();
580 ASSERT_EQ(5U, events.size());
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);
590 // TODO(eroman): Add back NetLogTest here...
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"),
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)
609 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
610 data_writes, arraysize(data_writes));
611 mock_socket_factory.AddSocketDataProvider(&data);
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())));
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 "/");
630 scoped_refptr<SocketStream> socket_stream(
631 new SocketStream(GURL("ws://example.com/demo"), delegate.get(),
632 &context, NULL));
634 socket_stream->SetClientSocketFactory(&mock_socket_factory);
636 socket_stream->Connect();
638 test_callback.WaitForResult();
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);
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"),
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)
663 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
664 data_writes1, arraysize(data_writes1));
665 mock_socket_factory.AddSocketDataProvider(&data1);
667 SSLSocketDataProvider data2(ASYNC, OK);
668 mock_socket_factory.AddSSLSocketDataProvider(&data2);
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())));
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 "/");
687 scoped_refptr<SocketStream> socket_stream(
688 new SocketStream(GURL("wss://example.com/demo"), delegate.get(),
689 &context, NULL));
691 socket_stream->SetClientSocketFactory(&mock_socket_factory);
693 socket_stream->Connect();
695 test_callback.WaitForResult();
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);
706 TEST_F(SocketStreamTest, IOPending) {
707 TestCompletionCallback test_callback;
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)));
719 TestURLRequestContext context;
721 scoped_refptr<SocketStream> socket_stream(
722 new SocketStream(GURL("ws://example.com/demo"), delegate.get(),
723 &context, NULL));
725 MockWrite data_writes[] = {
726 MockWrite(SocketStreamTest::kWebSocketHandshakeRequest),
727 MockWrite(ASYNC, "\0message1\xff", 10),
728 MockWrite(ASYNC, "\0message2\xff", 10)
730 MockRead data_reads[] = {
731 MockRead(SocketStreamTest::kWebSocketHandshakeResponse),
732 // Server doesn't close the connection after handshake.
733 MockRead(ASYNC, ERR_IO_PENDING)
735 AddWebSocketMessage("message1");
736 AddWebSocketMessage("message2");
738 DelayedSocketData data_provider(
739 1, data_reads, arraysize(data_reads),
740 data_writes, arraysize(data_writes));
742 MockClientSocketFactory* mock_socket_factory =
743 GetMockClientSocketFactory();
744 mock_socket_factory->AddSocketDataProvider(&data_provider);
746 socket_stream->SetClientSocketFactory(mock_socket_factory);
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);
754 EXPECT_EQ(OK, test_callback.WaitForResult());
756 EXPECT_TRUE(data_provider.at_read_eof());
757 EXPECT_TRUE(data_provider.at_write_eof());
759 const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents();
760 ASSERT_EQ(7U, events.size());
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);
772 TEST_F(SocketStreamTest, SwitchToSpdy) {
773 TestCompletionCallback test_callback;
775 scoped_ptr<SocketStreamEventRecorder> delegate(
776 new SocketStreamEventRecorder(test_callback.callback()));
777 delegate->SetOnStartOpenConnection(base::Bind(
778 &SocketStreamTest::DoSwitchToSpdyTest, base::Unretained(this)));
780 TestURLRequestContext context;
782 scoped_refptr<SocketStream> socket_stream(
783 new SocketStream(GURL("ws://example.com/demo"), delegate.get(),
784 &context, NULL));
786 socket_stream->Connect();
788 EXPECT_EQ(ERR_PROTOCOL_SWITCHED, test_callback.WaitForResult());
790 const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents();
791 ASSERT_EQ(2U, events.size());
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);
799 TEST_F(SocketStreamTest, SwitchAfterPending) {
800 TestCompletionCallback test_callback;
802 scoped_ptr<SocketStreamEventRecorder> delegate(
803 new SocketStreamEventRecorder(test_callback.callback()));
804 delegate->SetOnStartOpenConnection(base::Bind(
805 &SocketStreamTest::DoIOPending, base::Unretained(this)));
807 TestURLRequestContext context;
809 scoped_refptr<SocketStream> socket_stream(
810 new SocketStream(GURL("ws://example.com/demo"), delegate.get(),
811 &context, NULL));
813 socket_stream->Connect();
814 io_test_callback_.WaitForResult();
816 EXPECT_EQ(SocketStream::STATE_RESOLVE_PROTOCOL_COMPLETE,
817 socket_stream->next_state_);
818 delegate->CompleteConnection(ERR_PROTOCOL_SWITCHED);
820 EXPECT_EQ(ERR_PROTOCOL_SWITCHED, test_callback.WaitForResult());
822 const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents();
823 ASSERT_EQ(2U, events.size());
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);
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")
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)
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);
854 TestCompletionCallback test_callback;
855 TestURLRequestContextWithProxy context("https://myproxy:70");
857 scoped_ptr<SocketStreamEventRecorder> delegate(
858 new SocketStreamEventRecorder(test_callback.callback()));
859 delegate->SetOnConnected(base::Bind(&SocketStreamEventRecorder::DoClose,
860 base::Unretained(delegate.get())));
862 scoped_refptr<SocketStream> socket_stream(
863 new SocketStream(GURL("ws://example.com/demo"), delegate.get(),
864 &context, NULL));
866 socket_stream->SetClientSocketFactory(&mock_socket_factory);
868 socket_stream->Connect();
870 test_callback.WaitForResult();
872 const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents();
873 ASSERT_EQ(3U, events.size());
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);
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")
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)
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);
905 TestCompletionCallback test_callback;
906 TestURLRequestContextWithProxy context("https://myproxy:70");
908 scoped_ptr<SocketStreamEventRecorder> delegate(
909 new SocketStreamEventRecorder(test_callback.callback()));
910 delegate->SetOnConnected(base::Bind(&SocketStreamEventRecorder::DoClose,
911 base::Unretained(delegate.get())));
913 scoped_refptr<SocketStream> socket_stream(
914 new SocketStream(GURL("ws://example.com/demo"), delegate.get(),
915 &context, NULL));
917 socket_stream->SetClientSocketFactory(&mock_socket_factory);
919 socket_stream->Connect();
921 test_callback.WaitForResult();
923 const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents();
924 ASSERT_EQ(4U, events.size());
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);
934 TEST_F(SocketStreamTest, BeforeConnectFailed) {
935 TestCompletionCallback test_callback;
937 scoped_ptr<SocketStreamEventRecorder> delegate(
938 new SocketStreamEventRecorder(test_callback.callback()));
940 TestURLRequestContext context;
941 TestSocketStreamNetworkDelegate network_delegate;
942 network_delegate.SetBeforeConnectResult(ERR_ACCESS_DENIED);
943 context.set_network_delegate(&network_delegate);
945 scoped_refptr<SocketStream> socket_stream(
946 new SocketStream(GURL("ws://example.com/demo"), delegate.get(),
947 &context, NULL));
949 socket_stream->Connect();
951 test_callback.WaitForResult();
953 const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents();
954 ASSERT_EQ(2U, events.size());
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);
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;
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);
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;
986 socket_stream->Connect();
988 EXPECT_EQ(OK, test_callback.WaitForResult());
991 TEST_F(SocketStreamTest, NullContextSocketStreamShouldNotCrash) {
992 TestCompletionCallback test_callback;
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)));
1008 MockWrite data_writes[] = {
1009 MockWrite(SocketStreamTest::kWebSocketHandshakeRequest),
1011 MockRead data_reads[] = {
1012 MockRead(SocketStreamTest::kWebSocketHandshakeResponse),
1014 AddWebSocketMessage("message1");
1015 AddWebSocketMessage("message2");
1017 DelayedSocketData data_provider(
1018 1, data_reads, arraysize(data_reads),
1019 data_writes, arraysize(data_writes));
1021 MockClientSocketFactory* mock_socket_factory = GetMockClientSocketFactory();
1022 mock_socket_factory->AddSocketDataProvider(&data_provider);
1023 socket_stream->SetClientSocketFactory(mock_socket_factory);
1025 socket_stream->Connect();
1026 io_test_callback_.WaitForResult();
1027 delegate->CompleteConnection(OK);
1028 EXPECT_EQ(OK, test_callback.WaitForResult());
1030 EXPECT_TRUE(data_provider.at_read_eof());
1031 EXPECT_TRUE(data_provider.at_write_eof());
1033 const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents();
1034 ASSERT_EQ(5U, events.size());
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);
1044 } // namespace net