Revert "Merged all Chromoting Host code into remoting_core.dll (Windows)."
[chromium-blink-merge.git] / net / spdy / spdy_proxy_client_socket_spdy3_unittest.cc
blob627568f65b480cffca9ecbfd2402236c2152719d
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/spdy/spdy_proxy_client_socket.h"
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/buffered_spdy_framer.h"
22 #include "net/spdy/spdy_http_utils.h"
23 #include "net/spdy/spdy_protocol.h"
24 #include "net/spdy/spdy_session_pool.h"
25 #include "net/spdy/spdy_test_util_spdy3.h"
26 #include "testing/platform_test.h"
27 #include "testing/gtest/include/gtest/gtest.h"
29 using namespace net::test_spdy3;
31 //-----------------------------------------------------------------------------
33 namespace {
35 static const char kRequestUrl[] = "https://www.google.com/";
36 static const char kOriginHost[] = "www.google.com";
37 static const int kOriginPort = 443;
38 static const char kOriginHostPort[] = "www.google.com:443";
39 static const char kProxyUrl[] = "https://myproxy:6121/";
40 static const char kProxyHost[] = "myproxy";
41 static const int kProxyPort = 6121;
42 static const char kUserAgent[] = "Mozilla/1.0";
44 static const int kStreamId = 1;
46 static const char kMsg1[] = "\0hello!\xff";
47 static const int kLen1 = 8;
48 static const char kMsg2[] = "\00012345678\0";
49 static const int kLen2 = 10;
50 static const char kMsg3[] = "bye!";
51 static const int kLen3 = 4;
52 static const char kMsg33[] = "bye!bye!";
53 static const int kLen33 = kLen3 + kLen3;
54 static const char kMsg333[] = "bye!bye!bye!";
55 static const int kLen333 = kLen3 + kLen3 + kLen3;
57 static const char kRedirectUrl[] = "https://example.com/";
59 } // anonymous namespace
61 namespace net {
63 class SpdyProxyClientSocketSpdy3Test : public PlatformTest {
64 public:
65 SpdyProxyClientSocketSpdy3Test();
67 virtual void TearDown();
69 protected:
70 void Initialize(MockRead* reads, size_t reads_count, MockWrite* writes,
71 size_t writes_count);
72 SpdyFrame* ConstructConnectRequestFrame();
73 SpdyFrame* ConstructConnectAuthRequestFrame();
74 SpdyFrame* ConstructConnectReplyFrame();
75 SpdyFrame* ConstructConnectAuthReplyFrame();
76 SpdyFrame* ConstructConnectRedirectReplyFrame();
77 SpdyFrame* ConstructConnectErrorReplyFrame();
78 SpdyFrame* ConstructBodyFrame(const char* data, int length);
79 scoped_refptr<IOBufferWithSize> CreateBuffer(const char* data, int size);
80 void AssertConnectSucceeds();
81 void AssertConnectFails(int result);
82 void AssertConnectionEstablished();
83 void AssertSyncReadEquals(const char* data, int len);
84 void AssertAsyncReadEquals(const char* data, int len);
85 void AssertReadStarts(const char* data, int len);
86 void AssertReadReturns(const char* data, int len);
87 void AssertAsyncWriteSucceeds(const char* data, int len);
88 void AssertWriteReturns(const char* data, int len, int rv);
89 void AssertWriteLength(int len);
90 void AssertAsyncWriteWithReadsSucceeds(const char* data, int len,
91 int num_reads);
93 void AddAuthToCache() {
94 const string16 kFoo(ASCIIToUTF16("foo"));
95 const string16 kBar(ASCIIToUTF16("bar"));
96 session_->http_auth_cache()->Add(GURL(kProxyUrl),
97 "MyRealm1",
98 HttpAuth::AUTH_SCHEME_BASIC,
99 "Basic realm=MyRealm1",
100 AuthCredentials(kFoo, kBar),
101 "/");
104 void Run(int steps) {
105 data_->StopAfter(steps);
106 data_->Run();
109 scoped_ptr<SpdyProxyClientSocket> sock_;
110 TestCompletionCallback read_callback_;
111 TestCompletionCallback write_callback_;
112 scoped_ptr<DeterministicSocketData> data_;
114 private:
115 scoped_refptr<HttpNetworkSession> session_;
116 scoped_refptr<IOBuffer> read_buf_;
117 SpdySessionDependencies session_deps_;
118 MockConnect connect_data_;
119 scoped_refptr<SpdySession> spdy_session_;
120 scoped_refptr<SpdyStream> spdy_stream_;
121 BufferedSpdyFramer framer_;
123 std::string user_agent_;
124 GURL url_;
125 HostPortPair proxy_host_port_;
126 HostPortPair endpoint_host_port_pair_;
127 ProxyServer proxy_;
128 HostPortProxyPair endpoint_host_port_proxy_pair_;
129 scoped_refptr<TransportSocketParams> transport_params_;
131 DISALLOW_COPY_AND_ASSIGN(SpdyProxyClientSocketSpdy3Test);
134 SpdyProxyClientSocketSpdy3Test::SpdyProxyClientSocketSpdy3Test()
135 : sock_(NULL),
136 data_(NULL),
137 session_(NULL),
138 read_buf_(NULL),
139 session_deps_(),
140 connect_data_(SYNCHRONOUS, OK),
141 spdy_session_(NULL),
142 spdy_stream_(NULL),
143 framer_(3, false),
144 user_agent_(kUserAgent),
145 url_(kRequestUrl),
146 proxy_host_port_(kProxyHost, kProxyPort),
147 endpoint_host_port_pair_(kOriginHost, kOriginPort),
148 proxy_(ProxyServer::SCHEME_HTTPS, proxy_host_port_),
149 endpoint_host_port_proxy_pair_(endpoint_host_port_pair_, proxy_),
150 transport_params_(new TransportSocketParams(proxy_host_port_,
151 LOWEST,
152 false,
153 false,
154 OnHostResolutionCallback())) {
157 void SpdyProxyClientSocketSpdy3Test::TearDown() {
158 sock_.reset(NULL);
159 if (session_ != NULL)
160 session_->spdy_session_pool()->CloseAllSessions();
162 // Empty the current queue.
163 MessageLoop::current()->RunUntilIdle();
164 PlatformTest::TearDown();
167 void SpdyProxyClientSocketSpdy3Test::Initialize(MockRead* reads,
168 size_t reads_count,
169 MockWrite* writes,
170 size_t writes_count) {
171 data_.reset(new DeterministicSocketData(reads, reads_count,
172 writes, writes_count));
173 data_->set_connect_data(connect_data_);
174 data_->SetStop(2);
176 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
177 data_.get());
178 session_deps_.host_resolver->set_synchronous_mode(true);
180 session_ = SpdySessionDependencies::SpdyCreateSessionDeterministic(
181 &session_deps_);
183 // Creates a new spdy session
184 spdy_session_ =
185 session_->spdy_session_pool()->Get(endpoint_host_port_proxy_pair_,
186 BoundNetLog());
188 // Perform the TCP connect
189 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
190 EXPECT_EQ(OK,
191 connection->Init(endpoint_host_port_pair_.ToString(),
192 transport_params_, LOWEST, CompletionCallback(),
193 session_->GetTransportSocketPool(
194 HttpNetworkSession::NORMAL_SOCKET_POOL),
195 BoundNetLog()));
196 spdy_session_->InitializeWithSocket(connection.release(), false, OK);
198 // Create the SPDY Stream
199 ASSERT_EQ(
201 spdy_session_->CreateStream(url_, LOWEST, &spdy_stream_, BoundNetLog(),
202 CompletionCallback()));
204 // Create the SpdyProxyClientSocket
205 sock_.reset(
206 new SpdyProxyClientSocket(spdy_stream_, user_agent_,
207 endpoint_host_port_pair_, url_,
208 proxy_host_port_, session_->http_auth_cache(),
209 session_->http_auth_handler_factory()));
212 scoped_refptr<IOBufferWithSize> SpdyProxyClientSocketSpdy3Test::CreateBuffer(
213 const char* data, int size) {
214 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(size));
215 memcpy(buf->data(), data, size);
216 return buf;
219 void SpdyProxyClientSocketSpdy3Test::AssertConnectSucceeds() {
220 ASSERT_EQ(ERR_IO_PENDING, sock_->Connect(read_callback_.callback()));
221 data_->Run();
222 ASSERT_EQ(OK, read_callback_.WaitForResult());
225 void SpdyProxyClientSocketSpdy3Test::AssertConnectFails(int result) {
226 ASSERT_EQ(ERR_IO_PENDING, sock_->Connect(read_callback_.callback()));
227 data_->Run();
228 ASSERT_EQ(result, read_callback_.WaitForResult());
231 void SpdyProxyClientSocketSpdy3Test::AssertConnectionEstablished() {
232 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
233 ASSERT_TRUE(response != NULL);
234 ASSERT_EQ(200, response->headers->response_code());
235 ASSERT_EQ("Connection Established", response->headers->GetStatusText());
238 void SpdyProxyClientSocketSpdy3Test::AssertSyncReadEquals(const char* data,
239 int len) {
240 scoped_refptr<IOBuffer> buf(new IOBuffer(len));
241 ASSERT_EQ(len, sock_->Read(buf, len, CompletionCallback()));
242 ASSERT_EQ(std::string(data, len), std::string(buf->data(), len));
243 ASSERT_TRUE(sock_->IsConnected());
246 void SpdyProxyClientSocketSpdy3Test::AssertAsyncReadEquals(const char* data,
247 int len) {
248 data_->StopAfter(1);
249 // Issue the read, which will be completed asynchronously
250 scoped_refptr<IOBuffer> buf(new IOBuffer(len));
251 ASSERT_EQ(ERR_IO_PENDING, sock_->Read(buf, len, read_callback_.callback()));
252 EXPECT_TRUE(sock_->IsConnected());
253 data_->Run();
255 EXPECT_TRUE(sock_->IsConnected());
257 // Now the read will return
258 EXPECT_EQ(len, read_callback_.WaitForResult());
259 ASSERT_EQ(std::string(data, len), std::string(buf->data(), len));
262 void SpdyProxyClientSocketSpdy3Test::AssertReadStarts(const char* data,
263 int len) {
264 data_->StopAfter(1);
265 // Issue the read, which will be completed asynchronously
266 read_buf_ = new IOBuffer(len);
267 ASSERT_EQ(ERR_IO_PENDING,
268 sock_->Read(read_buf_, len, read_callback_.callback()));
269 EXPECT_TRUE(sock_->IsConnected());
272 void SpdyProxyClientSocketSpdy3Test::AssertReadReturns(const char* data,
273 int len) {
274 EXPECT_TRUE(sock_->IsConnected());
276 // Now the read will return
277 EXPECT_EQ(len, read_callback_.WaitForResult());
278 ASSERT_EQ(std::string(data, len), std::string(read_buf_->data(), len));
281 void SpdyProxyClientSocketSpdy3Test::AssertAsyncWriteSucceeds(const char* data,
282 int len) {
283 AssertWriteReturns(data, len, ERR_IO_PENDING);
284 data_->RunFor(1);
285 AssertWriteLength(len);
288 void SpdyProxyClientSocketSpdy3Test::AssertWriteReturns(const char* data,
289 int len,
290 int rv) {
291 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(data, len));
292 EXPECT_EQ(rv, sock_->Write(buf, buf->size(), write_callback_.callback()));
295 void SpdyProxyClientSocketSpdy3Test::AssertWriteLength(int len) {
296 EXPECT_EQ(len, write_callback_.WaitForResult());
299 void SpdyProxyClientSocketSpdy3Test::AssertAsyncWriteWithReadsSucceeds(
300 const char* data, int len, int num_reads) {
301 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(data, len));
303 EXPECT_EQ(ERR_IO_PENDING, sock_->Write(buf, buf->size(),
304 write_callback_.callback()));
306 for (int i = 0; i < num_reads; i++) {
307 Run(1);
308 AssertSyncReadEquals(kMsg2, kLen2);
311 write_callback_.WaitForResult();
314 // Constructs a standard SPDY SYN_STREAM frame for a CONNECT request.
315 SpdyFrame*
316 SpdyProxyClientSocketSpdy3Test::ConstructConnectRequestFrame() {
317 const SpdyHeaderInfo kSynStartHeader = {
318 SYN_STREAM,
319 kStreamId,
321 net::ConvertRequestPriorityToSpdyPriority(LOWEST, 3),
323 CONTROL_FLAG_NONE,
324 false,
325 INVALID,
326 NULL,
328 DATA_FLAG_NONE
330 const char* const kConnectHeaders[] = {
331 ":method", "CONNECT",
332 ":path", kOriginHostPort,
333 ":host", kOriginHost,
334 "user-agent", kUserAgent,
335 ":version", "HTTP/1.1",
337 return ConstructSpdyPacket(
338 kSynStartHeader, NULL, 0, kConnectHeaders, arraysize(kConnectHeaders)/2);
341 // Constructs a SPDY SYN_STREAM frame for a CONNECT request which includes
342 // Proxy-Authorization headers.
343 SpdyFrame*
344 SpdyProxyClientSocketSpdy3Test::ConstructConnectAuthRequestFrame() {
345 const SpdyHeaderInfo kSynStartHeader = {
346 SYN_STREAM,
347 kStreamId,
349 net::ConvertRequestPriorityToSpdyPriority(LOWEST, 3),
351 CONTROL_FLAG_NONE,
352 false,
353 INVALID,
354 NULL,
356 DATA_FLAG_NONE
358 const char* const kConnectHeaders[] = {
359 ":method", "CONNECT",
360 ":path", kOriginHostPort,
361 ":host", kOriginHost,
362 "user-agent", kUserAgent,
363 ":version", "HTTP/1.1",
364 "proxy-authorization", "Basic Zm9vOmJhcg==",
366 return ConstructSpdyPacket(
367 kSynStartHeader, NULL, 0, kConnectHeaders, arraysize(kConnectHeaders)/2);
370 // Constructs a standard SPDY SYN_REPLY frame to match the SPDY CONNECT.
371 SpdyFrame* SpdyProxyClientSocketSpdy3Test::ConstructConnectReplyFrame() {
372 const char* const kStandardReplyHeaders[] = {
373 ":status", "200 Connection Established",
374 ":version", "HTTP/1.1"
376 return ConstructSpdyControlFrame(NULL,
378 false,
379 kStreamId,
380 LOWEST,
381 SYN_REPLY,
382 CONTROL_FLAG_NONE,
383 kStandardReplyHeaders,
384 arraysize(kStandardReplyHeaders));
387 // Constructs a standard SPDY SYN_REPLY frame to match the SPDY CONNECT.
388 SpdyFrame*
389 SpdyProxyClientSocketSpdy3Test::ConstructConnectAuthReplyFrame() {
390 const char* const kStandardReplyHeaders[] = {
391 ":status", "407 Proxy Authentication Required",
392 ":version", "HTTP/1.1",
393 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
396 return ConstructSpdyControlFrame(NULL,
398 false,
399 kStreamId,
400 LOWEST,
401 SYN_REPLY,
402 CONTROL_FLAG_NONE,
403 kStandardReplyHeaders,
404 arraysize(kStandardReplyHeaders));
407 // Constructs a SPDY SYN_REPLY frame with an HTTP 302 redirect.
408 SpdyFrame*
409 SpdyProxyClientSocketSpdy3Test::ConstructConnectRedirectReplyFrame() {
410 const char* const kStandardReplyHeaders[] = {
411 ":status", "302 Found",
412 ":version", "HTTP/1.1",
413 "location", kRedirectUrl,
414 "set-cookie", "foo=bar"
417 return ConstructSpdyControlFrame(NULL,
419 false,
420 kStreamId,
421 LOWEST,
422 SYN_REPLY,
423 CONTROL_FLAG_NONE,
424 kStandardReplyHeaders,
425 arraysize(kStandardReplyHeaders));
428 // Constructs a SPDY SYN_REPLY frame with an HTTP 500 error.
429 SpdyFrame*
430 SpdyProxyClientSocketSpdy3Test::ConstructConnectErrorReplyFrame() {
431 const char* const kStandardReplyHeaders[] = {
432 ":status", "500 Internal Server Error",
433 ":version", "HTTP/1.1",
436 return ConstructSpdyControlFrame(NULL,
438 false,
439 kStreamId,
440 LOWEST,
441 SYN_REPLY,
442 CONTROL_FLAG_NONE,
443 kStandardReplyHeaders,
444 arraysize(kStandardReplyHeaders));
447 SpdyFrame* SpdyProxyClientSocketSpdy3Test::ConstructBodyFrame(
448 const char* data,
449 int length) {
450 return framer_.CreateDataFrame(kStreamId, data, length, DATA_FLAG_NONE);
453 // ----------- Connect
455 TEST_F(SpdyProxyClientSocketSpdy3Test, ConnectSendsCorrectRequest) {
456 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
457 MockWrite writes[] = {
458 CreateMockWrite(*conn, 0, SYNCHRONOUS),
461 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
462 MockRead reads[] = {
463 CreateMockRead(*resp, 1, ASYNC),
464 MockRead(ASYNC, 0, 2), // EOF
467 Initialize(reads, arraysize(reads), writes, arraysize(writes));
469 ASSERT_FALSE(sock_->IsConnected());
471 AssertConnectSucceeds();
473 AssertConnectionEstablished();
476 TEST_F(SpdyProxyClientSocketSpdy3Test, ConnectWithAuthRequested) {
477 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
478 MockWrite writes[] = {
479 CreateMockWrite(*conn, 0, SYNCHRONOUS),
482 scoped_ptr<SpdyFrame> resp(ConstructConnectAuthReplyFrame());
483 MockRead reads[] = {
484 CreateMockRead(*resp, 1, ASYNC),
485 MockRead(ASYNC, 0, 2), // EOF
488 Initialize(reads, arraysize(reads), writes, arraysize(writes));
490 AssertConnectFails(ERR_PROXY_AUTH_REQUESTED);
492 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
493 ASSERT_TRUE(response != NULL);
494 ASSERT_EQ(407, response->headers->response_code());
495 ASSERT_EQ("Proxy Authentication Required",
496 response->headers->GetStatusText());
499 TEST_F(SpdyProxyClientSocketSpdy3Test, ConnectWithAuthCredentials) {
500 scoped_ptr<SpdyFrame> conn(ConstructConnectAuthRequestFrame());
501 MockWrite writes[] = {
502 CreateMockWrite(*conn, 0, SYNCHRONOUS),
505 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
506 MockRead reads[] = {
507 CreateMockRead(*resp, 1, ASYNC),
508 MockRead(ASYNC, 0, 2), // EOF
511 Initialize(reads, arraysize(reads), writes, arraysize(writes));
512 AddAuthToCache();
514 AssertConnectSucceeds();
516 AssertConnectionEstablished();
519 TEST_F(SpdyProxyClientSocketSpdy3Test, ConnectRedirects) {
520 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
521 MockWrite writes[] = {
522 CreateMockWrite(*conn, 0, SYNCHRONOUS),
525 scoped_ptr<SpdyFrame> resp(ConstructConnectRedirectReplyFrame());
526 MockRead reads[] = {
527 CreateMockRead(*resp, 1, ASYNC),
528 MockRead(ASYNC, 0, 2), // EOF
531 Initialize(reads, arraysize(reads), writes, arraysize(writes));
533 AssertConnectFails(ERR_HTTPS_PROXY_TUNNEL_RESPONSE);
535 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
536 ASSERT_TRUE(response != NULL);
538 const HttpResponseHeaders* headers = response->headers;
539 ASSERT_EQ(302, headers->response_code());
540 ASSERT_FALSE(headers->HasHeader("set-cookie"));
541 ASSERT_TRUE(headers->HasHeaderValue("content-length", "0"));
543 std::string location;
544 ASSERT_TRUE(headers->IsRedirect(&location));
545 ASSERT_EQ(location, kRedirectUrl);
548 TEST_F(SpdyProxyClientSocketSpdy3Test, ConnectFails) {
549 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
550 MockWrite writes[] = {
551 CreateMockWrite(*conn, 0, SYNCHRONOUS),
554 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
555 MockRead reads[] = {
556 MockRead(ASYNC, 0, 1), // EOF
559 Initialize(reads, arraysize(reads), writes, arraysize(writes));
561 ASSERT_FALSE(sock_->IsConnected());
563 AssertConnectFails(ERR_CONNECTION_CLOSED);
565 ASSERT_FALSE(sock_->IsConnected());
568 // ----------- WasEverUsed
570 TEST_F(SpdyProxyClientSocketSpdy3Test, WasEverUsedReturnsCorrectValues) {
571 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
572 MockWrite writes[] = {
573 CreateMockWrite(*conn, 0, SYNCHRONOUS),
576 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
577 MockRead reads[] = {
578 CreateMockRead(*resp, 1, ASYNC),
579 MockRead(ASYNC, 0, 2), // EOF
582 Initialize(reads, arraysize(reads), writes, arraysize(writes));
584 EXPECT_FALSE(sock_->WasEverUsed());
585 AssertConnectSucceeds();
586 EXPECT_TRUE(sock_->WasEverUsed());
587 sock_->Disconnect();
588 EXPECT_TRUE(sock_->WasEverUsed());
591 // ----------- GetPeerAddress
593 TEST_F(SpdyProxyClientSocketSpdy3Test, GetPeerAddressReturnsCorrectValues) {
594 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
595 MockWrite writes[] = {
596 CreateMockWrite(*conn, 0, SYNCHRONOUS),
599 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
600 MockRead reads[] = {
601 CreateMockRead(*resp, 1, ASYNC),
602 MockRead(ASYNC, 0, 2), // EOF
605 Initialize(reads, arraysize(reads), writes, arraysize(writes));
607 net::IPEndPoint addr;
608 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr));
610 AssertConnectSucceeds();
611 EXPECT_TRUE(sock_->IsConnected());
612 EXPECT_EQ(OK, sock_->GetPeerAddress(&addr));
614 Run(1);
616 EXPECT_FALSE(sock_->IsConnected());
617 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr));
619 sock_->Disconnect();
621 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr));
624 // ----------- Write
626 TEST_F(SpdyProxyClientSocketSpdy3Test, WriteSendsDataInDataFrame) {
627 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
628 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
629 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
630 MockWrite writes[] = {
631 CreateMockWrite(*conn, 0, SYNCHRONOUS),
632 CreateMockWrite(*msg1, 2, SYNCHRONOUS),
633 CreateMockWrite(*msg2, 3, SYNCHRONOUS),
636 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
637 MockRead reads[] = {
638 CreateMockRead(*resp, 1, ASYNC),
639 MockRead(ASYNC, 0, 4), // EOF
642 Initialize(reads, arraysize(reads), writes, arraysize(writes));
644 AssertConnectSucceeds();
646 AssertAsyncWriteSucceeds(kMsg1, kLen1);
647 AssertAsyncWriteSucceeds(kMsg2, kLen2);
650 TEST_F(SpdyProxyClientSocketSpdy3Test, WriteSplitsLargeDataIntoMultipleFrames) {
651 std::string chunk_data(kMaxSpdyFrameChunkSize, 'x');
652 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
653 scoped_ptr<SpdyFrame> chunk(ConstructBodyFrame(chunk_data.data(),
654 chunk_data.length()));
655 MockWrite writes[] = {
656 CreateMockWrite(*conn, 0, SYNCHRONOUS),
657 CreateMockWrite(*chunk, 2, SYNCHRONOUS),
658 CreateMockWrite(*chunk, 3, SYNCHRONOUS),
659 CreateMockWrite(*chunk, 4, SYNCHRONOUS)
662 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
663 MockRead reads[] = {
664 CreateMockRead(*resp, 1, ASYNC),
665 MockRead(ASYNC, 0, 5), // EOF
668 Initialize(reads, arraysize(reads), writes, arraysize(writes));
670 AssertConnectSucceeds();
672 std::string big_data(kMaxSpdyFrameChunkSize * 3, 'x');
673 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(big_data.data(),
674 big_data.length()));
676 EXPECT_EQ(ERR_IO_PENDING, sock_->Write(buf, buf->size(),
677 write_callback_.callback()));
678 data_->RunFor(3);
680 EXPECT_EQ(buf->size(), write_callback_.WaitForResult());
683 // ----------- Read
685 TEST_F(SpdyProxyClientSocketSpdy3Test, ReadReadsDataInDataFrame) {
686 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
687 MockWrite writes[] = {
688 CreateMockWrite(*conn, 0, SYNCHRONOUS),
691 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
692 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
693 MockRead reads[] = {
694 CreateMockRead(*resp, 1, ASYNC),
695 CreateMockRead(*msg1, 2, ASYNC),
696 MockRead(ASYNC, 0, 3), // EOF
699 Initialize(reads, arraysize(reads), writes, arraysize(writes));
701 AssertConnectSucceeds();
703 Run(1); // SpdySession consumes the next read and sends it to
704 // sock_ to be buffered.
705 AssertSyncReadEquals(kMsg1, kLen1);
708 TEST_F(SpdyProxyClientSocketSpdy3Test, ReadDataFromBufferedFrames) {
709 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
710 MockWrite writes[] = {
711 CreateMockWrite(*conn, 0, SYNCHRONOUS),
714 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
715 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
716 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
717 MockRead reads[] = {
718 CreateMockRead(*resp, 1, ASYNC),
719 CreateMockRead(*msg1, 2, ASYNC),
720 CreateMockRead(*msg2, 3, ASYNC),
721 MockRead(ASYNC, 0, 4), // EOF
724 Initialize(reads, arraysize(reads), writes, arraysize(writes));
726 AssertConnectSucceeds();
728 Run(1); // SpdySession consumes the next read and sends it to
729 // sock_ to be buffered.
730 AssertSyncReadEquals(kMsg1, kLen1);
731 Run(1); // SpdySession consumes the next read and sends it to
732 // sock_ to be buffered.
733 AssertSyncReadEquals(kMsg2, kLen2);
736 TEST_F(SpdyProxyClientSocketSpdy3Test, ReadDataMultipleBufferedFrames) {
737 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
738 MockWrite writes[] = {
739 CreateMockWrite(*conn, 0, SYNCHRONOUS),
742 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
743 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
744 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
745 MockRead reads[] = {
746 CreateMockRead(*resp, 1, ASYNC),
747 CreateMockRead(*msg1, 2, ASYNC),
748 CreateMockRead(*msg2, 3, ASYNC),
749 MockRead(ASYNC, 0, 4), // EOF
752 Initialize(reads, arraysize(reads), writes, arraysize(writes));
754 AssertConnectSucceeds();
756 Run(2); // SpdySession consumes the next two reads and sends then to
757 // sock_ to be buffered.
758 AssertSyncReadEquals(kMsg1, kLen1);
759 AssertSyncReadEquals(kMsg2, kLen2);
762 TEST_F(SpdyProxyClientSocketSpdy3Test,
763 LargeReadWillMergeDataFromDifferentFrames) {
764 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
765 MockWrite writes[] = {
766 CreateMockWrite(*conn, 0, SYNCHRONOUS),
769 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
770 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
771 scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
772 MockRead reads[] = {
773 CreateMockRead(*resp, 1, ASYNC),
774 CreateMockRead(*msg3, 2, ASYNC),
775 CreateMockRead(*msg3, 3, ASYNC),
776 MockRead(ASYNC, 0, 4), // EOF
779 Initialize(reads, arraysize(reads), writes, arraysize(writes));
781 AssertConnectSucceeds();
783 Run(2); // SpdySession consumes the next two reads and sends then to
784 // sock_ to be buffered.
785 // The payload from two data frames, each with kMsg3 will be combined
786 // together into a single read().
787 AssertSyncReadEquals(kMsg33, kLen33);
790 TEST_F(SpdyProxyClientSocketSpdy3Test, MultipleShortReadsThenMoreRead) {
791 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
792 MockWrite writes[] = {
793 CreateMockWrite(*conn, 0, SYNCHRONOUS),
796 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
797 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
798 scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
799 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
800 MockRead reads[] = {
801 CreateMockRead(*resp, 1, ASYNC),
802 CreateMockRead(*msg1, 2, ASYNC),
803 CreateMockRead(*msg3, 3, ASYNC),
804 CreateMockRead(*msg3, 4, ASYNC),
805 CreateMockRead(*msg2, 5, ASYNC),
806 MockRead(ASYNC, 0, 6), // EOF
809 Initialize(reads, arraysize(reads), writes, arraysize(writes));
811 AssertConnectSucceeds();
813 Run(4); // SpdySession consumes the next four reads and sends then to
814 // sock_ to be buffered.
815 AssertSyncReadEquals(kMsg1, kLen1);
816 // The payload from two data frames, each with kMsg3 will be combined
817 // together into a single read().
818 AssertSyncReadEquals(kMsg33, kLen33);
819 AssertSyncReadEquals(kMsg2, kLen2);
822 TEST_F(SpdyProxyClientSocketSpdy3Test, ReadWillSplitDataFromLargeFrame) {
823 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
824 MockWrite writes[] = {
825 CreateMockWrite(*conn, 0, SYNCHRONOUS),
828 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
829 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
830 scoped_ptr<SpdyFrame> msg33(ConstructBodyFrame(kMsg33, kLen33));
831 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
832 MockRead reads[] = {
833 CreateMockRead(*resp, 1, ASYNC),
834 CreateMockRead(*msg1, 2, ASYNC),
835 CreateMockRead(*msg33, 3, ASYNC),
836 MockRead(ASYNC, 0, 4), // EOF
839 Initialize(reads, arraysize(reads), writes, arraysize(writes));
841 AssertConnectSucceeds();
843 Run(2); // SpdySession consumes the next two reads and sends then to
844 // sock_ to be buffered.
845 AssertSyncReadEquals(kMsg1, kLen1);
846 // The payload from the single large data frame will be read across
847 // two different reads.
848 AssertSyncReadEquals(kMsg3, kLen3);
849 AssertSyncReadEquals(kMsg3, kLen3);
852 TEST_F(SpdyProxyClientSocketSpdy3Test, MultipleReadsFromSameLargeFrame) {
853 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
854 MockWrite writes[] = {
855 CreateMockWrite(*conn, 0, SYNCHRONOUS),
858 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
859 scoped_ptr<SpdyFrame> msg333(ConstructBodyFrame(kMsg333, kLen333));
860 MockRead reads[] = {
861 CreateMockRead(*resp, 1, ASYNC),
862 CreateMockRead(*msg333, 2, ASYNC),
863 MockRead(ASYNC, 0, 3), // EOF
866 Initialize(reads, arraysize(reads), writes, arraysize(writes));
868 AssertConnectSucceeds();
870 Run(1); // SpdySession consumes the next read and sends it to
871 // sock_ to be buffered.
872 // The payload from the single large data frame will be read across
873 // two different reads.
874 AssertSyncReadEquals(kMsg33, kLen33);
876 // Now attempt to do a read of more data than remains buffered
877 scoped_refptr<IOBuffer> buf(new IOBuffer(kLen33));
878 ASSERT_EQ(kLen3, sock_->Read(buf, kLen33, read_callback_.callback()));
879 ASSERT_EQ(std::string(kMsg3, kLen3), std::string(buf->data(), kLen3));
880 ASSERT_TRUE(sock_->IsConnected());
883 TEST_F(SpdyProxyClientSocketSpdy3Test, ReadAuthResponseBody) {
884 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
885 MockWrite writes[] = {
886 CreateMockWrite(*conn, 0, SYNCHRONOUS),
889 scoped_ptr<SpdyFrame> resp(ConstructConnectAuthReplyFrame());
890 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
891 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
892 MockRead reads[] = {
893 CreateMockRead(*resp, 1, ASYNC),
894 CreateMockRead(*msg1, 2, ASYNC),
895 CreateMockRead(*msg2, 3, ASYNC),
896 MockRead(ASYNC, 0, 4), // EOF
899 Initialize(reads, arraysize(reads), writes, arraysize(writes));
901 AssertConnectFails(ERR_PROXY_AUTH_REQUESTED);
903 Run(2); // SpdySession consumes the next two reads and sends then to
904 // sock_ to be buffered.
905 AssertSyncReadEquals(kMsg1, kLen1);
906 AssertSyncReadEquals(kMsg2, kLen2);
909 TEST_F(SpdyProxyClientSocketSpdy3Test, ReadErrorResponseBody) {
910 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
911 MockWrite writes[] = {
912 CreateMockWrite(*conn, 0, SYNCHRONOUS),
915 scoped_ptr<SpdyFrame> resp(ConstructConnectErrorReplyFrame());
916 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
917 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
918 MockRead reads[] = {
919 CreateMockRead(*resp, 1, ASYNC),
920 CreateMockRead(*msg1, 2, ASYNC),
921 CreateMockRead(*msg2, 3, ASYNC),
922 MockRead(ASYNC, 0, 4), // EOF
925 Initialize(reads, arraysize(reads), writes, arraysize(writes));
927 AssertConnectFails(ERR_TUNNEL_CONNECTION_FAILED);
930 // ----------- Reads and Writes
932 TEST_F(SpdyProxyClientSocketSpdy3Test, AsyncReadAroundWrite) {
933 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
934 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
935 MockWrite writes[] = {
936 CreateMockWrite(*conn, 0, SYNCHRONOUS),
937 CreateMockWrite(*msg2, 3, SYNCHRONOUS),
940 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
941 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
942 scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
943 MockRead reads[] = {
944 CreateMockRead(*resp, 1, ASYNC),
945 CreateMockRead(*msg1, 2, ASYNC), // sync read
946 CreateMockRead(*msg3, 4, ASYNC), // async read
947 MockRead(ASYNC, 0, 5), // EOF
950 Initialize(reads, arraysize(reads), writes, arraysize(writes));
952 AssertConnectSucceeds();
954 Run(1);
955 AssertSyncReadEquals(kMsg1, kLen1);
957 AssertReadStarts(kMsg3, kLen3);
958 // Read should block until after the write succeeds
960 AssertAsyncWriteSucceeds(kMsg2, kLen2); // Runs 1 step
962 ASSERT_FALSE(read_callback_.have_result());
963 Run(1);
964 // Now the read will return
965 AssertReadReturns(kMsg3, kLen3);
968 TEST_F(SpdyProxyClientSocketSpdy3Test, AsyncWriteAroundReads) {
969 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
970 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
971 MockWrite writes[] = {
972 CreateMockWrite(*conn, 0, SYNCHRONOUS),
973 CreateMockWrite(*msg2, 4, ASYNC),
976 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
977 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
978 scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
979 MockRead reads[] = {
980 CreateMockRead(*resp, 1, ASYNC),
981 CreateMockRead(*msg1, 2, ASYNC),
982 CreateMockRead(*msg3, 3, ASYNC),
983 MockRead(ASYNC, 0, 5), // EOF
986 Initialize(reads, arraysize(reads), writes, arraysize(writes));
988 AssertConnectSucceeds();
990 Run(1);
991 AssertSyncReadEquals(kMsg1, kLen1);
992 // Write should block until the read completes
993 AssertWriteReturns(kMsg2, kLen2, ERR_IO_PENDING);
995 AssertAsyncReadEquals(kMsg3, kLen3);
997 ASSERT_FALSE(write_callback_.have_result());
999 // Now the write will complete
1000 Run(1);
1001 AssertWriteLength(kLen2);
1004 // ----------- Reading/Writing on Closed socket
1006 // Reading from an already closed socket should return 0
1007 TEST_F(SpdyProxyClientSocketSpdy3Test, ReadOnClosedSocketReturnsZero) {
1008 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1009 MockWrite writes[] = {
1010 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1013 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1014 MockRead reads[] = {
1015 CreateMockRead(*resp, 1, ASYNC),
1016 MockRead(ASYNC, 0, 2), // EOF
1019 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1021 AssertConnectSucceeds();
1023 Run(1);
1025 ASSERT_FALSE(sock_->IsConnected());
1026 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
1027 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
1028 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
1029 ASSERT_FALSE(sock_->IsConnectedAndIdle());
1032 // Read pending when socket is closed should return 0
1033 TEST_F(SpdyProxyClientSocketSpdy3Test, PendingReadOnCloseReturnsZero) {
1034 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1035 MockWrite writes[] = {
1036 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1039 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1040 MockRead reads[] = {
1041 CreateMockRead(*resp, 1, ASYNC),
1042 MockRead(ASYNC, 0, 2), // EOF
1045 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1047 AssertConnectSucceeds();
1049 AssertReadStarts(kMsg1, kLen1);
1051 Run(1);
1053 ASSERT_EQ(0, read_callback_.WaitForResult());
1056 // Reading from a disconnected socket is an error
1057 TEST_F(SpdyProxyClientSocketSpdy3Test,
1058 ReadOnDisconnectSocketReturnsNotConnected) {
1059 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1060 MockWrite writes[] = {
1061 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1064 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1065 MockRead reads[] = {
1066 CreateMockRead(*resp, 1, ASYNC),
1067 MockRead(ASYNC, 0, 2), // EOF
1070 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1072 AssertConnectSucceeds();
1074 sock_->Disconnect();
1076 ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED,
1077 sock_->Read(NULL, 1, CompletionCallback()));
1080 // Reading buffered data from an already closed socket should return
1081 // buffered data, then 0.
1082 TEST_F(SpdyProxyClientSocketSpdy3Test, ReadOnClosedSocketReturnsBufferedData) {
1083 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1084 MockWrite writes[] = {
1085 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1088 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1089 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
1090 MockRead reads[] = {
1091 CreateMockRead(*resp, 1, ASYNC),
1092 CreateMockRead(*msg1, 2, ASYNC),
1093 MockRead(ASYNC, 0, 3), // EOF
1096 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1098 AssertConnectSucceeds();
1100 Run(2);
1102 ASSERT_FALSE(sock_->IsConnected());
1103 scoped_refptr<IOBuffer> buf(new IOBuffer(kLen1));
1104 ASSERT_EQ(kLen1, sock_->Read(buf, kLen1, CompletionCallback()));
1105 ASSERT_EQ(std::string(kMsg1, kLen1), std::string(buf->data(), kLen1));
1107 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
1108 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
1109 sock_->Disconnect();
1110 ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED,
1111 sock_->Read(NULL, 1, CompletionCallback()));
1114 // Calling Write() on a closed socket is an error
1115 TEST_F(SpdyProxyClientSocketSpdy3Test, WriteOnClosedStream) {
1116 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1117 MockWrite writes[] = {
1118 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1121 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1122 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
1123 MockRead reads[] = {
1124 CreateMockRead(*resp, 1, ASYNC),
1125 MockRead(ASYNC, 0, 2), // EOF
1128 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1130 AssertConnectSucceeds();
1132 Run(1); // Read EOF which will close the stream
1133 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
1134 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED,
1135 sock_->Write(buf, buf->size(), CompletionCallback()));
1138 // Calling Write() on a disconnected socket is an error
1139 TEST_F(SpdyProxyClientSocketSpdy3Test, WriteOnDisconnectedSocket) {
1140 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1141 MockWrite writes[] = {
1142 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1145 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1146 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
1147 MockRead reads[] = {
1148 CreateMockRead(*resp, 1, ASYNC),
1149 MockRead(ASYNC, 0, 2), // EOF
1152 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1154 AssertConnectSucceeds();
1156 sock_->Disconnect();
1158 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
1159 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED,
1160 sock_->Write(buf, buf->size(), CompletionCallback()));
1163 // If the socket is closed with a pending Write(), the callback
1164 // should be called with ERR_CONNECTION_CLOSED.
1165 TEST_F(SpdyProxyClientSocketSpdy3Test, WritePendingOnClose) {
1166 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1167 MockWrite writes[] = {
1168 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1169 MockWrite(ASYNC, ERR_IO_PENDING, 2),
1172 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1173 MockRead reads[] = {
1174 CreateMockRead(*resp, 1, ASYNC),
1175 MockRead(ASYNC, 0, 3), // EOF
1178 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1180 AssertConnectSucceeds();
1182 EXPECT_TRUE(sock_->IsConnected());
1184 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
1185 EXPECT_EQ(ERR_IO_PENDING,
1186 sock_->Write(buf, buf->size(), write_callback_.callback()));
1188 Run(1);
1190 EXPECT_EQ(ERR_CONNECTION_CLOSED, write_callback_.WaitForResult());
1193 // If the socket is Disconnected with a pending Write(), the callback
1194 // should not be called.
1195 TEST_F(SpdyProxyClientSocketSpdy3Test, DisconnectWithWritePending) {
1196 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1197 MockWrite writes[] = {
1198 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1199 MockWrite(SYNCHRONOUS, 0, 2), // EOF
1202 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1203 MockRead reads[] = {
1204 CreateMockRead(*resp, 1, ASYNC),
1205 MockRead(ASYNC, 0, 3), // EOF
1208 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1210 AssertConnectSucceeds();
1212 EXPECT_TRUE(sock_->IsConnected());
1214 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
1215 EXPECT_EQ(ERR_IO_PENDING,
1216 sock_->Write(buf, buf->size(), write_callback_.callback()));
1218 sock_->Disconnect();
1220 EXPECT_FALSE(sock_->IsConnected());
1221 EXPECT_FALSE(write_callback_.have_result());
1224 // If the socket is Disconnected with a pending Read(), the callback
1225 // should not be called.
1226 TEST_F(SpdyProxyClientSocketSpdy3Test, DisconnectWithReadPending) {
1227 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1228 MockWrite writes[] = {
1229 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1232 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1233 MockRead reads[] = {
1234 CreateMockRead(*resp, 1, ASYNC),
1235 MockRead(ASYNC, 0, 2), // EOF
1238 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1240 AssertConnectSucceeds();
1242 EXPECT_TRUE(sock_->IsConnected());
1244 scoped_refptr<IOBuffer> buf(new IOBuffer(kLen1));
1245 ASSERT_EQ(ERR_IO_PENDING,
1246 sock_->Read(buf, kLen1, read_callback_.callback()));
1248 sock_->Disconnect();
1250 EXPECT_FALSE(sock_->IsConnected());
1251 EXPECT_FALSE(read_callback_.have_result());
1254 // If the socket is Reset when both a read and write are pending,
1255 // both should be called back.
1256 TEST_F(SpdyProxyClientSocketSpdy3Test, RstWithReadAndWritePending) {
1257 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1258 MockWrite writes[] = {
1259 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1260 MockWrite(ASYNC, ERR_IO_PENDING, 2),
1263 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1264 scoped_ptr<SpdyFrame> rst(ConstructSpdyRstStream(1, CANCEL));
1265 MockRead reads[] = {
1266 CreateMockRead(*resp, 1, ASYNC),
1267 CreateMockRead(*rst, 3, ASYNC),
1270 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1272 AssertConnectSucceeds();
1274 EXPECT_TRUE(sock_->IsConnected());
1276 scoped_refptr<IOBuffer> read_buf(new IOBuffer(kLen1));
1277 ASSERT_EQ(ERR_IO_PENDING,
1278 sock_->Read(read_buf, kLen1, read_callback_.callback()));
1280 scoped_refptr<IOBufferWithSize> write_buf(CreateBuffer(kMsg1, kLen1));
1281 EXPECT_EQ(ERR_IO_PENDING,
1282 sock_->Write(write_buf, write_buf->size(),
1283 write_callback_.callback()));
1285 Run(2);
1287 EXPECT_TRUE(sock_.get());
1288 EXPECT_TRUE(read_callback_.have_result());
1289 EXPECT_TRUE(write_callback_.have_result());
1292 // CompletionCallback that causes the SpdyProxyClientSocket to be
1293 // deleted when Run is invoked.
1294 class DeleteSockCallback : public TestCompletionCallbackBase {
1295 public:
1296 explicit DeleteSockCallback(scoped_ptr<SpdyProxyClientSocket>* sock)
1297 : sock_(sock),
1298 ALLOW_THIS_IN_INITIALIZER_LIST(callback_(
1299 base::Bind(&DeleteSockCallback::OnComplete,
1300 base::Unretained(this)))) {
1303 virtual ~DeleteSockCallback() {
1306 const CompletionCallback& callback() const { return callback_; }
1308 private:
1309 void OnComplete(int result) {
1310 sock_->reset(NULL);
1311 SetResult(result);
1314 scoped_ptr<SpdyProxyClientSocket>* sock_;
1315 CompletionCallback callback_;
1317 DISALLOW_COPY_AND_ASSIGN(DeleteSockCallback);
1320 // If the socket is Reset when both a read and write are pending, and the
1321 // read callback causes the socket to be deleted, the write callback should
1322 // not be called.
1323 TEST_F(SpdyProxyClientSocketSpdy3Test, RstWithReadAndWritePendingDelete) {
1324 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1325 MockWrite writes[] = {
1326 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1327 MockWrite(ASYNC, ERR_IO_PENDING, 2),
1330 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1331 scoped_ptr<SpdyFrame> rst(ConstructSpdyRstStream(1, CANCEL));
1332 MockRead reads[] = {
1333 CreateMockRead(*resp, 1, ASYNC),
1334 CreateMockRead(*rst, 3, ASYNC),
1337 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1339 AssertConnectSucceeds();
1341 EXPECT_TRUE(sock_->IsConnected());
1343 DeleteSockCallback read_callback(&sock_);
1345 scoped_refptr<IOBuffer> read_buf(new IOBuffer(kLen1));
1346 ASSERT_EQ(ERR_IO_PENDING,
1347 sock_->Read(read_buf, kLen1, read_callback.callback()));
1349 scoped_refptr<IOBufferWithSize> write_buf(CreateBuffer(kMsg1, kLen1));
1350 EXPECT_EQ(ERR_IO_PENDING, sock_->Write(write_buf, write_buf->size(),
1351 write_callback_.callback()));
1353 Run(2);
1355 EXPECT_FALSE(sock_.get());
1356 EXPECT_TRUE(read_callback.have_result());
1357 EXPECT_FALSE(write_callback_.have_result());
1360 } // namespace net