Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(773)

Side by Side Diff: net/socket_stream/socket_stream_unittest.cc

Issue 723343002: Update from https://crrev.com/304121 (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/socket_stream/socket_stream_metrics_unittest.cc ('k') | net/spdy/buffered_spdy_framer.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/socket_stream/socket_stream.h"
6
7 #include <string>
8 #include <vector>
9
10 #include "base/bind.h"
11 #include "base/bind_helpers.h"
12 #include "base/callback.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "net/base/auth.h"
15 #include "net/base/net_log.h"
16 #include "net/base/net_log_unittest.h"
17 #include "net/base/test_completion_callback.h"
18 #include "net/dns/mock_host_resolver.h"
19 #include "net/http/http_network_session.h"
20 #include "net/proxy/proxy_service.h"
21 #include "net/socket/socket_test_util.h"
22 #include "net/url_request/url_request_test_util.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24 #include "testing/platform_test.h"
25
26 using base::ASCIIToUTF16;
27
28 namespace net {
29
30 namespace {
31
32 struct SocketStreamEvent {
33 enum EventType {
34 EVENT_START_OPEN_CONNECTION, EVENT_CONNECTED, EVENT_SENT_DATA,
35 EVENT_RECEIVED_DATA, EVENT_CLOSE, EVENT_AUTH_REQUIRED, EVENT_ERROR,
36 };
37
38 SocketStreamEvent(EventType type,
39 SocketStream* socket_stream,
40 int num,
41 const std::string& str,
42 AuthChallengeInfo* auth_challenge_info,
43 int error)
44 : event_type(type), socket(socket_stream), number(num), data(str),
45 auth_info(auth_challenge_info), error_code(error) {}
46
47 EventType event_type;
48 SocketStream* socket;
49 int number;
50 std::string data;
51 scoped_refptr<AuthChallengeInfo> auth_info;
52 int error_code;
53 };
54
55 class SocketStreamEventRecorder : public SocketStream::Delegate {
56 public:
57 // |callback| will be run when the OnClose() or OnError() method is called.
58 // For OnClose(), |callback| is called with OK. For OnError(), it's called
59 // with the error code.
60 explicit SocketStreamEventRecorder(const CompletionCallback& callback)
61 : callback_(callback) {}
62 ~SocketStreamEventRecorder() override {}
63
64 void SetOnStartOpenConnection(
65 const base::Callback<int(SocketStreamEvent*)>& callback) {
66 on_start_open_connection_ = callback;
67 }
68 void SetOnConnected(
69 const base::Callback<void(SocketStreamEvent*)>& callback) {
70 on_connected_ = callback;
71 }
72 void SetOnSentData(
73 const base::Callback<void(SocketStreamEvent*)>& callback) {
74 on_sent_data_ = callback;
75 }
76 void SetOnReceivedData(
77 const base::Callback<void(SocketStreamEvent*)>& callback) {
78 on_received_data_ = callback;
79 }
80 void SetOnClose(const base::Callback<void(SocketStreamEvent*)>& callback) {
81 on_close_ = callback;
82 }
83 void SetOnAuthRequired(
84 const base::Callback<void(SocketStreamEvent*)>& callback) {
85 on_auth_required_ = callback;
86 }
87 void SetOnError(const base::Callback<void(SocketStreamEvent*)>& callback) {
88 on_error_ = callback;
89 }
90
91 int OnStartOpenConnection(SocketStream* socket,
92 const CompletionCallback& callback) override {
93 connection_callback_ = callback;
94 events_.push_back(
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());
99 return OK;
100 }
101 void OnConnected(SocketStream* socket,
102 int num_pending_send_allowed) override {
103 events_.push_back(
104 SocketStreamEvent(SocketStreamEvent::EVENT_CONNECTED,
105 socket, num_pending_send_allowed, std::string(),
106 NULL, OK));
107 if (!on_connected_.is_null())
108 on_connected_.Run(&events_.back());
109 }
110 void OnSentData(SocketStream* socket, int amount_sent) override {
111 events_.push_back(
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());
116 }
117 void OnReceivedData(SocketStream* socket,
118 const char* data,
119 int len) override {
120 events_.push_back(
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());
125 }
126 void OnClose(SocketStream* socket) override {
127 events_.push_back(
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())
133 callback_.Run(OK);
134 }
135 void OnAuthRequired(SocketStream* socket,
136 AuthChallengeInfo* auth_info) override {
137 events_.push_back(
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());
142 }
143 void OnError(const SocketStream* socket, int error) override {
144 events_.push_back(
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);
151 }
152
153 void DoClose(SocketStreamEvent* event) {
154 event->socket->Close();
155 }
156 void DoRestartWithAuth(SocketStreamEvent* event) {
157 VLOG(1) << "RestartWithAuth username=" << credentials_.username()
158 << " password=" << credentials_.password();
159 event->socket->RestartWithAuth(credentials_);
160 }
161 void SetAuthInfo(const AuthCredentials& credentials) {
162 credentials_ = credentials;
163 }
164 // Wakes up the SocketStream waiting for completion of OnStartOpenConnection()
165 // of its delegate.
166 void CompleteConnection(int result) {
167 connection_callback_.Run(result);
168 }
169
170 const std::vector<SocketStreamEvent>& GetSeenEvents() const {
171 return events_;
172 }
173
174 private:
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_;
186
187 DISALLOW_COPY_AND_ASSIGN(SocketStreamEventRecorder);
188 };
189
190 // This is used for the test OnErrorDetachDelegate.
191 class SelfDeletingDelegate : public SocketStream::Delegate {
192 public:
193 // |callback| must cause the test message loop to exit when called.
194 explicit SelfDeletingDelegate(const CompletionCallback& callback)
195 : socket_stream_(), callback_(callback) {}
196
197 ~SelfDeletingDelegate() override {}
198
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
202 // afterwards.
203 CompletionCallback callback = callback_;
204 socket_stream_->DetachDelegate();
205 delete this;
206 callback.Run(OK);
207 }
208
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);
214 }
215
216 void OnConnected(SocketStream* socket,
217 int max_pending_send_allowed) override {
218 ADD_FAILURE() << "OnConnected() should not be called";
219 }
220 void OnSentData(SocketStream* socket, int amount_sent) override {
221 ADD_FAILURE() << "OnSentData() should not be called";
222 }
223 void OnReceivedData(SocketStream* socket,
224 const char* data,
225 int len) override {
226 ADD_FAILURE() << "OnReceivedData() should not be called";
227 }
228 void OnClose(SocketStream* socket) override {
229 ADD_FAILURE() << "OnClose() should not be called";
230 }
231
232 private:
233 scoped_refptr<SocketStream> socket_stream_;
234 const CompletionCallback callback_;
235
236 DISALLOW_COPY_AND_ASSIGN(SelfDeletingDelegate);
237 };
238
239 class TestURLRequestContextWithProxy : public TestURLRequestContext {
240 public:
241 explicit TestURLRequestContextWithProxy(const std::string& proxy)
242 : TestURLRequestContext(true) {
243 context_storage_.set_proxy_service(ProxyService::CreateFixed(proxy));
244 Init();
245 }
246 ~TestURLRequestContextWithProxy() override {}
247 };
248
249 class TestSocketStreamNetworkDelegate : public TestNetworkDelegate {
250 public:
251 TestSocketStreamNetworkDelegate()
252 : before_connect_result_(OK) {}
253 ~TestSocketStreamNetworkDelegate() override {}
254
255 int OnBeforeSocketStreamConnect(SocketStream* stream,
256 const CompletionCallback& callback) override {
257 return before_connect_result_;
258 }
259
260 void SetBeforeConnectResult(int result) {
261 before_connect_result_ = result;
262 }
263
264 private:
265 int before_connect_result_;
266 };
267
268 } // namespace
269
270 class SocketStreamTest : public PlatformTest {
271 public:
272 ~SocketStreamTest() override {}
273 void SetUp() override {
274 mock_socket_factory_.reset();
275 handshake_request_ = kWebSocketHandshakeRequest;
276 handshake_response_ = kWebSocketHandshakeResponse;
277 }
278 void TearDown() override { mock_socket_factory_.reset(); }
279
280 virtual void SetWebSocketHandshakeMessage(
281 const char* request, const char* response) {
282 handshake_request_ = request;
283 handshake_response_ = response;
284 }
285 virtual void AddWebSocketMessage(const std::string& message) {
286 messages_.push_back(message);
287 }
288
289 virtual MockClientSocketFactory* GetMockClientSocketFactory() {
290 mock_socket_factory_.reset(new MockClientSocketFactory);
291 return mock_socket_factory_.get();
292 }
293
294 // Functions for SocketStreamEventRecorder to handle calls to the
295 // SocketStream::Delegate methods from the SocketStream.
296
297 virtual void DoSendWebSocketHandshake(SocketStreamEvent* event) {
298 event->socket->SendData(
299 handshake_request_.data(), handshake_request_.size());
300 }
301
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()));
310 }
311 // Actual StreamSocket close must happen after all frames queued by
312 // SendData above are sent out.
313 event->socket->Close();
314 }
315
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()));
326 }
327 // Actual StreamSocket close must happen after all frames queued by
328 // SendData above are sent out.
329 event->socket->Close();
330 }
331
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();
337 }
338
339 virtual int DoSwitchToSpdyTest(SocketStreamEvent* event) {
340 return ERR_PROTOCOL_SWITCHED;
341 }
342
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;
348 }
349
350 static const char kWebSocketHandshakeRequest[];
351 static const char kWebSocketHandshakeResponse[];
352
353 protected:
354 TestCompletionCallback io_test_callback_;
355
356 private:
357 std::string handshake_request_;
358 std::string handshake_response_;
359 std::vector<std::string> messages_;
360
361 scoped_ptr<MockClientSocketFactory> mock_socket_factory_;
362 };
363
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"
373 "\r\n"
374 "^n:ds[4U";
375
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"
383 "\r\n"
384 "8jKS'y:G*Co,Wxa-";
385
386 TEST_F(SocketStreamTest, CloseFlushPendingWrite) {
387 TestCompletionCallback test_callback;
388
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)));
396
397 TestURLRequestContext context;
398
399 scoped_refptr<SocketStream> socket_stream(
400 new SocketStream(GURL("ws://example.com/demo"), delegate.get(),
401 &context, NULL));
402
403 MockWrite data_writes[] = {
404 MockWrite(SocketStreamTest::kWebSocketHandshakeRequest),
405 MockWrite(ASYNC, "\0message1\xff", 10),
406 MockWrite(ASYNC, "\0message2\xff", 10)
407 };
408 MockRead data_reads[] = {
409 MockRead(SocketStreamTest::kWebSocketHandshakeResponse),
410 // Server doesn't close the connection after handshake.
411 MockRead(ASYNC, ERR_IO_PENDING)
412 };
413 AddWebSocketMessage("message1");
414 AddWebSocketMessage("message2");
415
416 DelayedSocketData data_provider(
417 1, data_reads, arraysize(data_reads),
418 data_writes, arraysize(data_writes));
419
420 MockClientSocketFactory* mock_socket_factory =
421 GetMockClientSocketFactory();
422 mock_socket_factory->AddSocketDataProvider(&data_provider);
423
424 socket_stream->SetClientSocketFactory(mock_socket_factory);
425
426 socket_stream->Connect();
427
428 test_callback.WaitForResult();
429
430 EXPECT_TRUE(data_provider.at_read_eof());
431 EXPECT_TRUE(data_provider.at_write_eof());
432
433 const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents();
434 ASSERT_EQ(7U, events.size());
435
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);
444 }
445
446 TEST_F(SocketStreamTest, ResolveFailure) {
447 TestCompletionCallback test_callback;
448
449 scoped_ptr<SocketStreamEventRecorder> delegate(
450 new SocketStreamEventRecorder(test_callback.callback()));
451
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());
458
459 scoped_refptr<SocketStream> socket_stream(
460 new SocketStream(GURL("ws://example.com/demo"), delegate.get(),
461 &context, NULL));
462
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);
469
470 socket_stream->Connect();
471
472 test_callback.WaitForResult();
473
474 const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents();
475 ASSERT_EQ(2U, events.size());
476
477 EXPECT_EQ(SocketStreamEvent::EVENT_ERROR, events[0].event_type);
478 EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE, events[1].event_type);
479 }
480
481 TEST_F(SocketStreamTest, ExceedMaxPendingSendAllowed) {
482 TestCompletionCallback test_callback;
483
484 scoped_ptr<SocketStreamEventRecorder> delegate(
485 new SocketStreamEventRecorder(test_callback.callback()));
486 delegate->SetOnConnected(base::Bind(
487 &SocketStreamTest::DoFailByTooBigDataAndClose, base::Unretained(this)));
488
489 TestURLRequestContext context;
490
491 scoped_refptr<SocketStream> socket_stream(
492 new SocketStream(GURL("ws://example.com/demo"), delegate.get(),
493 &context, NULL));
494
495 DelayedSocketData data_provider(1, NULL, 0, NULL, 0);
496
497 MockClientSocketFactory* mock_socket_factory =
498 GetMockClientSocketFactory();
499 mock_socket_factory->AddSocketDataProvider(&data_provider);
500
501 socket_stream->SetClientSocketFactory(mock_socket_factory);
502
503 socket_stream->Connect();
504
505 test_callback.WaitForResult();
506
507 const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents();
508 ASSERT_EQ(4U, events.size());
509
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);
515 }
516
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"),
523 };
524 MockRead data_reads1[] = {
525 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
526 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
527 MockRead("\r\n"),
528 };
529 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
530 data_writes1, arraysize(data_writes1));
531 mock_socket_factory.AddSocketDataProvider(&data1);
532
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"),
538 };
539 MockRead data_reads2[] = {
540 MockRead("HTTP/1.1 200 Connection Established\r\n"),
541 MockRead("Proxy-agent: Apache/2.2.8\r\n"),
542 MockRead("\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)
547 };
548 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
549 data_writes2, arraysize(data_writes2));
550 mock_socket_factory.AddSocketDataProvider(&data2);
551
552 TestCompletionCallback test_callback;
553
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())));
563
564 TestURLRequestContextWithProxy context("myproxy:70");
565
566 scoped_refptr<SocketStream> socket_stream(
567 new SocketStream(GURL("ws://example.com/demo"), delegate.get(),
568 &context, NULL));
569
570 socket_stream->SetClientSocketFactory(&mock_socket_factory);
571
572 socket_stream->Connect();
573
574 test_callback.WaitForResult();
575
576 const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents();
577 ASSERT_EQ(5U, events.size());
578
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);
586
587 // TODO(eroman): Add back NetLogTest here...
588 }
589
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"),
599 };
600 MockRead data_reads[] = {
601 MockRead("HTTP/1.1 200 Connection Established\r\n"),
602 MockRead("Proxy-agent: Apache/2.2.8\r\n"),
603 MockRead("\r\n"),
604 MockRead(ASYNC, ERR_IO_PENDING)
605 };
606 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
607 data_writes, arraysize(data_writes));
608 mock_socket_factory.AddSocketDataProvider(&data);
609
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())));
615
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"),
620 "MyRealm1",
621 HttpAuth::AUTH_SCHEME_BASIC,
622 "Basic realm=MyRealm1",
623 AuthCredentials(ASCIIToUTF16("foo"),
624 ASCIIToUTF16("bar")),
625 "/");
626
627 scoped_refptr<SocketStream> socket_stream(
628 new SocketStream(GURL("ws://example.com/demo"), delegate.get(),
629 &context, NULL));
630
631 socket_stream->SetClientSocketFactory(&mock_socket_factory);
632
633 socket_stream->Connect();
634
635 test_callback.WaitForResult();
636
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);
644 }
645
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"),
653 };
654 MockRead data_reads1[] = {
655 MockRead("HTTP/1.1 200 Connection Established\r\n"),
656 MockRead("Proxy-agent: Apache/2.2.8\r\n"),
657 MockRead("\r\n"),
658 MockRead(ASYNC, ERR_IO_PENDING)
659 };
660 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
661 data_writes1, arraysize(data_writes1));
662 mock_socket_factory.AddSocketDataProvider(&data1);
663
664 SSLSocketDataProvider data2(ASYNC, OK);
665 mock_socket_factory.AddSSLSocketDataProvider(&data2);
666
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())));
672
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"),
677 "MyRealm1",
678 HttpAuth::AUTH_SCHEME_BASIC,
679 "Basic realm=MyRealm1",
680 AuthCredentials(ASCIIToUTF16("foo"),
681 ASCIIToUTF16("bar")),
682 "/");
683
684 scoped_refptr<SocketStream> socket_stream(
685 new SocketStream(GURL("wss://example.com/demo"), delegate.get(),
686 &context, NULL));
687
688 socket_stream->SetClientSocketFactory(&mock_socket_factory);
689
690 socket_stream->Connect();
691
692 test_callback.WaitForResult();
693
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);
701 }
702
703 TEST_F(SocketStreamTest, IOPending) {
704 TestCompletionCallback test_callback;
705
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)));
715
716 TestURLRequestContext context;
717
718 scoped_refptr<SocketStream> socket_stream(
719 new SocketStream(GURL("ws://example.com/demo"), delegate.get(),
720 &context, NULL));
721
722 MockWrite data_writes[] = {
723 MockWrite(SocketStreamTest::kWebSocketHandshakeRequest),
724 MockWrite(ASYNC, "\0message1\xff", 10),
725 MockWrite(ASYNC, "\0message2\xff", 10)
726 };
727 MockRead data_reads[] = {
728 MockRead(SocketStreamTest::kWebSocketHandshakeResponse),
729 // Server doesn't close the connection after handshake.
730 MockRead(ASYNC, ERR_IO_PENDING)
731 };
732 AddWebSocketMessage("message1");
733 AddWebSocketMessage("message2");
734
735 DelayedSocketData data_provider(
736 1, data_reads, arraysize(data_reads),
737 data_writes, arraysize(data_writes));
738
739 MockClientSocketFactory* mock_socket_factory =
740 GetMockClientSocketFactory();
741 mock_socket_factory->AddSocketDataProvider(&data_provider);
742
743 socket_stream->SetClientSocketFactory(mock_socket_factory);
744
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);
750
751 EXPECT_EQ(OK, test_callback.WaitForResult());
752
753 EXPECT_TRUE(data_provider.at_read_eof());
754 EXPECT_TRUE(data_provider.at_write_eof());
755
756 const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents();
757 ASSERT_EQ(7U, events.size());
758
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);
767 }
768
769 TEST_F(SocketStreamTest, SwitchToSpdy) {
770 TestCompletionCallback test_callback;
771
772 scoped_ptr<SocketStreamEventRecorder> delegate(
773 new SocketStreamEventRecorder(test_callback.callback()));
774 delegate->SetOnStartOpenConnection(base::Bind(
775 &SocketStreamTest::DoSwitchToSpdyTest, base::Unretained(this)));
776
777 TestURLRequestContext context;
778
779 scoped_refptr<SocketStream> socket_stream(
780 new SocketStream(GURL("ws://example.com/demo"), delegate.get(),
781 &context, NULL));
782
783 socket_stream->Connect();
784
785 EXPECT_EQ(ERR_PROTOCOL_SWITCHED, test_callback.WaitForResult());
786
787 const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents();
788 ASSERT_EQ(2U, events.size());
789
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);
794 }
795
796 TEST_F(SocketStreamTest, SwitchAfterPending) {
797 TestCompletionCallback test_callback;
798
799 scoped_ptr<SocketStreamEventRecorder> delegate(
800 new SocketStreamEventRecorder(test_callback.callback()));
801 delegate->SetOnStartOpenConnection(base::Bind(
802 &SocketStreamTest::DoIOPending, base::Unretained(this)));
803
804 TestURLRequestContext context;
805
806 scoped_refptr<SocketStream> socket_stream(
807 new SocketStream(GURL("ws://example.com/demo"), delegate.get(),
808 &context, NULL));
809
810 socket_stream->Connect();
811 io_test_callback_.WaitForResult();
812
813 EXPECT_EQ(SocketStream::STATE_RESOLVE_PROTOCOL_COMPLETE,
814 socket_stream->next_state_);
815 delegate->CompleteConnection(ERR_PROTOCOL_SWITCHED);
816
817 EXPECT_EQ(ERR_PROTOCOL_SWITCHED, test_callback.WaitForResult());
818
819 const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents();
820 ASSERT_EQ(2U, events.size());
821
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);
826 }
827
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")
835 };
836 MockRead data_reads[] = {
837 MockRead("HTTP/1.1 200 Connection Established\r\n"),
838 MockRead("Proxy-agent: Apache/2.2.8\r\n"),
839 MockRead("\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)
844 };
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);
850
851 TestCompletionCallback test_callback;
852 TestURLRequestContextWithProxy context("https://myproxy:70");
853
854 scoped_ptr<SocketStreamEventRecorder> delegate(
855 new SocketStreamEventRecorder(test_callback.callback()));
856 delegate->SetOnConnected(base::Bind(&SocketStreamEventRecorder::DoClose,
857 base::Unretained(delegate.get())));
858
859 scoped_refptr<SocketStream> socket_stream(
860 new SocketStream(GURL("ws://example.com/demo"), delegate.get(),
861 &context, NULL));
862
863 socket_stream->SetClientSocketFactory(&mock_socket_factory);
864
865 socket_stream->Connect();
866
867 test_callback.WaitForResult();
868
869 const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents();
870 ASSERT_EQ(3U, events.size());
871
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);
877 }
878
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")
886 };
887 MockRead data_reads[] = {
888 MockRead("HTTP/1.1 200 Connection Established\r\n"),
889 MockRead("Proxy-agent: Apache/2.2.8\r\n"),
890 MockRead("\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)
895 };
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);
901
902 TestCompletionCallback test_callback;
903 TestURLRequestContextWithProxy context("https://myproxy:70");
904
905 scoped_ptr<SocketStreamEventRecorder> delegate(
906 new SocketStreamEventRecorder(test_callback.callback()));
907 delegate->SetOnConnected(base::Bind(&SocketStreamEventRecorder::DoClose,
908 base::Unretained(delegate.get())));
909
910 scoped_refptr<SocketStream> socket_stream(
911 new SocketStream(GURL("ws://example.com/demo"), delegate.get(),
912 &context, NULL));
913
914 socket_stream->SetClientSocketFactory(&mock_socket_factory);
915
916 socket_stream->Connect();
917
918 test_callback.WaitForResult();
919
920 const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents();
921 ASSERT_EQ(4U, events.size());
922
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);
929 }
930
931 TEST_F(SocketStreamTest, BeforeConnectFailed) {
932 TestCompletionCallback test_callback;
933
934 scoped_ptr<SocketStreamEventRecorder> delegate(
935 new SocketStreamEventRecorder(test_callback.callback()));
936
937 TestURLRequestContext context;
938 TestSocketStreamNetworkDelegate network_delegate;
939 network_delegate.SetBeforeConnectResult(ERR_ACCESS_DENIED);
940 context.set_network_delegate(&network_delegate);
941
942 scoped_refptr<SocketStream> socket_stream(
943 new SocketStream(GURL("ws://example.com/demo"), delegate.get(),
944 &context, NULL));
945
946 socket_stream->Connect();
947
948 test_callback.WaitForResult();
949
950 const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents();
951 ASSERT_EQ(2U, events.size());
952
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);
956 }
957
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;
963
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);
972
973 TestURLRequestContext context;
974 scoped_refptr<SocketStream> socket_stream(
975 new SocketStream(GURL("ws://localhost:9998/echo"), delegate,
976 &context, NULL));
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.
981 delegate = NULL;
982
983 socket_stream->Connect();
984
985 EXPECT_EQ(OK, test_callback.WaitForResult());
986 }
987
988 TEST_F(SocketStreamTest, NullContextSocketStreamShouldNotCrash) {
989 TestCompletionCallback test_callback;
990
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(),
996 &context, NULL));
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)));
1004
1005 MockWrite data_writes[] = {
1006 MockWrite(SocketStreamTest::kWebSocketHandshakeRequest),
1007 };
1008 MockRead data_reads[] = {
1009 MockRead(SocketStreamTest::kWebSocketHandshakeResponse),
1010 };
1011 AddWebSocketMessage("message1");
1012 AddWebSocketMessage("message2");
1013
1014 DelayedSocketData data_provider(
1015 1, data_reads, arraysize(data_reads),
1016 data_writes, arraysize(data_writes));
1017
1018 MockClientSocketFactory* mock_socket_factory = GetMockClientSocketFactory();
1019 mock_socket_factory->AddSocketDataProvider(&data_provider);
1020 socket_stream->SetClientSocketFactory(mock_socket_factory);
1021
1022 socket_stream->Connect();
1023 io_test_callback_.WaitForResult();
1024 delegate->CompleteConnection(OK);
1025 EXPECT_EQ(OK, test_callback.WaitForResult());
1026
1027 EXPECT_TRUE(data_provider.at_read_eof());
1028 EXPECT_TRUE(data_provider.at_write_eof());
1029
1030 const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents();
1031 ASSERT_EQ(5U, events.size());
1032
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);
1039 }
1040
1041 } // namespace net
OLDNEW
« no previous file with comments | « net/socket_stream/socket_stream_metrics_unittest.cc ('k') | net/spdy/buffered_spdy_framer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698