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

Side by Side Diff: net/spdy/spdy_proxy_client_socket_unittest.cc

Issue 3391029: Revert 60747 - Add a new class SpdyProxyClientSocket which implements ClientS... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 10 years, 2 months 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 | Annotate | Revision Log
« no previous file with comments | « net/spdy/spdy_proxy_client_socket.cc ('k') | net/spdy/spdy_session.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) 2010 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/spdy/spdy_proxy_client_socket.h"
6
7 #include "base/utf_string_conversions.h"
8 #include "net/base/address_list.h"
9 #include "net/base/net_log.h"
10 #include "net/base/net_log_unittest.h"
11 #include "net/base/mock_host_resolver.h"
12 #include "net/base/test_completion_callback.h"
13 #include "net/base/winsock_init.h"
14 #include "net/http/http_response_info.h"
15 #include "net/http/http_response_headers.h"
16 #include "net/socket/client_socket_factory.h"
17 #include "net/socket/tcp_client_socket.h"
18 #include "net/socket/socket_test_util.h"
19 #include "net/spdy/spdy_protocol.h"
20 #include "net/spdy/spdy_session_pool.h"
21 #include "net/spdy/spdy_test_util.h"
22 #include "testing/platform_test.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24
25 //-----------------------------------------------------------------------------
26
27 namespace {
28
29 static const char kUrl[] = "https://www.google.com/";
30 static const char kOriginHost[] = "www.google.com";
31 static const int kOriginPort = 443;
32 static const char kOriginHostPort[] = "www.google.com:443";
33 static const char kProxyUrl[] = "http://myproxy:6121/";
34 static const char kProxyHost[] = "myproxy";
35 static const int kProxyPort = 6121;
36 static const char kUserAgent[] = "Mozilla/1.0";
37
38 static const int kStreamId = 1;
39
40 static const char kMsg1[] = "\0hello!\xff";
41 static const int kLen1 = 8;
42 static const char kMsg2[] = "\012345678\0";
43 static const int kLen2 = 10;
44 static const char kMsg3[] = "bye!";
45 static const int kLen3 = 4;
46 static const char kMsg33[] = "bye!bye!";
47 static const int kLen33 = kLen3 + kLen3;
48
49 } // anonymous namespace
50
51 namespace net {
52
53 class SpdyProxyClientSocketTest : public PlatformTest {
54 public:
55 SpdyProxyClientSocketTest();
56
57 virtual void TearDown();
58
59 protected:
60 void Initialize(MockRead* reads, size_t reads_count, MockWrite* writes,
61 size_t writes_count);
62 spdy::SpdyFrame* ConstructConnectRequestFrame();
63 spdy::SpdyFrame* ConstructConnectAuthRequestFrame();
64 spdy::SpdyFrame* ConstructConnectReplyFrame();
65 spdy::SpdyFrame* ConstructConnectAuthReplyFrame();
66 spdy::SpdyFrame* ConstructConnectErrorReplyFrame();
67 spdy::SpdyFrame* ConstructBodyFrame(const char* data, int length);
68 scoped_refptr<IOBufferWithSize> CreateBuffer(const char* data, int size);
69 void AssertConnectSucceeds();
70 void AssertConnectionEstablished();
71 void AssertSyncReadEquals(const char* data, int len);
72 void AssertAsyncReadEquals(const char* data, int len);
73 void AssertAsyncWriteSucceeds(const char* data, int len);
74 void AssertAsyncWriteWithReadsSucceeds(const char* data, int len,
75 int num_reads);
76
77 void AddAuthToCache() {
78 const string16 kFoo(ASCIIToUTF16("foo"));
79 const string16 kBar(ASCIIToUTF16("bar"));
80 session_->auth_cache()->Add(GURL(kProxyUrl), "MyRealm1", "Basic",
81 "Basic realm=MyRealm1", kFoo, kBar, "/");
82 }
83
84 scoped_ptr<SpdyProxyClientSocket> sock_;
85 TestCompletionCallback callback_;
86
87 private:
88 scoped_refptr<HttpNetworkSession> session_;
89 scoped_refptr<OrderedSocketData> data_;
90 SpdySessionDependencies session_deps_;
91 MockConnect connect_data_;
92 scoped_refptr<SpdySession> spdy_session_;
93 scoped_refptr<SpdyStream> spdy_stream_;
94 spdy::SpdyFramer framer_;
95
96 std::string user_agent_;
97 GURL url_;
98 HostPortPair proxy_host_port_;
99 HostPortPair endpoint_host_port_pair_;
100 ProxyServer proxy_;
101 HostPortProxyPair endpoint_host_port_proxy_pair_;
102 scoped_refptr<TCPSocketParams> tcp_params_;
103
104 DISALLOW_COPY_AND_ASSIGN(SpdyProxyClientSocketTest);
105 };
106
107 SpdyProxyClientSocketTest::SpdyProxyClientSocketTest()
108 : sock_(NULL),
109 callback_(),
110 session_(NULL),
111 data_(NULL),
112 session_deps_(),
113 connect_data_(false, OK),
114 spdy_session_(NULL),
115 spdy_stream_(NULL),
116 framer_(),
117 user_agent_(kUserAgent),
118 url_(kUrl),
119 proxy_host_port_(kProxyHost, kProxyPort),
120 endpoint_host_port_pair_(kOriginHost, kOriginPort),
121 proxy_(ProxyServer::SCHEME_HTTPS, proxy_host_port_),
122 endpoint_host_port_proxy_pair_(endpoint_host_port_pair_, proxy_),
123 tcp_params_(new TCPSocketParams(proxy_host_port_, LOWEST, url_, false)) {
124 }
125
126 void SpdyProxyClientSocketTest::TearDown() {
127 if (session_ != NULL)
128 session_->spdy_session_pool()->CloseAllSessions();
129
130 spdy::SpdyFramer::set_enable_compression_default(true);
131 // Empty the current queue.
132 MessageLoop::current()->RunAllPending();
133 PlatformTest::TearDown();
134 }
135
136 void SpdyProxyClientSocketTest::Initialize(MockRead* reads,
137 size_t reads_count,
138 MockWrite* writes,
139 size_t writes_count) {
140 data_ = new OrderedSocketData(reads, reads_count, writes, writes_count);
141 data_->set_connect_data(connect_data_);
142
143 session_deps_.socket_factory->AddSocketDataProvider(data_.get());
144 session_deps_.host_resolver->set_synchronous_mode(true);
145
146 session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_);
147 SpdySession::SetSSLMode(false);
148 spdy::SpdyFramer::set_enable_compression_default(false);
149
150 // Creates a new spdy session
151 spdy_session_ =
152 session_->spdy_session_pool()->Get(endpoint_host_port_proxy_pair_,
153 session_->mutable_spdy_settings(),
154 BoundNetLog());
155
156 // Perform the TCP connect
157 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
158 EXPECT_EQ(OK,
159 connection->Init(endpoint_host_port_pair_.ToString(), tcp_params_,
160 LOWEST, NULL, session_->tcp_socket_pool(),
161 BoundNetLog()));
162 spdy_session_->InitializeWithSocket(connection.release(), false, OK);
163
164 // Create the SPDY Stream
165 ASSERT_EQ(
166 OK,
167 spdy_session_->CreateStream(url_, LOWEST, &spdy_stream_, BoundNetLog(),
168 NULL));
169
170 // Create the SpdyProxyClientSocket
171 sock_.reset(
172 new SpdyProxyClientSocket(spdy_stream_, user_agent_,
173 endpoint_host_port_pair_, url_,
174 proxy_host_port_, session_->auth_cache(),
175 session_->http_auth_handler_factory()));
176 }
177
178 scoped_refptr<IOBufferWithSize> SpdyProxyClientSocketTest::CreateBuffer(
179 const char* data, int size) {
180 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(size));
181 memcpy(buf->data(), data, size);
182 return buf;
183 }
184
185 void SpdyProxyClientSocketTest::AssertConnectSucceeds() {
186 ASSERT_EQ(ERR_IO_PENDING, sock_->Connect(&callback_));
187 ASSERT_EQ(OK, callback_.WaitForResult());
188 }
189
190 void SpdyProxyClientSocketTest::AssertConnectionEstablished() {
191 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
192 ASSERT_TRUE(response != NULL);
193 ASSERT_EQ(200, response->headers->response_code());
194 ASSERT_EQ("Connection Established", response->headers->GetStatusText());
195 }
196
197 void SpdyProxyClientSocketTest::AssertSyncReadEquals(const char* data,
198 int len) {
199 scoped_refptr<IOBuffer> buf(new IOBuffer(len));
200 ASSERT_EQ(len, sock_->Read(buf, len, NULL));
201 ASSERT_EQ(std::string(data, len), std::string(buf->data(), len));
202 ASSERT_TRUE(sock_->IsConnected());
203 }
204
205 void SpdyProxyClientSocketTest::AssertAsyncReadEquals(const char* data,
206 int len) {
207 // Issue the read, which will be completed asynchronously
208 scoped_refptr<IOBuffer> buf(new IOBuffer(len));
209 ASSERT_EQ(ERR_IO_PENDING, sock_->Read(buf, len, &callback_));
210 EXPECT_TRUE(sock_->IsConnected());
211
212 // Dummy write to un-block the read
213 AssertAsyncWriteSucceeds(kMsg2, kLen2);
214 EXPECT_TRUE(sock_->IsConnected());
215
216 // Now the read will return
217 EXPECT_EQ(len, callback_.WaitForResult());
218 ASSERT_EQ(std::string(data, len), std::string(buf->data(), len));
219 }
220
221 void SpdyProxyClientSocketTest::AssertAsyncWriteSucceeds(const char* data,
222 int len) {
223 AssertAsyncWriteWithReadsSucceeds(data, len, 0);
224 }
225
226 void SpdyProxyClientSocketTest::AssertAsyncWriteWithReadsSucceeds(
227 const char* data, int len, int num_reads) {
228 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(data, len));
229
230 TestCompletionCallback callback;
231 EXPECT_EQ(ERR_IO_PENDING, sock_->Write(buf, buf->size(), &callback));
232
233 // Dummy reads to un-block the writes
234 for (int i = 0; i < num_reads; i++) {
235 AssertSyncReadEquals(kMsg2, kLen2);
236 }
237
238 callback.WaitForResult();
239 }
240
241 // Constructs a standard SPDY SYN_STREAM frame for a CONNECT request.
242 spdy::SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectRequestFrame() {
243 const SpdyHeaderInfo kSynStartHeader = {
244 spdy::SYN_STREAM,
245 kStreamId,
246 0,
247 net::ConvertRequestPriorityToSpdyPriority(LOWEST),
248 spdy::CONTROL_FLAG_NONE,
249 false,
250 spdy::INVALID,
251 NULL,
252 0,
253 spdy::DATA_FLAG_NONE
254 };
255 const char* const kConnectHeaders[] = {
256 "method", "CONNECT",
257 "url", kOriginHostPort,
258 "host", kOriginHost,
259 "user-agent", kUserAgent,
260 "version", "HTTP/1.1",
261 "proxy-connection", "keep-alive",
262 };
263 return ConstructSpdyPacket(
264 kSynStartHeader, NULL, 0, kConnectHeaders, arraysize(kConnectHeaders)/2);
265 }
266
267 // Constructs a SPDY SYN_STREAM frame for a CONNECT request which includes
268 // Proxy-Authorization headers.
269 spdy::SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectAuthRequestFrame() {
270 const SpdyHeaderInfo kSynStartHeader = {
271 spdy::SYN_STREAM,
272 kStreamId,
273 0,
274 net::ConvertRequestPriorityToSpdyPriority(LOWEST),
275 spdy::CONTROL_FLAG_NONE,
276 false,
277 spdy::INVALID,
278 NULL,
279 0,
280 spdy::DATA_FLAG_NONE
281 };
282 const char* const kConnectHeaders[] = {
283 "method", "CONNECT",
284 "url", kOriginHostPort,
285 "host", kOriginHost,
286 "user-agent", kUserAgent,
287 "version", "HTTP/1.1",
288 "proxy-authorization", "Basic Zm9vOmJhcg==",
289 "proxy-connection", "keep-alive",
290 };
291 return ConstructSpdyPacket(
292 kSynStartHeader, NULL, 0, kConnectHeaders, arraysize(kConnectHeaders)/2);
293 }
294
295 // Constructs a standard SPDY SYN_REPLY frame to match the SPDY CONNECT.
296 spdy::SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectReplyFrame() {
297 const char* const kStandardReplyHeaders[] = {
298 "status", "200 Connection Established",
299 "version", "HTTP/1.1"
300 };
301 return ConstructSpdyControlFrame(NULL,
302 0,
303 false,
304 kStreamId,
305 LOWEST,
306 spdy::SYN_REPLY,
307 spdy::CONTROL_FLAG_NONE,
308 kStandardReplyHeaders,
309 arraysize(kStandardReplyHeaders));
310 }
311
312 // Constructs a standard SPDY SYN_REPLY frame to match the SPDY CONNECT.
313 spdy::SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectAuthReplyFrame() {
314 const char* const kStandardReplyHeaders[] = {
315 "status", "407 Proxy Authentication Required",
316 "version", "HTTP/1.1",
317 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
318 };
319
320 return ConstructSpdyControlFrame(NULL,
321 0,
322 false,
323 kStreamId,
324 LOWEST,
325 spdy::SYN_REPLY,
326 spdy::CONTROL_FLAG_NONE,
327 kStandardReplyHeaders,
328 arraysize(kStandardReplyHeaders));
329 }
330
331 // Constructs a SPDY SYN_REPLY frame with an HTTP 500 error.
332 spdy::SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectErrorReplyFrame() {
333 const char* const kStandardReplyHeaders[] = {
334 "status", "500 Internal Server Error",
335 "version", "HTTP/1.1",
336 };
337
338 return ConstructSpdyControlFrame(NULL,
339 0,
340 false,
341 kStreamId,
342 LOWEST,
343 spdy::SYN_REPLY,
344 spdy::CONTROL_FLAG_NONE,
345 kStandardReplyHeaders,
346 arraysize(kStandardReplyHeaders));
347 }
348
349 spdy::SpdyFrame* SpdyProxyClientSocketTest::ConstructBodyFrame(const char* data,
350 int length) {
351 return framer_.CreateDataFrame(kStreamId, data, length, spdy::DATA_FLAG_NONE);
352 }
353
354 // ----------- Connect
355
356 TEST_F(SpdyProxyClientSocketTest, ConnectSendsCorrectRequest) {
357 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
358 MockWrite writes[] = {
359 CreateMockWrite(*conn, 0),
360 };
361
362 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
363 MockRead reads[] = {
364 CreateMockRead(*resp, 1),
365 MockRead(true, 0, 0), // EOF
366 };
367
368 Initialize(reads, arraysize(reads), writes, arraysize(writes));
369
370 ASSERT_FALSE(sock_->IsConnected());
371
372 AssertConnectSucceeds();
373
374 AssertConnectionEstablished();
375 }
376
377 TEST_F(SpdyProxyClientSocketTest, ConnectWithAuthRequested) {
378 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
379 MockWrite writes[] = {
380 CreateMockWrite(*conn, 0),
381 };
382
383 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectAuthReplyFrame());
384 MockRead reads[] = {
385 CreateMockRead(*resp, 1),
386 MockRead(true, 0, 0), // EOF
387 };
388
389 Initialize(reads, arraysize(reads), writes, arraysize(writes));
390
391 EXPECT_EQ(ERR_IO_PENDING, sock_->Connect(&callback_));
392 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, callback_.WaitForResult());
393
394 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
395 ASSERT_TRUE(response != NULL);
396 ASSERT_EQ(407, response->headers->response_code());
397 ASSERT_EQ("Proxy Authentication Required",
398 response->headers->GetStatusText());
399 }
400
401 TEST_F(SpdyProxyClientSocketTest, ConnectWithAuthCredentials) {
402 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectAuthRequestFrame());
403 MockWrite writes[] = {
404 CreateMockWrite(*conn, 0),
405 };
406
407 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
408 MockRead reads[] = {
409 CreateMockRead(*resp, 1),
410 MockRead(true, 0, 0), // EOF
411 };
412
413 Initialize(reads, arraysize(reads), writes, arraysize(writes));
414 AddAuthToCache();
415
416 EXPECT_EQ(ERR_IO_PENDING, sock_->Connect(&callback_));
417 EXPECT_EQ(OK, callback_.WaitForResult());
418
419 AssertConnectionEstablished();
420 }
421
422 TEST_F(SpdyProxyClientSocketTest, ConnectFails) {
423 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
424 MockWrite writes[] = {
425 CreateMockWrite(*conn, 0),
426 };
427
428 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
429 MockRead reads[] = {
430 MockRead(true, 0, 0), // EOF
431 };
432
433 Initialize(reads, arraysize(reads), writes, arraysize(writes));
434
435 ASSERT_FALSE(sock_->IsConnected());
436
437 ASSERT_EQ(ERR_IO_PENDING, sock_->Connect(&callback_));
438 ASSERT_EQ(ERR_CONNECTION_CLOSED, callback_.WaitForResult());
439
440 ASSERT_FALSE(sock_->IsConnected());
441 }
442
443 // ----------- WasEverUsed
444
445 TEST_F(SpdyProxyClientSocketTest, WasEverUsedReturnsCorrectValues) {
446 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
447 MockWrite writes[] = {
448 CreateMockWrite(*conn, 0),
449 };
450
451 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
452 MockRead reads[] = {
453 CreateMockRead(*resp, 1),
454 MockRead(true, 0, 0), // EOF
455 };
456
457 Initialize(reads, arraysize(reads), writes, arraysize(writes));
458
459 EXPECT_FALSE(sock_->WasEverUsed());
460 AssertConnectSucceeds();
461 EXPECT_TRUE(sock_->WasEverUsed());
462 sock_->Disconnect();
463 EXPECT_TRUE(sock_->WasEverUsed());
464 }
465
466 // ----------- GetPeerAddress
467
468 TEST_F(SpdyProxyClientSocketTest, GetPeerAddressReturnsCorrectValues) {
469 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
470 MockWrite writes[] = {
471 CreateMockWrite(*conn, 1),
472 MockWrite(true, 0, 3), // EOF
473 };
474
475 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
476 MockRead reads[] = {
477 CreateMockRead(*resp, 2),
478 MockRead(false, 0, 4), // EOF
479 };
480
481 Initialize(reads, arraysize(reads), writes, arraysize(writes));
482
483 net::AddressList addr;
484 EXPECT_EQ(ERR_UNEXPECTED, sock_->GetPeerAddress(&addr));
485 AssertConnectSucceeds();
486 EXPECT_TRUE(sock_->IsConnected());
487 EXPECT_EQ(OK, sock_->GetPeerAddress(&addr));
488 sock_->Disconnect();
489 EXPECT_EQ(ERR_UNEXPECTED, sock_->GetPeerAddress(&addr));
490 }
491
492 // ----------- Write
493
494 TEST_F(SpdyProxyClientSocketTest, WriteSendsDataInDataFrame) {
495 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
496 scoped_ptr<spdy::SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
497 scoped_ptr<spdy::SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
498 MockWrite writes[] = {
499 CreateMockWrite(*conn, 0),
500 CreateMockWrite(*msg1, 3),
501 CreateMockWrite(*msg2, 4),
502 };
503
504 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
505 MockRead reads[] = {
506 CreateMockRead(*resp, 2),
507 MockRead(true, 0, 6), // EOF
508 };
509
510 Initialize(reads, arraysize(reads), writes, arraysize(writes));
511
512 AssertConnectSucceeds();
513
514 AssertAsyncWriteSucceeds(kMsg1, kLen1);
515 AssertAsyncWriteSucceeds(kMsg2, kLen2);
516 }
517
518 // ----------- Read
519
520 TEST_F(SpdyProxyClientSocketTest, ReadReadsDataInDataFrame) {
521 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
522 MockWrite writes[] = {
523 CreateMockWrite(*conn, 1),
524 };
525
526 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
527 scoped_ptr<spdy::SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
528 scoped_ptr<spdy::SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
529 MockRead reads[] = {
530 CreateMockRead(*resp, 2),
531 CreateMockRead(*msg1, 3),
532 CreateMockRead(*msg2, 4),
533 MockRead(true, 0, 6), // EOF
534 };
535
536 Initialize(reads, arraysize(reads), writes, arraysize(writes));
537
538 AssertConnectSucceeds();
539
540 AssertSyncReadEquals(kMsg1, kLen1);
541 AssertSyncReadEquals(kMsg2, kLen2);
542 }
543
544 TEST_F(SpdyProxyClientSocketTest, ReadAuthResponseBody) {
545 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
546 MockWrite writes[] = {
547 CreateMockWrite(*conn, 1),
548 };
549
550 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectAuthReplyFrame());
551 scoped_ptr<spdy::SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
552 scoped_ptr<spdy::SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
553 MockRead reads[] = {
554 CreateMockRead(*resp, 2),
555 CreateMockRead(*msg1, 3),
556 CreateMockRead(*msg2, 4),
557 MockRead(true, 0, 6), // EOF
558 };
559
560 Initialize(reads, arraysize(reads), writes, arraysize(writes));
561
562 EXPECT_EQ(ERR_IO_PENDING, sock_->Connect(&callback_));
563 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, callback_.WaitForResult());
564 // EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, callback_.WaitForResult());
565
566 AssertSyncReadEquals(kMsg1, kLen1);
567 AssertSyncReadEquals(kMsg2, kLen2);
568 }
569
570 TEST_F(SpdyProxyClientSocketTest, ReadErrorResponseBody) {
571 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
572 MockWrite writes[] = {
573 CreateMockWrite(*conn, 1),
574 };
575
576 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectErrorReplyFrame());
577 scoped_ptr<spdy::SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
578 scoped_ptr<spdy::SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
579 MockRead reads[] = {
580 CreateMockRead(*resp, 2),
581 CreateMockRead(*msg1, 3),
582 CreateMockRead(*msg2, 4),
583 MockRead(true, 0, 6), // EOF
584 };
585
586 Initialize(reads, arraysize(reads), writes, arraysize(writes));
587
588 EXPECT_EQ(ERR_IO_PENDING, sock_->Connect(&callback_));
589 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, callback_.WaitForResult());
590
591 AssertSyncReadEquals(kMsg1, kLen1);
592 AssertSyncReadEquals(kMsg2, kLen2);
593 }
594
595 // ----------- Reads and Writes
596
597 TEST_F(SpdyProxyClientSocketTest, AsyncReadAroundWrite) {
598 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
599 scoped_ptr<spdy::SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
600 MockWrite writes[] = {
601 CreateMockWrite(*conn, 1),
602 CreateMockWrite(*msg2, 4), // write to un-cork the read
603 };
604
605 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
606 scoped_ptr<spdy::SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
607 scoped_ptr<spdy::SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
608 MockRead reads[] = {
609 CreateMockRead(*resp, 2),
610 CreateMockRead(*msg1, 3), // sync read
611 CreateMockRead(*msg3, 5, true), // async read
612 MockRead(true, 0, 9), // EOF
613 };
614
615 Initialize(reads, arraysize(reads), writes, arraysize(writes));
616
617 AssertConnectSucceeds();
618
619 AssertSyncReadEquals(kMsg1, kLen1);
620
621 AssertAsyncReadEquals(kMsg3, kLen3);
622 }
623
624 TEST_F(SpdyProxyClientSocketTest, AsyncWriteAroundRead) {
625 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
626 scoped_ptr<spdy::SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
627 MockWrite writes[] = {
628 CreateMockWrite(*conn, 1),
629 CreateMockWrite(*msg1, 4),
630 };
631
632 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
633 scoped_ptr<spdy::SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
634 MockRead reads[] = {
635 CreateMockRead(*resp, 2),
636 CreateMockRead(*msg2, 3), // sync read (which will un-cork the write)
637 MockRead(true, 0, 5), // EOF
638 };
639
640 Initialize(reads, arraysize(reads), writes, arraysize(writes));
641
642 AssertConnectSucceeds();
643
644 AssertAsyncWriteWithReadsSucceeds(kMsg1, kLen1, 1);
645 }
646
647 TEST_F(SpdyProxyClientSocketTest, Mixed) {
648 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
649 scoped_ptr<spdy::SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
650 MockWrite writes[] = {
651 CreateMockWrite(*conn, 1),
652 CreateMockWrite(*msg2, 4), // write to un-cork the read
653 };
654
655 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
656 scoped_ptr<spdy::SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
657 scoped_ptr<spdy::SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
658 MockRead reads[] = {
659 CreateMockRead(*resp, 2),
660 CreateMockRead(*msg1, 3), // sync read
661 CreateMockRead(*msg3, 5, true), // async read
662 MockRead(true, 0, 9), // EOF
663 };
664
665 Initialize(reads, arraysize(reads), writes, arraysize(writes));
666
667 AssertConnectSucceeds();
668
669 AssertSyncReadEquals(kMsg1, kLen1);
670 AssertAsyncReadEquals(kMsg3, kLen3);
671 }
672
673 TEST_F(SpdyProxyClientSocketTest, MultipleShortReads) {
674 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
675 MockWrite writes[] = {
676 CreateMockWrite(*conn, 1),
677 };
678
679 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
680 scoped_ptr<spdy::SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
681 scoped_ptr<spdy::SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
682 MockRead reads[] = {
683 CreateMockRead(*resp, 2),
684 CreateMockRead(*msg1, 3), // sync read
685 CreateMockRead(*msg3, 4), // sync read
686 CreateMockRead(*msg3, 5), // sync read
687 MockRead(true, 0, 8), // EOF
688 };
689
690 Initialize(reads, arraysize(reads), writes, arraysize(writes));
691
692 AssertConnectSucceeds();
693
694 AssertSyncReadEquals(kMsg1, kLen1);
695 // The payload from two data frames, each with kMsg3 will be combined
696 // together into a single read().
697 AssertSyncReadEquals(kMsg33, kLen33);
698 }
699
700 TEST_F(SpdyProxyClientSocketTest, MultipleShortReadsThenMoreRead) {
701 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
702 MockWrite writes[] = {
703 CreateMockWrite(*conn, 1),
704 };
705
706 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
707 scoped_ptr<spdy::SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
708 scoped_ptr<spdy::SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
709 scoped_ptr<spdy::SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
710 MockRead reads[] = {
711 CreateMockRead(*resp, 2),
712 CreateMockRead(*msg1, 3), // sync read
713 CreateMockRead(*msg3, 4), // sync read
714 CreateMockRead(*msg3, 5), // sync read
715 CreateMockRead(*msg2, 5), // sync read
716 MockRead(true, 0, 8), // EOF
717 };
718
719 Initialize(reads, arraysize(reads), writes, arraysize(writes));
720
721 AssertConnectSucceeds();
722
723 AssertSyncReadEquals(kMsg1, kLen1);
724 // The payload from two data frames, each with kMsg3 will be combined
725 // together into a single read().
726 AssertSyncReadEquals(kMsg33, kLen33);
727 AssertSyncReadEquals(kMsg2, kLen2);
728 }
729
730
731 TEST_F(SpdyProxyClientSocketTest, LargeSplitRead) {
732 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
733 MockWrite writes[] = {
734 CreateMockWrite(*conn, 1),
735 };
736
737 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
738 scoped_ptr<spdy::SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
739 scoped_ptr<spdy::SpdyFrame> msg33(ConstructBodyFrame(kMsg33, kLen33));
740 scoped_ptr<spdy::SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
741 MockRead reads[] = {
742 CreateMockRead(*resp, 2),
743 CreateMockRead(*msg1, 3),
744 CreateMockRead(*msg33, 4),
745 MockRead(true, 0, 8), // EOF
746 };
747
748 Initialize(reads, arraysize(reads), writes, arraysize(writes));
749
750 AssertConnectSucceeds();
751
752 AssertSyncReadEquals(kMsg1, kLen1);
753 // The payload from the single large data frame will be read across
754 // two different reads.
755 AssertSyncReadEquals(kMsg3, kLen3);
756 AssertSyncReadEquals(kMsg3, kLen3);
757 }
758
759 TEST_F(SpdyProxyClientSocketTest, WriteLargeDataSplits) {
760 std::string chunk_data(kMaxSpdyFrameChunkSize, 'x');
761 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
762 scoped_ptr<spdy::SpdyFrame> chunk(ConstructBodyFrame(chunk_data.data(),
763 chunk_data.length()));
764 MockWrite writes[] = {
765 CreateMockWrite(*conn, 1),
766 CreateMockWrite(*chunk, 3, false),
767 CreateMockWrite(*chunk, 4, false),
768 CreateMockWrite(*chunk, 5, false)
769 };
770
771 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
772 MockRead reads[] = {
773 CreateMockRead(*resp, 2),
774 MockRead(true, 0, 7), // EOF
775 };
776
777 Initialize(reads, arraysize(reads), writes, arraysize(writes));
778
779 AssertConnectSucceeds();
780
781 std::string big_data(kMaxSpdyFrameChunkSize * 3, 'x');
782 AssertAsyncWriteSucceeds(big_data.data(), big_data.length());
783 }
784
785 // ----------- Reading/Writing on Closed socket
786
787 // Reading from an already closed socket should return 0
788 TEST_F(SpdyProxyClientSocketTest, ReadOnClosedSocketReturnsZero) {
789 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
790 MockWrite writes[] = {
791 CreateMockWrite(*conn, 1),
792 };
793
794 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
795 MockRead reads[] = {
796 CreateMockRead(*resp, 2),
797 MockRead(true, 0, 4), // EOF
798 };
799
800 Initialize(reads, arraysize(reads), writes, arraysize(writes));
801
802 AssertConnectSucceeds();
803
804 sock_->Disconnect();
805
806 ASSERT_EQ(0, sock_->Read(NULL, 1, NULL));
807 ASSERT_EQ(ERR_CONNECTION_CLOSED, sock_->Read(NULL, 1, NULL));
808 ASSERT_EQ(ERR_CONNECTION_CLOSED, sock_->Read(NULL, 1, NULL));
809 }
810
811 // Calling Write() on a closed socket is an error
812 TEST_F(SpdyProxyClientSocketTest, WriteOnClosedStream) {
813 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
814 MockWrite writes[] = {
815 CreateMockWrite(*conn, 1),
816 };
817
818 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
819 scoped_ptr<spdy::SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
820 MockRead reads[] = {
821 CreateMockRead(*resp, 2),
822 MockRead(false, 0, 3), // EOF
823 };
824
825 Initialize(reads, arraysize(reads), writes, arraysize(writes));
826
827 AssertConnectSucceeds();
828
829 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
830 EXPECT_EQ(ERR_CONNECTION_CLOSED, sock_->Write(buf, buf->size(), NULL));
831 }
832
833 // ----------- Pending read/write when closed
834
835 // If the socket is closed with a pending Write(), the callback
836 // should not be called.
837 TEST_F(SpdyProxyClientSocketTest, DisconnectWithWritePending) {
838 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
839 MockWrite writes[] = {
840 CreateMockWrite(*conn, 1),
841 MockWrite(true, 0, 3), // EOF
842 };
843
844 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
845 MockRead reads[] = {
846 CreateMockRead(*resp, 2),
847 MockRead(false, 0, 4), // EOF
848 };
849
850 Initialize(reads, arraysize(reads), writes, arraysize(writes));
851
852 AssertConnectSucceeds();
853
854 EXPECT_TRUE(sock_->IsConnected());
855
856 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
857 EXPECT_EQ(ERR_IO_PENDING, sock_->Write(buf, buf->size(), &callback_));
858
859 sock_->Disconnect();
860
861 EXPECT_FALSE(sock_->IsConnected());
862 EXPECT_FALSE(callback_.have_result());
863 }
864
865 // If the socket is closed with a pending Read(), the callback
866 // should not be called.
867 TEST_F(SpdyProxyClientSocketTest, DisconnectWithReadPending) {
868 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
869 MockWrite writes[] = {
870 CreateMockWrite(*conn, 1),
871 };
872
873 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
874 MockRead reads[] = {
875 CreateMockRead(*resp, 2),
876 MockRead(true, 0, 4), // EOF
877 };
878
879 Initialize(reads, arraysize(reads), writes, arraysize(writes));
880
881 AssertConnectSucceeds();
882
883 EXPECT_TRUE(sock_->IsConnected());
884
885 scoped_refptr<IOBuffer> buf(new IOBuffer(kLen1));
886 ASSERT_EQ(ERR_IO_PENDING, sock_->Read(buf, kLen1, &callback_));
887
888 sock_->Disconnect();
889
890 EXPECT_FALSE(sock_->IsConnected());
891 EXPECT_FALSE(callback_.have_result());
892 }
893
894 } // namespace net
OLDNEW
« no previous file with comments | « net/spdy/spdy_proxy_client_socket.cc ('k') | net/spdy/spdy_session.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698