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

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

Issue 9582034: Fork SPDY/2 and SPDY/3 versions of our SPDY tests, in preparation for landing (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Fix merge bug Created 8 years, 9 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_spdy3_unittest.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) 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/spdy/spdy_proxy_client_socket.h"
6
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/utf_string_conversions.h"
10 #include "net/base/address_list.h"
11 #include "net/base/net_log.h"
12 #include "net/base/net_log_unittest.h"
13 #include "net/base/mock_host_resolver.h"
14 #include "net/base/test_completion_callback.h"
15 #include "net/base/winsock_init.h"
16 #include "net/http/http_response_info.h"
17 #include "net/http/http_response_headers.h"
18 #include "net/socket/client_socket_factory.h"
19 #include "net/socket/tcp_client_socket.h"
20 #include "net/socket/socket_test_util.h"
21 #include "net/spdy/spdy_http_utils.h"
22 #include "net/spdy/spdy_protocol.h"
23 #include "net/spdy/spdy_session_pool.h"
24 #include "net/spdy/spdy_test_util.h"
25 #include "testing/platform_test.h"
26 #include "testing/gtest/include/gtest/gtest.h"
27
28 //-----------------------------------------------------------------------------
29
30 namespace {
31
32 static const char kUrl[] = "https://www.google.com/";
33 static const char kOriginHost[] = "www.google.com";
34 static const int kOriginPort = 443;
35 static const char kOriginHostPort[] = "www.google.com:443";
36 static const char kProxyUrl[] = "https://myproxy:6121/";
37 static const char kProxyHost[] = "myproxy";
38 static const int kProxyPort = 6121;
39 static const char kUserAgent[] = "Mozilla/1.0";
40
41 static const int kStreamId = 1;
42
43 static const char kMsg1[] = "\0hello!\xff";
44 static const int kLen1 = 8;
45 static const char kMsg2[] = "\00012345678\0";
46 static const int kLen2 = 10;
47 static const char kMsg3[] = "bye!";
48 static const int kLen3 = 4;
49 static const char kMsg33[] = "bye!bye!";
50 static const int kLen33 = kLen3 + kLen3;
51 static const char kMsg333[] = "bye!bye!bye!";
52 static const int kLen333 = kLen3 + kLen3 + kLen3;
53
54 } // anonymous namespace
55
56 namespace net {
57
58 class SpdyProxyClientSocketTest : public PlatformTest {
59 public:
60 SpdyProxyClientSocketTest();
61
62 virtual void TearDown();
63
64 protected:
65 void Initialize(MockRead* reads, size_t reads_count, MockWrite* writes,
66 size_t writes_count);
67 spdy::SpdyFrame* ConstructConnectRequestFrame();
68 spdy::SpdyFrame* ConstructConnectAuthRequestFrame();
69 spdy::SpdyFrame* ConstructConnectReplyFrame();
70 spdy::SpdyFrame* ConstructConnectAuthReplyFrame();
71 spdy::SpdyFrame* ConstructConnectErrorReplyFrame();
72 spdy::SpdyFrame* ConstructBodyFrame(const char* data, int length);
73 scoped_refptr<IOBufferWithSize> CreateBuffer(const char* data, int size);
74 void AssertConnectSucceeds();
75 void AssertConnectFails(int result);
76 void AssertConnectionEstablished();
77 void AssertSyncReadEquals(const char* data, int len);
78 void AssertAsyncReadEquals(const char* data, int len);
79 void AssertReadStarts(const char* data, int len);
80 void AssertReadReturns(const char* data, int len);
81 void AssertAsyncWriteSucceeds(const char* data, int len);
82 void AssertWriteReturns(const char* data, int len, int rv);
83 void AssertWriteLength(int len);
84 void AssertAsyncWriteWithReadsSucceeds(const char* data, int len,
85 int num_reads);
86
87 void AddAuthToCache() {
88 const string16 kFoo(ASCIIToUTF16("foo"));
89 const string16 kBar(ASCIIToUTF16("bar"));
90 session_->http_auth_cache()->Add(GURL(kProxyUrl),
91 "MyRealm1",
92 HttpAuth::AUTH_SCHEME_BASIC,
93 "Basic realm=MyRealm1",
94 AuthCredentials(kFoo, kBar),
95 "/");
96 }
97
98 void Run(int steps) {
99 data_->StopAfter(steps);
100 data_->Run();
101 }
102
103 scoped_ptr<SpdyProxyClientSocket> sock_;
104 TestCompletionCallback read_callback_;
105 TestCompletionCallback write_callback_;
106 scoped_refptr<DeterministicSocketData> data_;
107
108 private:
109 scoped_refptr<HttpNetworkSession> session_;
110 scoped_refptr<IOBuffer> read_buf_;
111 SpdySessionDependencies session_deps_;
112 MockConnect connect_data_;
113 scoped_refptr<SpdySession> spdy_session_;
114 scoped_refptr<SpdyStream> spdy_stream_;
115 spdy::SpdyFramer framer_;
116
117 std::string user_agent_;
118 GURL url_;
119 HostPortPair proxy_host_port_;
120 HostPortPair endpoint_host_port_pair_;
121 ProxyServer proxy_;
122 HostPortProxyPair endpoint_host_port_proxy_pair_;
123 scoped_refptr<TransportSocketParams> transport_params_;
124
125 DISALLOW_COPY_AND_ASSIGN(SpdyProxyClientSocketTest);
126 };
127
128 SpdyProxyClientSocketTest::SpdyProxyClientSocketTest()
129 : sock_(NULL),
130 data_(NULL),
131 session_(NULL),
132 read_buf_(NULL),
133 session_deps_(),
134 connect_data_(SYNCHRONOUS, OK),
135 spdy_session_(NULL),
136 spdy_stream_(NULL),
137 framer_(),
138 user_agent_(kUserAgent),
139 url_(kUrl),
140 proxy_host_port_(kProxyHost, kProxyPort),
141 endpoint_host_port_pair_(kOriginHost, kOriginPort),
142 proxy_(ProxyServer::SCHEME_HTTPS, proxy_host_port_),
143 endpoint_host_port_proxy_pair_(endpoint_host_port_pair_, proxy_),
144 transport_params_(new TransportSocketParams(proxy_host_port_,
145 LOWEST,
146 false,
147 false)) {
148 }
149
150 void SpdyProxyClientSocketTest::TearDown() {
151 sock_.reset(NULL);
152 if (session_ != NULL)
153 session_->spdy_session_pool()->CloseAllSessions();
154
155 spdy::SpdyFramer::set_enable_compression_default(true);
156 // Empty the current queue.
157 MessageLoop::current()->RunAllPending();
158 PlatformTest::TearDown();
159 }
160
161 void SpdyProxyClientSocketTest::Initialize(MockRead* reads,
162 size_t reads_count,
163 MockWrite* writes,
164 size_t writes_count) {
165 data_ = new DeterministicSocketData(reads, reads_count, writes, writes_count);
166 data_->set_connect_data(connect_data_);
167 data_->SetStop(2);
168
169 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
170 data_.get());
171 session_deps_.host_resolver->set_synchronous_mode(true);
172
173 session_ = SpdySessionDependencies::SpdyCreateSessionDeterministic(
174 &session_deps_);
175 SpdySession::SetSSLMode(false);
176 spdy::SpdyFramer::set_enable_compression_default(false);
177
178 // Creates a new spdy session
179 spdy_session_ =
180 session_->spdy_session_pool()->Get(endpoint_host_port_proxy_pair_,
181 BoundNetLog());
182
183 // Perform the TCP connect
184 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
185 EXPECT_EQ(OK,
186 connection->Init(endpoint_host_port_pair_.ToString(),
187 transport_params_, LOWEST, CompletionCallback(),
188 session_->GetTransportSocketPool(),
189 BoundNetLog()));
190 spdy_session_->InitializeWithSocket(connection.release(), false, OK);
191
192 // Create the SPDY Stream
193 ASSERT_EQ(
194 OK,
195 spdy_session_->CreateStream(url_, LOWEST, &spdy_stream_, BoundNetLog(),
196 CompletionCallback()));
197
198 // Create the SpdyProxyClientSocket
199 sock_.reset(
200 new SpdyProxyClientSocket(spdy_stream_, user_agent_,
201 endpoint_host_port_pair_, url_,
202 proxy_host_port_, session_->http_auth_cache(),
203 session_->http_auth_handler_factory()));
204 }
205
206 scoped_refptr<IOBufferWithSize> SpdyProxyClientSocketTest::CreateBuffer(
207 const char* data, int size) {
208 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(size));
209 memcpy(buf->data(), data, size);
210 return buf;
211 }
212
213 void SpdyProxyClientSocketTest::AssertConnectSucceeds() {
214 ASSERT_EQ(ERR_IO_PENDING, sock_->Connect(read_callback_.callback()));
215 data_->Run();
216 ASSERT_EQ(OK, read_callback_.WaitForResult());
217 }
218
219 void SpdyProxyClientSocketTest::AssertConnectFails(int result) {
220 ASSERT_EQ(ERR_IO_PENDING, sock_->Connect(read_callback_.callback()));
221 data_->Run();
222 ASSERT_EQ(result, read_callback_.WaitForResult());
223 }
224
225 void SpdyProxyClientSocketTest::AssertConnectionEstablished() {
226 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
227 ASSERT_TRUE(response != NULL);
228 ASSERT_EQ(200, response->headers->response_code());
229 ASSERT_EQ("Connection Established", response->headers->GetStatusText());
230 }
231
232 void SpdyProxyClientSocketTest::AssertSyncReadEquals(const char* data,
233 int len) {
234 scoped_refptr<IOBuffer> buf(new IOBuffer(len));
235 ASSERT_EQ(len, sock_->Read(buf, len, CompletionCallback()));
236 ASSERT_EQ(std::string(data, len), std::string(buf->data(), len));
237 ASSERT_TRUE(sock_->IsConnected());
238 }
239
240 void SpdyProxyClientSocketTest::AssertAsyncReadEquals(const char* data,
241 int len) {
242 data_->StopAfter(1);
243 // Issue the read, which will be completed asynchronously
244 scoped_refptr<IOBuffer> buf(new IOBuffer(len));
245 ASSERT_EQ(ERR_IO_PENDING, sock_->Read(buf, len, read_callback_.callback()));
246 EXPECT_TRUE(sock_->IsConnected());
247 data_->Run();
248
249 EXPECT_TRUE(sock_->IsConnected());
250
251 // Now the read will return
252 EXPECT_EQ(len, read_callback_.WaitForResult());
253 ASSERT_EQ(std::string(data, len), std::string(buf->data(), len));
254 }
255
256 void SpdyProxyClientSocketTest::AssertReadStarts(const char* data, int len) {
257 data_->StopAfter(1);
258 // Issue the read, which will be completed asynchronously
259 read_buf_ = new IOBuffer(len);
260 ASSERT_EQ(ERR_IO_PENDING,
261 sock_->Read(read_buf_, len, read_callback_.callback()));
262 EXPECT_TRUE(sock_->IsConnected());
263 }
264
265 void SpdyProxyClientSocketTest::AssertReadReturns(const char* data, int len) {
266 EXPECT_TRUE(sock_->IsConnected());
267
268 // Now the read will return
269 EXPECT_EQ(len, read_callback_.WaitForResult());
270 ASSERT_EQ(std::string(data, len), std::string(read_buf_->data(), len));
271 }
272
273 void SpdyProxyClientSocketTest::AssertAsyncWriteSucceeds(const char* data,
274 int len) {
275 AssertWriteReturns(data, len, ERR_IO_PENDING);
276 data_->RunFor(1);
277 AssertWriteLength(len);
278 }
279
280 void SpdyProxyClientSocketTest::AssertWriteReturns(const char* data, int len,
281 int rv) {
282 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(data, len));
283 EXPECT_EQ(rv, sock_->Write(buf, buf->size(), write_callback_.callback()));
284 }
285
286 void SpdyProxyClientSocketTest::AssertWriteLength(int len) {
287 EXPECT_EQ(len, write_callback_.WaitForResult());
288 }
289
290 void SpdyProxyClientSocketTest::AssertAsyncWriteWithReadsSucceeds(
291 const char* data, int len, int num_reads) {
292 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(data, len));
293
294 EXPECT_EQ(ERR_IO_PENDING, sock_->Write(buf, buf->size(),
295 write_callback_.callback()));
296
297 for (int i = 0; i < num_reads; i++) {
298 Run(1);
299 AssertSyncReadEquals(kMsg2, kLen2);
300 }
301
302 write_callback_.WaitForResult();
303 }
304
305 // Constructs a standard SPDY SYN_STREAM frame for a CONNECT request.
306 spdy::SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectRequestFrame() {
307 const SpdyHeaderInfo kSynStartHeader = {
308 spdy::SYN_STREAM,
309 kStreamId,
310 0,
311 net::ConvertRequestPriorityToSpdyPriority(LOWEST),
312 spdy::CONTROL_FLAG_NONE,
313 false,
314 spdy::INVALID,
315 NULL,
316 0,
317 spdy::DATA_FLAG_NONE
318 };
319 const char* const kConnectHeaders[] = {
320 "method", "CONNECT",
321 "url", kOriginHostPort,
322 "host", kOriginHost,
323 "user-agent", kUserAgent,
324 "version", "HTTP/1.1",
325 };
326 return ConstructSpdyPacket(
327 kSynStartHeader, NULL, 0, kConnectHeaders, arraysize(kConnectHeaders)/2);
328 }
329
330 // Constructs a SPDY SYN_STREAM frame for a CONNECT request which includes
331 // Proxy-Authorization headers.
332 spdy::SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectAuthRequestFrame() {
333 const SpdyHeaderInfo kSynStartHeader = {
334 spdy::SYN_STREAM,
335 kStreamId,
336 0,
337 net::ConvertRequestPriorityToSpdyPriority(LOWEST),
338 spdy::CONTROL_FLAG_NONE,
339 false,
340 spdy::INVALID,
341 NULL,
342 0,
343 spdy::DATA_FLAG_NONE
344 };
345 const char* const kConnectHeaders[] = {
346 "method", "CONNECT",
347 "url", kOriginHostPort,
348 "host", kOriginHost,
349 "user-agent", kUserAgent,
350 "version", "HTTP/1.1",
351 "proxy-authorization", "Basic Zm9vOmJhcg==",
352 };
353 return ConstructSpdyPacket(
354 kSynStartHeader, NULL, 0, kConnectHeaders, arraysize(kConnectHeaders)/2);
355 }
356
357 // Constructs a standard SPDY SYN_REPLY frame to match the SPDY CONNECT.
358 spdy::SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectReplyFrame() {
359 const char* const kStandardReplyHeaders[] = {
360 "status", "200 Connection Established",
361 "version", "HTTP/1.1"
362 };
363 return ConstructSpdyControlFrame(NULL,
364 0,
365 false,
366 kStreamId,
367 LOWEST,
368 spdy::SYN_REPLY,
369 spdy::CONTROL_FLAG_NONE,
370 kStandardReplyHeaders,
371 arraysize(kStandardReplyHeaders));
372 }
373
374 // Constructs a standard SPDY SYN_REPLY frame to match the SPDY CONNECT.
375 spdy::SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectAuthReplyFrame() {
376 const char* const kStandardReplyHeaders[] = {
377 "status", "407 Proxy Authentication Required",
378 "version", "HTTP/1.1",
379 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
380 };
381
382 return ConstructSpdyControlFrame(NULL,
383 0,
384 false,
385 kStreamId,
386 LOWEST,
387 spdy::SYN_REPLY,
388 spdy::CONTROL_FLAG_NONE,
389 kStandardReplyHeaders,
390 arraysize(kStandardReplyHeaders));
391 }
392
393 // Constructs a SPDY SYN_REPLY frame with an HTTP 500 error.
394 spdy::SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectErrorReplyFrame() {
395 const char* const kStandardReplyHeaders[] = {
396 "status", "500 Internal Server Error",
397 "version", "HTTP/1.1",
398 };
399
400 return ConstructSpdyControlFrame(NULL,
401 0,
402 false,
403 kStreamId,
404 LOWEST,
405 spdy::SYN_REPLY,
406 spdy::CONTROL_FLAG_NONE,
407 kStandardReplyHeaders,
408 arraysize(kStandardReplyHeaders));
409 }
410
411 spdy::SpdyFrame* SpdyProxyClientSocketTest::ConstructBodyFrame(const char* data,
412 int length) {
413 return framer_.CreateDataFrame(kStreamId, data, length, spdy::DATA_FLAG_NONE);
414 }
415
416 // ----------- Connect
417
418 TEST_F(SpdyProxyClientSocketTest, ConnectSendsCorrectRequest) {
419 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
420 MockWrite writes[] = {
421 CreateMockWrite(*conn, 0, SYNCHRONOUS),
422 };
423
424 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
425 MockRead reads[] = {
426 CreateMockRead(*resp, 1, ASYNC),
427 MockRead(ASYNC, 0, 3), // EOF
428 };
429
430 Initialize(reads, arraysize(reads), writes, arraysize(writes));
431
432 ASSERT_FALSE(sock_->IsConnected());
433
434 AssertConnectSucceeds();
435
436 AssertConnectionEstablished();
437 }
438
439 TEST_F(SpdyProxyClientSocketTest, ConnectWithAuthRequested) {
440 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
441 MockWrite writes[] = {
442 CreateMockWrite(*conn, 0, SYNCHRONOUS),
443 };
444
445 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectAuthReplyFrame());
446 MockRead reads[] = {
447 CreateMockRead(*resp, 1, ASYNC),
448 MockRead(ASYNC, 0, 3), // EOF
449 };
450
451 Initialize(reads, arraysize(reads), writes, arraysize(writes));
452
453 AssertConnectFails(ERR_PROXY_AUTH_REQUESTED);
454
455 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
456 ASSERT_TRUE(response != NULL);
457 ASSERT_EQ(407, response->headers->response_code());
458 ASSERT_EQ("Proxy Authentication Required",
459 response->headers->GetStatusText());
460 }
461
462 TEST_F(SpdyProxyClientSocketTest, ConnectWithAuthCredentials) {
463 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectAuthRequestFrame());
464 MockWrite writes[] = {
465 CreateMockWrite(*conn, 0, SYNCHRONOUS),
466 };
467
468 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
469 MockRead reads[] = {
470 CreateMockRead(*resp, 1, ASYNC),
471 MockRead(ASYNC, 0, 3), // EOF
472 };
473
474 Initialize(reads, arraysize(reads), writes, arraysize(writes));
475 AddAuthToCache();
476
477 AssertConnectSucceeds();
478
479 AssertConnectionEstablished();
480 }
481
482 TEST_F(SpdyProxyClientSocketTest, ConnectFails) {
483 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
484 MockWrite writes[] = {
485 CreateMockWrite(*conn, 0, SYNCHRONOUS),
486 };
487
488 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
489 MockRead reads[] = {
490 MockRead(ASYNC, 0, 1), // EOF
491 };
492
493 Initialize(reads, arraysize(reads), writes, arraysize(writes));
494
495 ASSERT_FALSE(sock_->IsConnected());
496
497 AssertConnectFails(ERR_CONNECTION_CLOSED);
498
499 ASSERT_FALSE(sock_->IsConnected());
500 }
501
502 // ----------- WasEverUsed
503
504 TEST_F(SpdyProxyClientSocketTest, WasEverUsedReturnsCorrectValues) {
505 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
506 MockWrite writes[] = {
507 CreateMockWrite(*conn, 0, SYNCHRONOUS),
508 };
509
510 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
511 MockRead reads[] = {
512 CreateMockRead(*resp, 1, ASYNC),
513 MockRead(ASYNC, 0, 2), // EOF
514 };
515
516 Initialize(reads, arraysize(reads), writes, arraysize(writes));
517
518 EXPECT_FALSE(sock_->WasEverUsed());
519 AssertConnectSucceeds();
520 EXPECT_TRUE(sock_->WasEverUsed());
521 sock_->Disconnect();
522 EXPECT_TRUE(sock_->WasEverUsed());
523 }
524
525 // ----------- GetPeerAddress
526
527 TEST_F(SpdyProxyClientSocketTest, GetPeerAddressReturnsCorrectValues) {
528 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
529 MockWrite writes[] = {
530 CreateMockWrite(*conn, 0, SYNCHRONOUS),
531 };
532
533 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
534 MockRead reads[] = {
535 CreateMockRead(*resp, 1, ASYNC),
536 MockRead(ASYNC, 0, 2), // EOF
537 };
538
539 Initialize(reads, arraysize(reads), writes, arraysize(writes));
540
541 net::AddressList addr;
542 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr));
543
544 AssertConnectSucceeds();
545 EXPECT_TRUE(sock_->IsConnected());
546 EXPECT_EQ(OK, sock_->GetPeerAddress(&addr));
547
548 Run(1);
549
550 EXPECT_FALSE(sock_->IsConnected());
551 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr));
552
553 sock_->Disconnect();
554
555 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr));
556 }
557
558 // ----------- Write
559
560 TEST_F(SpdyProxyClientSocketTest, WriteSendsDataInDataFrame) {
561 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
562 scoped_ptr<spdy::SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
563 scoped_ptr<spdy::SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
564 MockWrite writes[] = {
565 CreateMockWrite(*conn, 0, SYNCHRONOUS),
566 CreateMockWrite(*msg1, 2, SYNCHRONOUS),
567 CreateMockWrite(*msg2, 3, SYNCHRONOUS),
568 };
569
570 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
571 MockRead reads[] = {
572 CreateMockRead(*resp, 1, ASYNC),
573 MockRead(ASYNC, 0, 4), // EOF
574 };
575
576 Initialize(reads, arraysize(reads), writes, arraysize(writes));
577
578 AssertConnectSucceeds();
579
580 AssertAsyncWriteSucceeds(kMsg1, kLen1);
581 AssertAsyncWriteSucceeds(kMsg2, kLen2);
582 }
583
584 TEST_F(SpdyProxyClientSocketTest, WriteSplitsLargeDataIntoMultipleFrames) {
585 std::string chunk_data(kMaxSpdyFrameChunkSize, 'x');
586 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
587 scoped_ptr<spdy::SpdyFrame> chunk(ConstructBodyFrame(chunk_data.data(),
588 chunk_data.length()));
589 MockWrite writes[] = {
590 CreateMockWrite(*conn, 0, SYNCHRONOUS),
591 CreateMockWrite(*chunk, 2, SYNCHRONOUS),
592 CreateMockWrite(*chunk, 3, SYNCHRONOUS),
593 CreateMockWrite(*chunk, 4, SYNCHRONOUS)
594 };
595
596 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
597 MockRead reads[] = {
598 CreateMockRead(*resp, 1, ASYNC),
599 MockRead(ASYNC, 0, 5), // EOF
600 };
601
602 Initialize(reads, arraysize(reads), writes, arraysize(writes));
603
604 AssertConnectSucceeds();
605
606 std::string big_data(kMaxSpdyFrameChunkSize * 3, 'x');
607 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(big_data.data(),
608 big_data.length()));
609
610 EXPECT_EQ(ERR_IO_PENDING, sock_->Write(buf, buf->size(),
611 write_callback_.callback()));
612 data_->RunFor(3);
613
614 EXPECT_EQ(buf->size(), write_callback_.WaitForResult());
615 }
616
617 // ----------- Read
618
619 TEST_F(SpdyProxyClientSocketTest, ReadReadsDataInDataFrame) {
620 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
621 MockWrite writes[] = {
622 CreateMockWrite(*conn, 0, SYNCHRONOUS),
623 };
624
625 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
626 scoped_ptr<spdy::SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
627 MockRead reads[] = {
628 CreateMockRead(*resp, 1, ASYNC),
629 CreateMockRead(*msg1, 2, ASYNC),
630 MockRead(ASYNC, 0, 3), // EOF
631 };
632
633 Initialize(reads, arraysize(reads), writes, arraysize(writes));
634
635 AssertConnectSucceeds();
636
637 Run(1); // SpdySession consumes the next read and sends it to
638 // sock_ to be buffered.
639 AssertSyncReadEquals(kMsg1, kLen1);
640 }
641
642 TEST_F(SpdyProxyClientSocketTest, ReadDataFromBufferedFrames) {
643 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
644 MockWrite writes[] = {
645 CreateMockWrite(*conn, 0, SYNCHRONOUS),
646 };
647
648 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
649 scoped_ptr<spdy::SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
650 scoped_ptr<spdy::SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
651 MockRead reads[] = {
652 CreateMockRead(*resp, 1, ASYNC),
653 CreateMockRead(*msg1, 2, ASYNC),
654 CreateMockRead(*msg2, 3, ASYNC),
655 MockRead(ASYNC, 0, 4), // EOF
656 };
657
658 Initialize(reads, arraysize(reads), writes, arraysize(writes));
659
660 AssertConnectSucceeds();
661
662 Run(1); // SpdySession consumes the next read and sends it to
663 // sock_ to be buffered.
664 AssertSyncReadEquals(kMsg1, kLen1);
665 Run(1); // SpdySession consumes the next read and sends it to
666 // sock_ to be buffered.
667 AssertSyncReadEquals(kMsg2, kLen2);
668 }
669
670 TEST_F(SpdyProxyClientSocketTest, ReadDataMultipleBufferedFrames) {
671 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
672 MockWrite writes[] = {
673 CreateMockWrite(*conn, 0, SYNCHRONOUS),
674 };
675
676 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
677 scoped_ptr<spdy::SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
678 scoped_ptr<spdy::SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
679 MockRead reads[] = {
680 CreateMockRead(*resp, 1, ASYNC),
681 CreateMockRead(*msg1, 2, ASYNC),
682 CreateMockRead(*msg2, 3, ASYNC),
683 MockRead(ASYNC, 0, 4), // EOF
684 };
685
686 Initialize(reads, arraysize(reads), writes, arraysize(writes));
687
688 AssertConnectSucceeds();
689
690 Run(2); // SpdySession consumes the next two reads and sends then to
691 // sock_ to be buffered.
692 AssertSyncReadEquals(kMsg1, kLen1);
693 AssertSyncReadEquals(kMsg2, kLen2);
694 }
695
696 TEST_F(SpdyProxyClientSocketTest, LargeReadWillMergeDataFromDifferentFrames) {
697 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
698 MockWrite writes[] = {
699 CreateMockWrite(*conn, 0, SYNCHRONOUS),
700 };
701
702 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
703 scoped_ptr<spdy::SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
704 scoped_ptr<spdy::SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
705 MockRead reads[] = {
706 CreateMockRead(*resp, 1, ASYNC),
707 CreateMockRead(*msg3, 2, ASYNC),
708 CreateMockRead(*msg3, 3, ASYNC),
709 MockRead(ASYNC, 0, 4), // EOF
710 };
711
712 Initialize(reads, arraysize(reads), writes, arraysize(writes));
713
714 AssertConnectSucceeds();
715
716 Run(2); // SpdySession consumes the next two reads and sends then to
717 // sock_ to be buffered.
718 // The payload from two data frames, each with kMsg3 will be combined
719 // together into a single read().
720 AssertSyncReadEquals(kMsg33, kLen33);
721 }
722
723 TEST_F(SpdyProxyClientSocketTest, MultipleShortReadsThenMoreRead) {
724 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
725 MockWrite writes[] = {
726 CreateMockWrite(*conn, 0, SYNCHRONOUS),
727 };
728
729 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
730 scoped_ptr<spdy::SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
731 scoped_ptr<spdy::SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
732 scoped_ptr<spdy::SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
733 MockRead reads[] = {
734 CreateMockRead(*resp, 1, ASYNC),
735 CreateMockRead(*msg1, 2, ASYNC),
736 CreateMockRead(*msg3, 3, ASYNC),
737 CreateMockRead(*msg3, 4, ASYNC),
738 CreateMockRead(*msg2, 5, ASYNC),
739 MockRead(ASYNC, 0, 6), // EOF
740 };
741
742 Initialize(reads, arraysize(reads), writes, arraysize(writes));
743
744 AssertConnectSucceeds();
745
746 Run(4); // SpdySession consumes the next four reads and sends then to
747 // sock_ to be buffered.
748 AssertSyncReadEquals(kMsg1, kLen1);
749 // The payload from two data frames, each with kMsg3 will be combined
750 // together into a single read().
751 AssertSyncReadEquals(kMsg33, kLen33);
752 AssertSyncReadEquals(kMsg2, kLen2);
753 }
754
755 TEST_F(SpdyProxyClientSocketTest, ReadWillSplitDataFromLargeFrame) {
756 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
757 MockWrite writes[] = {
758 CreateMockWrite(*conn, 0, SYNCHRONOUS),
759 };
760
761 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
762 scoped_ptr<spdy::SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
763 scoped_ptr<spdy::SpdyFrame> msg33(ConstructBodyFrame(kMsg33, kLen33));
764 scoped_ptr<spdy::SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
765 MockRead reads[] = {
766 CreateMockRead(*resp, 1, ASYNC),
767 CreateMockRead(*msg1, 2, ASYNC),
768 CreateMockRead(*msg33, 3, ASYNC),
769 MockRead(ASYNC, 0, 4), // EOF
770 };
771
772 Initialize(reads, arraysize(reads), writes, arraysize(writes));
773
774 AssertConnectSucceeds();
775
776 Run(2); // SpdySession consumes the next two reads and sends then to
777 // sock_ to be buffered.
778 AssertSyncReadEquals(kMsg1, kLen1);
779 // The payload from the single large data frame will be read across
780 // two different reads.
781 AssertSyncReadEquals(kMsg3, kLen3);
782 AssertSyncReadEquals(kMsg3, kLen3);
783 }
784
785 TEST_F(SpdyProxyClientSocketTest, MultipleReadsFromSameLargeFrame) {
786 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
787 MockWrite writes[] = {
788 CreateMockWrite(*conn, 0, SYNCHRONOUS),
789 };
790
791 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
792 scoped_ptr<spdy::SpdyFrame> msg333(ConstructBodyFrame(kMsg333, kLen333));
793 MockRead reads[] = {
794 CreateMockRead(*resp, 1, ASYNC),
795 CreateMockRead(*msg333, 2, ASYNC),
796 MockRead(ASYNC, 0, 3), // EOF
797 };
798
799 Initialize(reads, arraysize(reads), writes, arraysize(writes));
800
801 AssertConnectSucceeds();
802
803 Run(1); // SpdySession consumes the next read and sends it to
804 // sock_ to be buffered.
805 // The payload from the single large data frame will be read across
806 // two different reads.
807 AssertSyncReadEquals(kMsg33, kLen33);
808
809 // Now attempt to do a read of more data than remains buffered
810 scoped_refptr<IOBuffer> buf(new IOBuffer(kLen33));
811 ASSERT_EQ(kLen3, sock_->Read(buf, kLen33, read_callback_.callback()));
812 ASSERT_EQ(std::string(kMsg3, kLen3), std::string(buf->data(), kLen3));
813 ASSERT_TRUE(sock_->IsConnected());
814 }
815
816 TEST_F(SpdyProxyClientSocketTest, ReadAuthResponseBody) {
817 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
818 MockWrite writes[] = {
819 CreateMockWrite(*conn, 0, SYNCHRONOUS),
820 };
821
822 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectAuthReplyFrame());
823 scoped_ptr<spdy::SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
824 scoped_ptr<spdy::SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
825 MockRead reads[] = {
826 CreateMockRead(*resp, 1, ASYNC),
827 CreateMockRead(*msg1, 2, ASYNC),
828 CreateMockRead(*msg2, 3, ASYNC),
829 MockRead(ASYNC, 0, 4), // EOF
830 };
831
832 Initialize(reads, arraysize(reads), writes, arraysize(writes));
833
834 AssertConnectFails(ERR_PROXY_AUTH_REQUESTED);
835
836 Run(2); // SpdySession consumes the next two reads and sends then to
837 // sock_ to be buffered.
838 AssertSyncReadEquals(kMsg1, kLen1);
839 AssertSyncReadEquals(kMsg2, kLen2);
840 }
841
842 TEST_F(SpdyProxyClientSocketTest, ReadErrorResponseBody) {
843 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
844 MockWrite writes[] = {
845 CreateMockWrite(*conn, 0, SYNCHRONOUS),
846 };
847
848 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectErrorReplyFrame());
849 scoped_ptr<spdy::SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
850 scoped_ptr<spdy::SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
851 MockRead reads[] = {
852 CreateMockRead(*resp, 1, ASYNC),
853 CreateMockRead(*msg1, 2, ASYNC),
854 CreateMockRead(*msg2, 3, ASYNC),
855 MockRead(ASYNC, 0, 4), // EOF
856 };
857
858 Initialize(reads, arraysize(reads), writes, arraysize(writes));
859
860 AssertConnectFails(ERR_HTTPS_PROXY_TUNNEL_RESPONSE);
861
862 Run(2); // SpdySession consumes the next two reads and sends then to
863 // sock_ to be buffered.
864 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED,
865 sock_->Read(NULL, 1, CompletionCallback()));
866 scoped_refptr<IOBuffer> buf(new IOBuffer(kLen1 + kLen2));
867 scoped_ptr<HttpStream> stream(sock_->CreateConnectResponseStream());
868 stream->ReadResponseBody(buf, kLen1 + kLen2, read_callback_.callback());
869 }
870
871 // ----------- Reads and Writes
872
873 TEST_F(SpdyProxyClientSocketTest, AsyncReadAroundWrite) {
874 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
875 scoped_ptr<spdy::SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
876 MockWrite writes[] = {
877 CreateMockWrite(*conn, 0, SYNCHRONOUS),
878 CreateMockWrite(*msg2, 3, SYNCHRONOUS),
879 };
880
881 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
882 scoped_ptr<spdy::SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
883 scoped_ptr<spdy::SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
884 MockRead reads[] = {
885 CreateMockRead(*resp, 1, ASYNC),
886 CreateMockRead(*msg1, 2, ASYNC), // sync read
887 CreateMockRead(*msg3, 4, ASYNC), // async read
888 MockRead(ASYNC, 0, 5), // EOF
889 };
890
891 Initialize(reads, arraysize(reads), writes, arraysize(writes));
892
893 AssertConnectSucceeds();
894
895 Run(1);
896 AssertSyncReadEquals(kMsg1, kLen1);
897
898 AssertReadStarts(kMsg3, kLen3);
899 // Read should block until after the write succeeds
900
901 AssertAsyncWriteSucceeds(kMsg2, kLen2); // Runs 1 step
902
903 ASSERT_FALSE(read_callback_.have_result());
904 Run(1);
905 // Now the read will return
906 AssertReadReturns(kMsg3, kLen3);
907 }
908
909 TEST_F(SpdyProxyClientSocketTest, AsyncWriteAroundReads) {
910 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
911 scoped_ptr<spdy::SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
912 MockWrite writes[] = {
913 CreateMockWrite(*conn, 0, SYNCHRONOUS),
914 CreateMockWrite(*msg2, 4, ASYNC),
915 };
916
917 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
918 scoped_ptr<spdy::SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
919 scoped_ptr<spdy::SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
920 MockRead reads[] = {
921 CreateMockRead(*resp, 1, ASYNC),
922 CreateMockRead(*msg1, 2, ASYNC),
923 CreateMockRead(*msg3, 3, ASYNC),
924 MockRead(ASYNC, 0, 5), // EOF
925 };
926
927 Initialize(reads, arraysize(reads), writes, arraysize(writes));
928
929 AssertConnectSucceeds();
930
931 Run(1);
932 AssertSyncReadEquals(kMsg1, kLen1);
933 // Write should block until the read completes
934 AssertWriteReturns(kMsg2, kLen2, ERR_IO_PENDING);
935
936 AssertAsyncReadEquals(kMsg3, kLen3);
937
938 ASSERT_FALSE(write_callback_.have_result());
939
940 // Now the write will complete
941 Run(1);
942 AssertWriteLength(kLen2);
943 }
944
945 // ----------- Reading/Writing on Closed socket
946
947 // Reading from an already closed socket should return 0
948 TEST_F(SpdyProxyClientSocketTest, ReadOnClosedSocketReturnsZero) {
949 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
950 MockWrite writes[] = {
951 CreateMockWrite(*conn, 0, SYNCHRONOUS),
952 };
953
954 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
955 MockRead reads[] = {
956 CreateMockRead(*resp, 1, ASYNC),
957 MockRead(ASYNC, 0, 2), // EOF
958 };
959
960 Initialize(reads, arraysize(reads), writes, arraysize(writes));
961
962 AssertConnectSucceeds();
963
964 Run(1);
965
966 ASSERT_FALSE(sock_->IsConnected());
967 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
968 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
969 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
970 ASSERT_FALSE(sock_->IsConnectedAndIdle());
971 }
972
973 // Read pending when socket is closed should return 0
974 TEST_F(SpdyProxyClientSocketTest, PendingReadOnCloseReturnsZero) {
975 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
976 MockWrite writes[] = {
977 CreateMockWrite(*conn, 0, SYNCHRONOUS),
978 };
979
980 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
981 MockRead reads[] = {
982 CreateMockRead(*resp, 1, ASYNC),
983 MockRead(ASYNC, 0, 2), // EOF
984 };
985
986 Initialize(reads, arraysize(reads), writes, arraysize(writes));
987
988 AssertConnectSucceeds();
989
990 AssertReadStarts(kMsg1, kLen1);
991
992 Run(1);
993
994 ASSERT_EQ(0, read_callback_.WaitForResult());
995 }
996
997 // Reading from a disconnected socket is an error
998 TEST_F(SpdyProxyClientSocketTest, ReadOnDisconnectSocketReturnsNotConnected) {
999 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
1000 MockWrite writes[] = {
1001 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1002 };
1003
1004 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
1005 MockRead reads[] = {
1006 CreateMockRead(*resp, 1, ASYNC),
1007 MockRead(ASYNC, 0, 2), // EOF
1008 };
1009
1010 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1011
1012 AssertConnectSucceeds();
1013
1014 sock_->Disconnect();
1015
1016 ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED,
1017 sock_->Read(NULL, 1, CompletionCallback()));
1018 }
1019
1020 // Reading buffered data from an already closed socket should return
1021 // buffered data, then 0.
1022 TEST_F(SpdyProxyClientSocketTest, ReadOnClosedSocketReturnsBufferedData) {
1023 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
1024 MockWrite writes[] = {
1025 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1026 };
1027
1028 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
1029 scoped_ptr<spdy::SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
1030 MockRead reads[] = {
1031 CreateMockRead(*resp, 1, ASYNC),
1032 CreateMockRead(*msg1, 2, ASYNC),
1033 MockRead(ASYNC, 0, 3), // EOF
1034 };
1035
1036 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1037
1038 AssertConnectSucceeds();
1039
1040 Run(2);
1041
1042 ASSERT_FALSE(sock_->IsConnected());
1043 scoped_refptr<IOBuffer> buf(new IOBuffer(kLen1));
1044 ASSERT_EQ(kLen1, sock_->Read(buf, kLen1, CompletionCallback()));
1045 ASSERT_EQ(std::string(kMsg1, kLen1), std::string(buf->data(), kLen1));
1046
1047 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
1048 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
1049 sock_->Disconnect();
1050 ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED,
1051 sock_->Read(NULL, 1, CompletionCallback()));
1052 }
1053
1054 // Calling Write() on a closed socket is an error
1055 TEST_F(SpdyProxyClientSocketTest, WriteOnClosedStream) {
1056 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
1057 MockWrite writes[] = {
1058 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1059 };
1060
1061 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
1062 scoped_ptr<spdy::SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
1063 MockRead reads[] = {
1064 CreateMockRead(*resp, 1, ASYNC),
1065 MockRead(ASYNC, 0, 2), // EOF
1066 };
1067
1068 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1069
1070 AssertConnectSucceeds();
1071
1072 Run(1); // Read EOF which will close the stream
1073 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
1074 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED,
1075 sock_->Write(buf, buf->size(), CompletionCallback()));
1076 }
1077
1078 // Calling Write() on a disconnected socket is an error
1079 TEST_F(SpdyProxyClientSocketTest, WriteOnDisconnectedSocket) {
1080 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
1081 MockWrite writes[] = {
1082 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1083 };
1084
1085 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
1086 scoped_ptr<spdy::SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
1087 MockRead reads[] = {
1088 CreateMockRead(*resp, 1, ASYNC),
1089 MockRead(ASYNC, 0, 2), // EOF
1090 };
1091
1092 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1093
1094 AssertConnectSucceeds();
1095
1096 sock_->Disconnect();
1097
1098 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
1099 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED,
1100 sock_->Write(buf, buf->size(), CompletionCallback()));
1101 }
1102
1103 // If the socket is closed with a pending Write(), the callback
1104 // should be called with ERR_CONNECTION_CLOSED.
1105 TEST_F(SpdyProxyClientSocketTest, WritePendingOnClose) {
1106 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
1107 MockWrite writes[] = {
1108 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1109 MockWrite(ASYNC, ERR_IO_PENDING, 2),
1110 };
1111
1112 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
1113 MockRead reads[] = {
1114 CreateMockRead(*resp, 1, ASYNC),
1115 MockRead(ASYNC, 0, 3), // EOF
1116 };
1117
1118 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1119
1120 AssertConnectSucceeds();
1121
1122 EXPECT_TRUE(sock_->IsConnected());
1123
1124 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
1125 EXPECT_EQ(ERR_IO_PENDING,
1126 sock_->Write(buf, buf->size(), write_callback_.callback()));
1127
1128 Run(1);
1129
1130 EXPECT_EQ(ERR_CONNECTION_CLOSED, write_callback_.WaitForResult());
1131 }
1132
1133 // If the socket is Disconnected with a pending Write(), the callback
1134 // should not be called.
1135 TEST_F(SpdyProxyClientSocketTest, DisconnectWithWritePending) {
1136 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
1137 MockWrite writes[] = {
1138 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1139 MockWrite(SYNCHRONOUS, 0, 2), // EOF
1140 };
1141
1142 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
1143 MockRead reads[] = {
1144 CreateMockRead(*resp, 1, ASYNC),
1145 MockRead(ASYNC, 0, 3), // EOF
1146 };
1147
1148 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1149
1150 AssertConnectSucceeds();
1151
1152 EXPECT_TRUE(sock_->IsConnected());
1153
1154 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
1155 EXPECT_EQ(ERR_IO_PENDING,
1156 sock_->Write(buf, buf->size(), write_callback_.callback()));
1157
1158 sock_->Disconnect();
1159
1160 EXPECT_FALSE(sock_->IsConnected());
1161 EXPECT_FALSE(write_callback_.have_result());
1162 }
1163
1164 // If the socket is Disconnected with a pending Read(), the callback
1165 // should not be called.
1166 TEST_F(SpdyProxyClientSocketTest, DisconnectWithReadPending) {
1167 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
1168 MockWrite writes[] = {
1169 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1170 };
1171
1172 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
1173 MockRead reads[] = {
1174 CreateMockRead(*resp, 1, ASYNC),
1175 MockRead(ASYNC, 0, 2), // EOF
1176 };
1177
1178 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1179
1180 AssertConnectSucceeds();
1181
1182 EXPECT_TRUE(sock_->IsConnected());
1183
1184 scoped_refptr<IOBuffer> buf(new IOBuffer(kLen1));
1185 ASSERT_EQ(ERR_IO_PENDING,
1186 sock_->Read(buf, kLen1, read_callback_.callback()));
1187
1188 sock_->Disconnect();
1189
1190 EXPECT_FALSE(sock_->IsConnected());
1191 EXPECT_FALSE(read_callback_.have_result());
1192 }
1193
1194 // If the socket is Reset when both a read and write are pending,
1195 // both should be called back.
1196 TEST_F(SpdyProxyClientSocketTest, RstWithReadAndWritePending) {
1197 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
1198 MockWrite writes[] = {
1199 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1200 MockWrite(ASYNC, ERR_IO_PENDING, 2),
1201 };
1202
1203 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
1204 scoped_ptr<spdy::SpdyFrame> rst(ConstructSpdyRstStream(1, spdy::CANCEL));
1205 MockRead reads[] = {
1206 CreateMockRead(*resp, 1, ASYNC),
1207 CreateMockRead(*rst, 3, ASYNC),
1208 };
1209
1210 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1211
1212 AssertConnectSucceeds();
1213
1214 EXPECT_TRUE(sock_->IsConnected());
1215
1216 scoped_refptr<IOBuffer> read_buf(new IOBuffer(kLen1));
1217 ASSERT_EQ(ERR_IO_PENDING,
1218 sock_->Read(read_buf, kLen1, read_callback_.callback()));
1219
1220 scoped_refptr<IOBufferWithSize> write_buf(CreateBuffer(kMsg1, kLen1));
1221 EXPECT_EQ(ERR_IO_PENDING,
1222 sock_->Write(write_buf, write_buf->size(),
1223 write_callback_.callback()));
1224
1225 Run(2);
1226
1227 EXPECT_TRUE(sock_.get());
1228 EXPECT_TRUE(read_callback_.have_result());
1229 EXPECT_TRUE(write_callback_.have_result());
1230 }
1231
1232 // CompletionCallback that causes the SpdyProxyClientSocket to be
1233 // deleted when Run is invoked.
1234 class DeleteSockCallback : public TestCompletionCallbackBase {
1235 public:
1236 explicit DeleteSockCallback(scoped_ptr<SpdyProxyClientSocket>* sock)
1237 : sock_(sock),
1238 ALLOW_THIS_IN_INITIALIZER_LIST(callback_(
1239 base::Bind(&DeleteSockCallback::OnComplete,
1240 base::Unretained(this)))) {
1241 }
1242
1243 virtual ~DeleteSockCallback() {
1244 }
1245
1246 const CompletionCallback& callback() const { return callback_; }
1247
1248 private:
1249 void OnComplete(int result) {
1250 sock_->reset(NULL);
1251 SetResult(result);
1252 }
1253
1254 scoped_ptr<SpdyProxyClientSocket>* sock_;
1255 CompletionCallback callback_;
1256
1257 DISALLOW_COPY_AND_ASSIGN(DeleteSockCallback);
1258 };
1259
1260 // If the socket is Reset when both a read and write are pending, and the
1261 // read callback causes the socket to be deleted, the write callback should
1262 // not be called.
1263 TEST_F(SpdyProxyClientSocketTest, RstWithReadAndWritePendingDelete) {
1264 scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
1265 MockWrite writes[] = {
1266 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1267 MockWrite(ASYNC, ERR_IO_PENDING, 2),
1268 };
1269
1270 scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
1271 scoped_ptr<spdy::SpdyFrame> rst(ConstructSpdyRstStream(1, spdy::CANCEL));
1272 MockRead reads[] = {
1273 CreateMockRead(*resp, 1, ASYNC),
1274 CreateMockRead(*rst, 3, ASYNC),
1275 };
1276
1277 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1278
1279 AssertConnectSucceeds();
1280
1281 EXPECT_TRUE(sock_->IsConnected());
1282
1283 DeleteSockCallback read_callback(&sock_);
1284
1285 scoped_refptr<IOBuffer> read_buf(new IOBuffer(kLen1));
1286 ASSERT_EQ(ERR_IO_PENDING,
1287 sock_->Read(read_buf, kLen1, read_callback.callback()));
1288
1289 scoped_refptr<IOBufferWithSize> write_buf(CreateBuffer(kMsg1, kLen1));
1290 EXPECT_EQ(ERR_IO_PENDING, sock_->Write(write_buf, write_buf->size(),
1291 write_callback_.callback()));
1292
1293 Run(2);
1294
1295 EXPECT_FALSE(sock_.get());
1296 EXPECT_TRUE(read_callback.have_result());
1297 EXPECT_FALSE(write_callback_.have_result());
1298 }
1299
1300 } // namespace net
OLDNEW
« no previous file with comments | « net/spdy/spdy_proxy_client_socket_spdy3_unittest.cc ('k') | net/spdy/spdy_session.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698