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"
8 #include "base/bind_helpers.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "net/base/address_list.h"
11 #include "net/base/capturing_net_log.h"
12 #include "net/base/net_log.h"
13 #include "net/base/net_log_unittest.h"
14 #include "net/base/test_completion_callback.h"
15 #include "net/base/winsock_init.h"
16 #include "net/dns/mock_host_resolver.h"
17 #include "net/http/http_response_headers.h"
18 #include "net/http/http_response_info.h"
19 #include "net/socket/client_socket_factory.h"
20 #include "net/socket/next_proto.h"
21 #include "net/socket/socket_test_util.h"
22 #include "net/socket/tcp_client_socket.h"
23 #include "net/spdy/buffered_spdy_framer.h"
24 #include "net/spdy/spdy_http_utils.h"
25 #include "net/spdy/spdy_protocol.h"
26 #include "net/spdy/spdy_session_pool.h"
27 #include "net/spdy/spdy_test_util_common.h"
28 #include "testing/gtest/include/gtest/gtest.h"
29 #include "testing/platform_test.h"
31 //-----------------------------------------------------------------------------
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
63 class SpdyProxyClientSocketTest
64 : public PlatformTest
,
65 public testing::WithParamInterface
<NextProto
> {
67 SpdyProxyClientSocketTest();
69 virtual void TearDown();
72 void Initialize(MockRead
* reads
, size_t reads_count
, MockWrite
* writes
,
74 SpdyFrame
* ConstructConnectRequestFrame();
75 SpdyFrame
* ConstructConnectAuthRequestFrame();
76 SpdyFrame
* ConstructConnectReplyFrame();
77 SpdyFrame
* ConstructConnectAuthReplyFrame();
78 SpdyFrame
* ConstructConnectRedirectReplyFrame();
79 SpdyFrame
* ConstructConnectErrorReplyFrame();
80 SpdyFrame
* ConstructBodyFrame(const char* data
, int length
);
81 scoped_refptr
<IOBufferWithSize
> CreateBuffer(const char* data
, int size
);
82 void AssertConnectSucceeds();
83 void AssertConnectFails(int result
);
84 void AssertConnectionEstablished();
85 void AssertSyncReadEquals(const char* data
, int len
);
86 void AssertAsyncReadEquals(const char* data
, int len
);
87 void AssertReadStarts(const char* data
, int len
);
88 void AssertReadReturns(const char* data
, int len
);
89 void AssertAsyncWriteSucceeds(const char* data
, int len
);
90 void AssertWriteReturns(const char* data
, int len
, int rv
);
91 void AssertWriteLength(int len
);
92 void AssertAsyncWriteWithReadsSucceeds(const char* data
, int len
,
95 void AddAuthToCache() {
96 const base::string16
kFoo(base::ASCIIToUTF16("foo"));
97 const base::string16
kBar(base::ASCIIToUTF16("bar"));
98 session_
->http_auth_cache()->Add(GURL(kProxyUrl
),
100 HttpAuth::AUTH_SCHEME_BASIC
,
101 "Basic realm=MyRealm1",
102 AuthCredentials(kFoo
, kBar
),
106 void Run(int steps
) {
107 data_
->StopAfter(steps
);
111 void CloseSpdySession(net::Error error
, const std::string
& description
) {
112 spdy_session_
->CloseSessionOnError(error
, description
);
115 SpdyTestUtil spdy_util_
;
116 scoped_ptr
<SpdyProxyClientSocket
> sock_
;
117 TestCompletionCallback read_callback_
;
118 TestCompletionCallback write_callback_
;
119 scoped_ptr
<DeterministicSocketData
> data_
;
120 CapturingBoundNetLog net_log_
;
123 scoped_refptr
<HttpNetworkSession
> session_
;
124 scoped_refptr
<IOBuffer
> read_buf_
;
125 SpdySessionDependencies session_deps_
;
126 MockConnect connect_data_
;
127 base::WeakPtr
<SpdySession
> spdy_session_
;
128 BufferedSpdyFramer framer_
;
130 std::string user_agent_
;
132 HostPortPair proxy_host_port_
;
133 HostPortPair endpoint_host_port_pair_
;
135 SpdySessionKey endpoint_spdy_session_key_
;
137 DISALLOW_COPY_AND_ASSIGN(SpdyProxyClientSocketTest
);
140 INSTANTIATE_TEST_CASE_P(
142 SpdyProxyClientSocketTest
,
143 testing::Values(kProtoDeprecatedSPDY2
,
144 kProtoSPDY3
, kProtoSPDY31
, kProtoSPDY4a2
,
145 kProtoHTTP2Draft04
));
147 SpdyProxyClientSocketTest::SpdyProxyClientSocketTest()
148 : spdy_util_(GetParam()),
151 session_deps_(GetParam()),
152 connect_data_(SYNCHRONOUS
, OK
),
153 framer_(spdy_util_
.spdy_version(), false),
154 user_agent_(kUserAgent
),
156 proxy_host_port_(kProxyHost
, kProxyPort
),
157 endpoint_host_port_pair_(kOriginHost
, kOriginPort
),
158 proxy_(ProxyServer::SCHEME_HTTPS
, proxy_host_port_
),
159 endpoint_spdy_session_key_(endpoint_host_port_pair_
,
161 kPrivacyModeDisabled
) {
162 session_deps_
.net_log
= net_log_
.bound().net_log();
165 void SpdyProxyClientSocketTest::TearDown() {
167 if (session_
.get() != NULL
)
168 session_
->spdy_session_pool()->CloseAllSessions();
170 // Empty the current queue.
171 base::MessageLoop::current()->RunUntilIdle();
172 PlatformTest::TearDown();
175 void SpdyProxyClientSocketTest::Initialize(MockRead
* reads
,
178 size_t writes_count
) {
179 data_
.reset(new DeterministicSocketData(reads
, reads_count
,
180 writes
, writes_count
));
181 data_
->set_connect_data(connect_data_
);
184 session_deps_
.deterministic_socket_factory
->AddSocketDataProvider(
186 session_deps_
.host_resolver
->set_synchronous_mode(true);
188 session_
= SpdySessionDependencies::SpdyCreateSessionDeterministic(
191 // Creates the SPDY session and stream.
193 CreateInsecureSpdySession(
194 session_
, endpoint_spdy_session_key_
, BoundNetLog());
195 base::WeakPtr
<SpdyStream
> spdy_stream(
196 CreateStreamSynchronously(
197 SPDY_BIDIRECTIONAL_STREAM
, spdy_session_
, url_
, LOWEST
,
199 ASSERT_TRUE(spdy_stream
.get() != NULL
);
201 // Create the SpdyProxyClientSocket.
203 new SpdyProxyClientSocket(spdy_stream
, user_agent_
,
204 endpoint_host_port_pair_
, url_
,
205 proxy_host_port_
, net_log_
.bound(),
206 session_
->http_auth_cache(),
207 session_
->http_auth_handler_factory()));
210 scoped_refptr
<IOBufferWithSize
> SpdyProxyClientSocketTest::CreateBuffer(
211 const char* data
, int size
) {
212 scoped_refptr
<IOBufferWithSize
> buf(new IOBufferWithSize(size
));
213 memcpy(buf
->data(), data
, size
);
217 void SpdyProxyClientSocketTest::AssertConnectSucceeds() {
218 ASSERT_EQ(ERR_IO_PENDING
, sock_
->Connect(read_callback_
.callback()));
220 ASSERT_EQ(OK
, read_callback_
.WaitForResult());
223 void SpdyProxyClientSocketTest::AssertConnectFails(int result
) {
224 ASSERT_EQ(ERR_IO_PENDING
, sock_
->Connect(read_callback_
.callback()));
226 ASSERT_EQ(result
, read_callback_
.WaitForResult());
229 void SpdyProxyClientSocketTest::AssertConnectionEstablished() {
230 const HttpResponseInfo
* response
= sock_
->GetConnectResponseInfo();
231 ASSERT_TRUE(response
!= NULL
);
232 ASSERT_EQ(200, response
->headers
->response_code());
233 ASSERT_EQ("Connection Established", response
->headers
->GetStatusText());
236 void SpdyProxyClientSocketTest::AssertSyncReadEquals(const char* data
,
238 scoped_refptr
<IOBuffer
> buf(new IOBuffer(len
));
239 ASSERT_EQ(len
, sock_
->Read(buf
.get(), len
, CompletionCallback()));
240 ASSERT_EQ(std::string(data
, len
), std::string(buf
->data(), len
));
241 ASSERT_TRUE(sock_
->IsConnected());
244 void SpdyProxyClientSocketTest::AssertAsyncReadEquals(const char* data
,
247 // Issue the read, which will be completed asynchronously
248 scoped_refptr
<IOBuffer
> buf(new IOBuffer(len
));
249 ASSERT_EQ(ERR_IO_PENDING
,
250 sock_
->Read(buf
.get(), len
, read_callback_
.callback()));
251 EXPECT_TRUE(sock_
->IsConnected());
254 EXPECT_TRUE(sock_
->IsConnected());
256 // Now the read will return
257 EXPECT_EQ(len
, read_callback_
.WaitForResult());
258 ASSERT_EQ(std::string(data
, len
), std::string(buf
->data(), len
));
261 void SpdyProxyClientSocketTest::AssertReadStarts(const char* data
,
264 // Issue the read, which will be completed asynchronously
265 read_buf_
= new IOBuffer(len
);
266 ASSERT_EQ(ERR_IO_PENDING
,
267 sock_
->Read(read_buf_
.get(), len
, read_callback_
.callback()));
268 EXPECT_TRUE(sock_
->IsConnected());
271 void SpdyProxyClientSocketTest::AssertReadReturns(const char* data
,
273 EXPECT_TRUE(sock_
->IsConnected());
275 // Now the read will return
276 EXPECT_EQ(len
, read_callback_
.WaitForResult());
277 ASSERT_EQ(std::string(data
, len
), std::string(read_buf_
->data(), len
));
280 void SpdyProxyClientSocketTest::AssertAsyncWriteSucceeds(const char* data
,
282 AssertWriteReturns(data
, len
, ERR_IO_PENDING
);
284 AssertWriteLength(len
);
287 void SpdyProxyClientSocketTest::AssertWriteReturns(const char* data
,
290 scoped_refptr
<IOBufferWithSize
> buf(CreateBuffer(data
, len
));
292 sock_
->Write(buf
.get(), buf
->size(), write_callback_
.callback()));
295 void SpdyProxyClientSocketTest::AssertWriteLength(int len
) {
296 EXPECT_EQ(len
, write_callback_
.WaitForResult());
299 void SpdyProxyClientSocketTest::AssertAsyncWriteWithReadsSucceeds(
300 const char* data
, int len
, int num_reads
) {
301 scoped_refptr
<IOBufferWithSize
> buf(CreateBuffer(data
, len
));
303 EXPECT_EQ(ERR_IO_PENDING
,
304 sock_
->Write(buf
.get(), buf
->size(), write_callback_
.callback()));
306 for (int i
= 0; i
< num_reads
; i
++) {
308 AssertSyncReadEquals(kMsg2
, kLen2
);
311 write_callback_
.WaitForResult();
314 // Constructs a standard SPDY SYN_STREAM frame for a CONNECT request.
316 SpdyProxyClientSocketTest::ConstructConnectRequestFrame() {
317 const SpdyHeaderInfo kSynStartHeader
= {
321 net::ConvertRequestPriorityToSpdyPriority(
322 LOWEST
, spdy_util_
.spdy_version()),
331 bool spdy2
= spdy_util_
.is_spdy2();
332 const char* const kConnectHeaders
[] = {
333 spdy2
? "method" : ":method", "CONNECT",
334 spdy2
? "url" : ":path", kOriginHostPort
,
335 spdy2
? "host" : ":host", kOriginHost
,
336 "user-agent", kUserAgent
,
337 spdy2
? "version" : ":version", "HTTP/1.1",
339 return spdy_util_
.ConstructSpdyFrame(
340 kSynStartHeader
, NULL
, 0, kConnectHeaders
, arraysize(kConnectHeaders
)/2);
343 // Constructs a SPDY SYN_STREAM frame for a CONNECT request which includes
344 // Proxy-Authorization headers.
346 SpdyProxyClientSocketTest::ConstructConnectAuthRequestFrame() {
347 const SpdyHeaderInfo kSynStartHeader
= {
351 net::ConvertRequestPriorityToSpdyPriority(
352 LOWEST
, spdy_util_
.spdy_version()),
361 bool spdy2
= spdy_util_
.is_spdy2();
362 const char* const kConnectHeaders
[] = {
363 spdy2
? "method" : ":method", "CONNECT",
364 spdy2
? "url" : ":path", kOriginHostPort
,
365 spdy2
? "host" : ":host", kOriginHost
,
366 "user-agent", kUserAgent
,
367 spdy2
? "version" : ":version", "HTTP/1.1",
368 "proxy-authorization", "Basic Zm9vOmJhcg==",
370 return spdy_util_
.ConstructSpdyFrame(
371 kSynStartHeader
, NULL
, 0, kConnectHeaders
, arraysize(kConnectHeaders
)/2);
374 // Constructs a standard SPDY SYN_REPLY frame to match the SPDY CONNECT.
375 SpdyFrame
* SpdyProxyClientSocketTest::ConstructConnectReplyFrame() {
376 bool spdy2
= spdy_util_
.is_spdy2();
377 const char* const kStandardReplyHeaders
[] = {
378 spdy2
? "status" : ":status", "200 Connection Established",
379 spdy2
? "version" : ":version", "HTTP/1.1"
381 return spdy_util_
.ConstructSpdyControlFrame(NULL
,
388 kStandardReplyHeaders
,
389 arraysize(kStandardReplyHeaders
),
393 // Constructs a standard SPDY SYN_REPLY frame to match the SPDY CONNECT.
395 SpdyProxyClientSocketTest::ConstructConnectAuthReplyFrame() {
396 bool spdy2
= spdy_util_
.is_spdy2();
398 const char* const kStandardReplyHeaders
[] = {
399 spdy2
? "status" : ":status", "407 Proxy Authentication Required",
400 spdy2
? "version" : ":version", "HTTP/1.1",
401 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
404 return spdy_util_
.ConstructSpdyControlFrame(NULL
,
411 kStandardReplyHeaders
,
412 arraysize(kStandardReplyHeaders
),
416 // Constructs a SPDY SYN_REPLY frame with an HTTP 302 redirect.
418 SpdyProxyClientSocketTest::ConstructConnectRedirectReplyFrame() {
419 bool spdy2
= spdy_util_
.is_spdy2();
421 const char* const kStandardReplyHeaders
[] = {
422 spdy2
? "status" : ":status", "302 Found",
423 spdy2
? "version" : ":version", "HTTP/1.1",
424 "location", kRedirectUrl
,
425 "set-cookie", "foo=bar"
428 return spdy_util_
.ConstructSpdyControlFrame(NULL
,
435 kStandardReplyHeaders
,
436 arraysize(kStandardReplyHeaders
),
440 // Constructs a SPDY SYN_REPLY frame with an HTTP 500 error.
442 SpdyProxyClientSocketTest::ConstructConnectErrorReplyFrame() {
443 bool spdy2
= spdy_util_
.is_spdy2();
445 const char* const kStandardReplyHeaders
[] = {
446 spdy2
? "status" : ":status", "500 Internal Server Error",
447 spdy2
? "version" : ":version", "HTTP/1.1",
450 return spdy_util_
.ConstructSpdyControlFrame(NULL
,
457 kStandardReplyHeaders
,
458 arraysize(kStandardReplyHeaders
),
462 SpdyFrame
* SpdyProxyClientSocketTest::ConstructBodyFrame(
465 return framer_
.CreateDataFrame(kStreamId
, data
, length
, DATA_FLAG_NONE
);
468 // ----------- Connect
470 TEST_P(SpdyProxyClientSocketTest
, ConnectSendsCorrectRequest
) {
471 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
472 MockWrite writes
[] = {
473 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
476 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
478 CreateMockRead(*resp
, 1, ASYNC
),
479 MockRead(ASYNC
, 0, 2), // EOF
482 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
484 ASSERT_FALSE(sock_
->IsConnected());
486 AssertConnectSucceeds();
488 AssertConnectionEstablished();
491 TEST_P(SpdyProxyClientSocketTest
, ConnectWithAuthRequested
) {
492 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
493 MockWrite writes
[] = {
494 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
497 scoped_ptr
<SpdyFrame
> resp(ConstructConnectAuthReplyFrame());
499 CreateMockRead(*resp
, 1, ASYNC
),
500 MockRead(ASYNC
, 0, 2), // EOF
503 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
505 AssertConnectFails(ERR_PROXY_AUTH_REQUESTED
);
507 const HttpResponseInfo
* response
= sock_
->GetConnectResponseInfo();
508 ASSERT_TRUE(response
!= NULL
);
509 ASSERT_EQ(407, response
->headers
->response_code());
510 ASSERT_EQ("Proxy Authentication Required",
511 response
->headers
->GetStatusText());
514 TEST_P(SpdyProxyClientSocketTest
, ConnectWithAuthCredentials
) {
515 scoped_ptr
<SpdyFrame
> conn(ConstructConnectAuthRequestFrame());
516 MockWrite writes
[] = {
517 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
520 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
522 CreateMockRead(*resp
, 1, ASYNC
),
523 MockRead(ASYNC
, 0, 2), // EOF
526 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
529 AssertConnectSucceeds();
531 AssertConnectionEstablished();
534 TEST_P(SpdyProxyClientSocketTest
, ConnectRedirects
) {
535 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
536 MockWrite writes
[] = {
537 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
540 scoped_ptr
<SpdyFrame
> resp(ConstructConnectRedirectReplyFrame());
542 CreateMockRead(*resp
, 1, ASYNC
),
543 MockRead(ASYNC
, 0, 2), // EOF
546 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
548 AssertConnectFails(ERR_HTTPS_PROXY_TUNNEL_RESPONSE
);
550 const HttpResponseInfo
* response
= sock_
->GetConnectResponseInfo();
551 ASSERT_TRUE(response
!= NULL
);
553 const HttpResponseHeaders
* headers
= response
->headers
.get();
554 ASSERT_EQ(302, headers
->response_code());
555 ASSERT_FALSE(headers
->HasHeader("set-cookie"));
556 ASSERT_TRUE(headers
->HasHeaderValue("content-length", "0"));
558 std::string location
;
559 ASSERT_TRUE(headers
->IsRedirect(&location
));
560 ASSERT_EQ(location
, kRedirectUrl
);
563 TEST_P(SpdyProxyClientSocketTest
, ConnectFails
) {
564 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
565 MockWrite writes
[] = {
566 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
569 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
571 MockRead(ASYNC
, 0, 1), // EOF
574 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
576 ASSERT_FALSE(sock_
->IsConnected());
578 AssertConnectFails(ERR_CONNECTION_CLOSED
);
580 ASSERT_FALSE(sock_
->IsConnected());
583 // ----------- WasEverUsed
585 TEST_P(SpdyProxyClientSocketTest
, WasEverUsedReturnsCorrectValues
) {
586 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
587 MockWrite writes
[] = {
588 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
591 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
593 CreateMockRead(*resp
, 1, ASYNC
),
594 MockRead(ASYNC
, 0, 2), // EOF
597 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
599 EXPECT_FALSE(sock_
->WasEverUsed());
600 AssertConnectSucceeds();
601 EXPECT_TRUE(sock_
->WasEverUsed());
603 EXPECT_TRUE(sock_
->WasEverUsed());
606 // ----------- GetPeerAddress
608 TEST_P(SpdyProxyClientSocketTest
, GetPeerAddressReturnsCorrectValues
) {
609 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
610 MockWrite writes
[] = {
611 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
614 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
616 CreateMockRead(*resp
, 1, ASYNC
),
617 MockRead(ASYNC
, 0, 2), // EOF
620 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
622 net::IPEndPoint addr
;
623 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED
, sock_
->GetPeerAddress(&addr
));
625 AssertConnectSucceeds();
626 EXPECT_TRUE(sock_
->IsConnected());
627 EXPECT_EQ(OK
, sock_
->GetPeerAddress(&addr
));
631 EXPECT_FALSE(sock_
->IsConnected());
632 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED
, sock_
->GetPeerAddress(&addr
));
636 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED
, sock_
->GetPeerAddress(&addr
));
641 TEST_P(SpdyProxyClientSocketTest
, WriteSendsDataInDataFrame
) {
642 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
643 scoped_ptr
<SpdyFrame
> msg1(ConstructBodyFrame(kMsg1
, kLen1
));
644 scoped_ptr
<SpdyFrame
> msg2(ConstructBodyFrame(kMsg2
, kLen2
));
645 MockWrite writes
[] = {
646 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
647 CreateMockWrite(*msg1
, 2, SYNCHRONOUS
),
648 CreateMockWrite(*msg2
, 3, SYNCHRONOUS
),
651 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
653 CreateMockRead(*resp
, 1, ASYNC
),
654 MockRead(ASYNC
, 0, 4), // EOF
657 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
659 AssertConnectSucceeds();
661 AssertAsyncWriteSucceeds(kMsg1
, kLen1
);
662 AssertAsyncWriteSucceeds(kMsg2
, kLen2
);
665 TEST_P(SpdyProxyClientSocketTest
, WriteSplitsLargeDataIntoMultipleFrames
) {
666 std::string
chunk_data(kMaxSpdyFrameChunkSize
, 'x');
667 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
668 scoped_ptr
<SpdyFrame
> chunk(ConstructBodyFrame(chunk_data
.data(),
669 chunk_data
.length()));
670 MockWrite writes
[] = {
671 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
672 CreateMockWrite(*chunk
, 2, SYNCHRONOUS
),
673 CreateMockWrite(*chunk
, 3, SYNCHRONOUS
),
674 CreateMockWrite(*chunk
, 4, SYNCHRONOUS
)
677 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
679 CreateMockRead(*resp
, 1, ASYNC
),
680 MockRead(ASYNC
, 0, 5), // EOF
683 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
685 AssertConnectSucceeds();
687 std::string
big_data(kMaxSpdyFrameChunkSize
* 3, 'x');
688 scoped_refptr
<IOBufferWithSize
> buf(CreateBuffer(big_data
.data(),
691 EXPECT_EQ(ERR_IO_PENDING
,
692 sock_
->Write(buf
.get(), buf
->size(), write_callback_
.callback()));
695 EXPECT_EQ(buf
->size(), write_callback_
.WaitForResult());
700 TEST_P(SpdyProxyClientSocketTest
, ReadReadsDataInDataFrame
) {
701 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
702 MockWrite writes
[] = {
703 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
706 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
707 scoped_ptr
<SpdyFrame
> msg1(ConstructBodyFrame(kMsg1
, kLen1
));
709 CreateMockRead(*resp
, 1, ASYNC
),
710 CreateMockRead(*msg1
, 2, ASYNC
),
711 MockRead(ASYNC
, 0, 3), // EOF
714 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
716 AssertConnectSucceeds();
718 Run(1); // SpdySession consumes the next read and sends it to
719 // sock_ to be buffered.
720 AssertSyncReadEquals(kMsg1
, kLen1
);
723 TEST_P(SpdyProxyClientSocketTest
, ReadDataFromBufferedFrames
) {
724 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
725 MockWrite writes
[] = {
726 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
729 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
730 scoped_ptr
<SpdyFrame
> msg1(ConstructBodyFrame(kMsg1
, kLen1
));
731 scoped_ptr
<SpdyFrame
> msg2(ConstructBodyFrame(kMsg2
, kLen2
));
733 CreateMockRead(*resp
, 1, ASYNC
),
734 CreateMockRead(*msg1
, 2, ASYNC
),
735 CreateMockRead(*msg2
, 3, ASYNC
),
736 MockRead(ASYNC
, 0, 4), // EOF
739 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
741 AssertConnectSucceeds();
743 Run(1); // SpdySession consumes the next read and sends it to
744 // sock_ to be buffered.
745 AssertSyncReadEquals(kMsg1
, kLen1
);
746 Run(1); // SpdySession consumes the next read and sends it to
747 // sock_ to be buffered.
748 AssertSyncReadEquals(kMsg2
, kLen2
);
751 TEST_P(SpdyProxyClientSocketTest
, ReadDataMultipleBufferedFrames
) {
752 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
753 MockWrite writes
[] = {
754 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
757 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
758 scoped_ptr
<SpdyFrame
> msg1(ConstructBodyFrame(kMsg1
, kLen1
));
759 scoped_ptr
<SpdyFrame
> msg2(ConstructBodyFrame(kMsg2
, kLen2
));
761 CreateMockRead(*resp
, 1, ASYNC
),
762 CreateMockRead(*msg1
, 2, ASYNC
),
763 CreateMockRead(*msg2
, 3, ASYNC
),
764 MockRead(ASYNC
, 0, 4), // EOF
767 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
769 AssertConnectSucceeds();
771 Run(2); // SpdySession consumes the next two reads and sends then to
772 // sock_ to be buffered.
773 AssertSyncReadEquals(kMsg1
, kLen1
);
774 AssertSyncReadEquals(kMsg2
, kLen2
);
777 TEST_P(SpdyProxyClientSocketTest
,
778 LargeReadWillMergeDataFromDifferentFrames
) {
779 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
780 MockWrite writes
[] = {
781 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
784 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
785 scoped_ptr
<SpdyFrame
> msg1(ConstructBodyFrame(kMsg1
, kLen1
));
786 scoped_ptr
<SpdyFrame
> msg3(ConstructBodyFrame(kMsg3
, kLen3
));
788 CreateMockRead(*resp
, 1, ASYNC
),
789 CreateMockRead(*msg3
, 2, ASYNC
),
790 CreateMockRead(*msg3
, 3, ASYNC
),
791 MockRead(ASYNC
, 0, 4), // EOF
794 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
796 AssertConnectSucceeds();
798 Run(2); // SpdySession consumes the next two reads and sends then to
799 // sock_ to be buffered.
800 // The payload from two data frames, each with kMsg3 will be combined
801 // together into a single read().
802 AssertSyncReadEquals(kMsg33
, kLen33
);
805 TEST_P(SpdyProxyClientSocketTest
, MultipleShortReadsThenMoreRead
) {
806 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
807 MockWrite writes
[] = {
808 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
811 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
812 scoped_ptr
<SpdyFrame
> msg1(ConstructBodyFrame(kMsg1
, kLen1
));
813 scoped_ptr
<SpdyFrame
> msg3(ConstructBodyFrame(kMsg3
, kLen3
));
814 scoped_ptr
<SpdyFrame
> msg2(ConstructBodyFrame(kMsg2
, kLen2
));
816 CreateMockRead(*resp
, 1, ASYNC
),
817 CreateMockRead(*msg1
, 2, ASYNC
),
818 CreateMockRead(*msg3
, 3, ASYNC
),
819 CreateMockRead(*msg3
, 4, ASYNC
),
820 CreateMockRead(*msg2
, 5, ASYNC
),
821 MockRead(ASYNC
, 0, 6), // EOF
824 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
826 AssertConnectSucceeds();
828 Run(4); // SpdySession consumes the next four reads and sends then to
829 // sock_ to be buffered.
830 AssertSyncReadEquals(kMsg1
, kLen1
);
831 // The payload from two data frames, each with kMsg3 will be combined
832 // together into a single read().
833 AssertSyncReadEquals(kMsg33
, kLen33
);
834 AssertSyncReadEquals(kMsg2
, kLen2
);
837 TEST_P(SpdyProxyClientSocketTest
, ReadWillSplitDataFromLargeFrame
) {
838 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
839 MockWrite writes
[] = {
840 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
843 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
844 scoped_ptr
<SpdyFrame
> msg1(ConstructBodyFrame(kMsg1
, kLen1
));
845 scoped_ptr
<SpdyFrame
> msg33(ConstructBodyFrame(kMsg33
, kLen33
));
846 scoped_ptr
<SpdyFrame
> msg2(ConstructBodyFrame(kMsg2
, kLen2
));
848 CreateMockRead(*resp
, 1, ASYNC
),
849 CreateMockRead(*msg1
, 2, ASYNC
),
850 CreateMockRead(*msg33
, 3, ASYNC
),
851 MockRead(ASYNC
, 0, 4), // EOF
854 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
856 AssertConnectSucceeds();
858 Run(2); // SpdySession consumes the next two reads and sends then to
859 // sock_ to be buffered.
860 AssertSyncReadEquals(kMsg1
, kLen1
);
861 // The payload from the single large data frame will be read across
862 // two different reads.
863 AssertSyncReadEquals(kMsg3
, kLen3
);
864 AssertSyncReadEquals(kMsg3
, kLen3
);
867 TEST_P(SpdyProxyClientSocketTest
, MultipleReadsFromSameLargeFrame
) {
868 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
869 MockWrite writes
[] = {
870 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
873 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
874 scoped_ptr
<SpdyFrame
> msg333(ConstructBodyFrame(kMsg333
, kLen333
));
876 CreateMockRead(*resp
, 1, ASYNC
),
877 CreateMockRead(*msg333
, 2, ASYNC
),
878 MockRead(ASYNC
, 0, 3), // EOF
881 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
883 AssertConnectSucceeds();
885 Run(1); // SpdySession consumes the next read and sends it to
886 // sock_ to be buffered.
887 // The payload from the single large data frame will be read across
888 // two different reads.
889 AssertSyncReadEquals(kMsg33
, kLen33
);
891 // Now attempt to do a read of more data than remains buffered
892 scoped_refptr
<IOBuffer
> buf(new IOBuffer(kLen33
));
893 ASSERT_EQ(kLen3
, sock_
->Read(buf
.get(), kLen33
, read_callback_
.callback()));
894 ASSERT_EQ(std::string(kMsg3
, kLen3
), std::string(buf
->data(), kLen3
));
895 ASSERT_TRUE(sock_
->IsConnected());
898 TEST_P(SpdyProxyClientSocketTest
, ReadAuthResponseBody
) {
899 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
900 MockWrite writes
[] = {
901 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
904 scoped_ptr
<SpdyFrame
> resp(ConstructConnectAuthReplyFrame());
905 scoped_ptr
<SpdyFrame
> msg1(ConstructBodyFrame(kMsg1
, kLen1
));
906 scoped_ptr
<SpdyFrame
> msg2(ConstructBodyFrame(kMsg2
, kLen2
));
908 CreateMockRead(*resp
, 1, ASYNC
),
909 CreateMockRead(*msg1
, 2, ASYNC
),
910 CreateMockRead(*msg2
, 3, ASYNC
),
911 MockRead(ASYNC
, 0, 4), // EOF
914 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
916 AssertConnectFails(ERR_PROXY_AUTH_REQUESTED
);
918 Run(2); // SpdySession consumes the next two reads and sends then to
919 // sock_ to be buffered.
920 AssertSyncReadEquals(kMsg1
, kLen1
);
921 AssertSyncReadEquals(kMsg2
, kLen2
);
924 TEST_P(SpdyProxyClientSocketTest
, ReadErrorResponseBody
) {
925 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
926 MockWrite writes
[] = {
927 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
930 scoped_ptr
<SpdyFrame
> resp(ConstructConnectErrorReplyFrame());
931 scoped_ptr
<SpdyFrame
> msg1(ConstructBodyFrame(kMsg1
, kLen1
));
932 scoped_ptr
<SpdyFrame
> msg2(ConstructBodyFrame(kMsg2
, kLen2
));
934 CreateMockRead(*resp
, 1, ASYNC
),
935 CreateMockRead(*msg1
, 2, ASYNC
),
936 CreateMockRead(*msg2
, 3, ASYNC
),
937 MockRead(ASYNC
, 0, 4), // EOF
940 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
942 AssertConnectFails(ERR_TUNNEL_CONNECTION_FAILED
);
945 // ----------- Reads and Writes
947 TEST_P(SpdyProxyClientSocketTest
, AsyncReadAroundWrite
) {
948 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
949 scoped_ptr
<SpdyFrame
> msg2(ConstructBodyFrame(kMsg2
, kLen2
));
950 MockWrite writes
[] = {
951 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
952 CreateMockWrite(*msg2
, 3, SYNCHRONOUS
),
955 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
956 scoped_ptr
<SpdyFrame
> msg1(ConstructBodyFrame(kMsg1
, kLen1
));
957 scoped_ptr
<SpdyFrame
> msg3(ConstructBodyFrame(kMsg3
, kLen3
));
959 CreateMockRead(*resp
, 1, ASYNC
),
960 CreateMockRead(*msg1
, 2, ASYNC
), // sync read
961 CreateMockRead(*msg3
, 4, ASYNC
), // async read
962 MockRead(ASYNC
, 0, 5), // EOF
965 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
967 AssertConnectSucceeds();
970 AssertSyncReadEquals(kMsg1
, kLen1
);
972 AssertReadStarts(kMsg3
, kLen3
);
973 // Read should block until after the write succeeds
975 AssertAsyncWriteSucceeds(kMsg2
, kLen2
); // Runs 1 step
977 ASSERT_FALSE(read_callback_
.have_result());
979 // Now the read will return
980 AssertReadReturns(kMsg3
, kLen3
);
983 TEST_P(SpdyProxyClientSocketTest
, AsyncWriteAroundReads
) {
984 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
985 scoped_ptr
<SpdyFrame
> msg2(ConstructBodyFrame(kMsg2
, kLen2
));
986 MockWrite writes
[] = {
987 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
988 CreateMockWrite(*msg2
, 4, ASYNC
),
991 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
992 scoped_ptr
<SpdyFrame
> msg1(ConstructBodyFrame(kMsg1
, kLen1
));
993 scoped_ptr
<SpdyFrame
> msg3(ConstructBodyFrame(kMsg3
, kLen3
));
995 CreateMockRead(*resp
, 1, ASYNC
),
996 CreateMockRead(*msg1
, 2, ASYNC
),
997 CreateMockRead(*msg3
, 3, ASYNC
),
998 MockRead(ASYNC
, 0, 5), // EOF
1001 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
1003 AssertConnectSucceeds();
1006 AssertSyncReadEquals(kMsg1
, kLen1
);
1007 // Write should block until the read completes
1008 AssertWriteReturns(kMsg2
, kLen2
, ERR_IO_PENDING
);
1010 AssertAsyncReadEquals(kMsg3
, kLen3
);
1012 ASSERT_FALSE(write_callback_
.have_result());
1014 // Now the write will complete
1016 AssertWriteLength(kLen2
);
1019 // ----------- Reading/Writing on Closed socket
1021 // Reading from an already closed socket should return 0
1022 TEST_P(SpdyProxyClientSocketTest
, ReadOnClosedSocketReturnsZero
) {
1023 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
1024 MockWrite writes
[] = {
1025 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
1028 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
1029 MockRead reads
[] = {
1030 CreateMockRead(*resp
, 1, ASYNC
),
1031 MockRead(ASYNC
, 0, 2), // EOF
1034 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
1036 AssertConnectSucceeds();
1040 ASSERT_FALSE(sock_
->IsConnected());
1041 ASSERT_EQ(0, sock_
->Read(NULL
, 1, CompletionCallback()));
1042 ASSERT_EQ(0, sock_
->Read(NULL
, 1, CompletionCallback()));
1043 ASSERT_EQ(0, sock_
->Read(NULL
, 1, CompletionCallback()));
1044 ASSERT_FALSE(sock_
->IsConnectedAndIdle());
1047 // Read pending when socket is closed should return 0
1048 TEST_P(SpdyProxyClientSocketTest
, PendingReadOnCloseReturnsZero
) {
1049 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
1050 MockWrite writes
[] = {
1051 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
1054 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
1055 MockRead reads
[] = {
1056 CreateMockRead(*resp
, 1, ASYNC
),
1057 MockRead(ASYNC
, 0, 2), // EOF
1060 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
1062 AssertConnectSucceeds();
1064 AssertReadStarts(kMsg1
, kLen1
);
1068 ASSERT_EQ(0, read_callback_
.WaitForResult());
1071 // Reading from a disconnected socket is an error
1072 TEST_P(SpdyProxyClientSocketTest
,
1073 ReadOnDisconnectSocketReturnsNotConnected
) {
1074 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
1075 MockWrite writes
[] = {
1076 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
1079 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
1080 MockRead reads
[] = {
1081 CreateMockRead(*resp
, 1, ASYNC
),
1082 MockRead(ASYNC
, 0, 2), // EOF
1085 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
1087 AssertConnectSucceeds();
1089 sock_
->Disconnect();
1091 ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED
,
1092 sock_
->Read(NULL
, 1, CompletionCallback()));
1095 // Reading buffered data from an already closed socket should return
1096 // buffered data, then 0.
1097 TEST_P(SpdyProxyClientSocketTest
, ReadOnClosedSocketReturnsBufferedData
) {
1098 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
1099 MockWrite writes
[] = {
1100 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
1103 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
1104 scoped_ptr
<SpdyFrame
> msg1(ConstructBodyFrame(kMsg1
, kLen1
));
1105 MockRead reads
[] = {
1106 CreateMockRead(*resp
, 1, ASYNC
),
1107 CreateMockRead(*msg1
, 2, ASYNC
),
1108 MockRead(ASYNC
, 0, 3), // EOF
1111 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
1113 AssertConnectSucceeds();
1117 ASSERT_FALSE(sock_
->IsConnected());
1118 scoped_refptr
<IOBuffer
> buf(new IOBuffer(kLen1
));
1119 ASSERT_EQ(kLen1
, sock_
->Read(buf
.get(), kLen1
, CompletionCallback()));
1120 ASSERT_EQ(std::string(kMsg1
, kLen1
), std::string(buf
->data(), kLen1
));
1122 ASSERT_EQ(0, sock_
->Read(NULL
, 1, CompletionCallback()));
1123 ASSERT_EQ(0, sock_
->Read(NULL
, 1, CompletionCallback()));
1124 sock_
->Disconnect();
1125 ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED
,
1126 sock_
->Read(NULL
, 1, CompletionCallback()));
1129 // Calling Write() on a closed socket is an error
1130 TEST_P(SpdyProxyClientSocketTest
, WriteOnClosedStream
) {
1131 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
1132 MockWrite writes
[] = {
1133 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
1136 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
1137 scoped_ptr
<SpdyFrame
> msg1(ConstructBodyFrame(kMsg1
, kLen1
));
1138 MockRead reads
[] = {
1139 CreateMockRead(*resp
, 1, ASYNC
),
1140 MockRead(ASYNC
, 0, 2), // EOF
1143 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
1145 AssertConnectSucceeds();
1147 Run(1); // Read EOF which will close the stream
1148 scoped_refptr
<IOBufferWithSize
> buf(CreateBuffer(kMsg1
, kLen1
));
1149 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED
,
1150 sock_
->Write(buf
.get(), buf
->size(), CompletionCallback()));
1153 // Calling Write() on a disconnected socket is an error
1154 TEST_P(SpdyProxyClientSocketTest
, WriteOnDisconnectedSocket
) {
1155 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
1156 MockWrite writes
[] = {
1157 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
1160 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
1161 scoped_ptr
<SpdyFrame
> msg1(ConstructBodyFrame(kMsg1
, kLen1
));
1162 MockRead reads
[] = {
1163 CreateMockRead(*resp
, 1, ASYNC
),
1164 MockRead(ASYNC
, 0, 2), // EOF
1167 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
1169 AssertConnectSucceeds();
1171 sock_
->Disconnect();
1173 scoped_refptr
<IOBufferWithSize
> buf(CreateBuffer(kMsg1
, kLen1
));
1174 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED
,
1175 sock_
->Write(buf
.get(), buf
->size(), CompletionCallback()));
1178 // If the socket is closed with a pending Write(), the callback
1179 // should be called with ERR_CONNECTION_CLOSED.
1180 TEST_P(SpdyProxyClientSocketTest
, WritePendingOnClose
) {
1181 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
1182 MockWrite writes
[] = {
1183 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
1184 MockWrite(ASYNC
, ERR_ABORTED
, 2),
1187 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
1188 MockRead reads
[] = {
1189 CreateMockRead(*resp
, 1, ASYNC
),
1190 MockRead(ASYNC
, 0, 3), // EOF
1193 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
1195 AssertConnectSucceeds();
1197 EXPECT_TRUE(sock_
->IsConnected());
1199 scoped_refptr
<IOBufferWithSize
> buf(CreateBuffer(kMsg1
, kLen1
));
1200 EXPECT_EQ(ERR_IO_PENDING
,
1201 sock_
->Write(buf
.get(), buf
->size(), write_callback_
.callback()));
1203 CloseSpdySession(ERR_ABORTED
, std::string());
1205 EXPECT_EQ(ERR_CONNECTION_CLOSED
, write_callback_
.WaitForResult());
1208 // If the socket is Disconnected with a pending Write(), the callback
1209 // should not be called.
1210 TEST_P(SpdyProxyClientSocketTest
, DisconnectWithWritePending
) {
1211 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
1212 MockWrite writes
[] = {
1213 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
1214 MockWrite(SYNCHRONOUS
, 0, 2), // EOF
1217 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
1218 MockRead reads
[] = {
1219 CreateMockRead(*resp
, 1, ASYNC
),
1220 MockRead(ASYNC
, 0, 3), // EOF
1223 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
1225 AssertConnectSucceeds();
1227 EXPECT_TRUE(sock_
->IsConnected());
1229 scoped_refptr
<IOBufferWithSize
> buf(CreateBuffer(kMsg1
, kLen1
));
1230 EXPECT_EQ(ERR_IO_PENDING
,
1231 sock_
->Write(buf
.get(), buf
->size(), write_callback_
.callback()));
1233 sock_
->Disconnect();
1235 EXPECT_FALSE(sock_
->IsConnected());
1236 EXPECT_FALSE(write_callback_
.have_result());
1239 // If the socket is Disconnected with a pending Read(), the callback
1240 // should not be called.
1241 TEST_P(SpdyProxyClientSocketTest
, DisconnectWithReadPending
) {
1242 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
1243 MockWrite writes
[] = {
1244 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
1247 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
1248 MockRead reads
[] = {
1249 CreateMockRead(*resp
, 1, ASYNC
),
1250 MockRead(ASYNC
, 0, 2), // EOF
1253 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
1255 AssertConnectSucceeds();
1257 EXPECT_TRUE(sock_
->IsConnected());
1259 scoped_refptr
<IOBuffer
> buf(new IOBuffer(kLen1
));
1260 ASSERT_EQ(ERR_IO_PENDING
,
1261 sock_
->Read(buf
.get(), kLen1
, read_callback_
.callback()));
1263 sock_
->Disconnect();
1265 EXPECT_FALSE(sock_
->IsConnected());
1266 EXPECT_FALSE(read_callback_
.have_result());
1269 // If the socket is Reset when both a read and write are pending,
1270 // both should be called back.
1271 TEST_P(SpdyProxyClientSocketTest
, RstWithReadAndWritePending
) {
1272 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
1273 MockWrite writes
[] = {
1274 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
1275 MockWrite(ASYNC
, ERR_ABORTED
, 3),
1278 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
1279 scoped_ptr
<SpdyFrame
> rst(
1280 spdy_util_
.ConstructSpdyRstStream(1, RST_STREAM_CANCEL
));
1281 MockRead reads
[] = {
1282 CreateMockRead(*resp
, 1, ASYNC
),
1283 CreateMockRead(*rst
, 2, ASYNC
),
1284 MockRead(ASYNC
, 0, 4) // EOF
1287 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
1289 AssertConnectSucceeds();
1291 EXPECT_TRUE(sock_
->IsConnected());
1293 scoped_refptr
<IOBuffer
> read_buf(new IOBuffer(kLen1
));
1294 ASSERT_EQ(ERR_IO_PENDING
,
1295 sock_
->Read(read_buf
.get(), kLen1
, read_callback_
.callback()));
1297 scoped_refptr
<IOBufferWithSize
> write_buf(CreateBuffer(kMsg1
, kLen1
));
1301 write_buf
.get(), write_buf
->size(), write_callback_
.callback()));
1305 EXPECT_TRUE(sock_
.get());
1306 EXPECT_TRUE(read_callback_
.have_result());
1307 EXPECT_TRUE(write_callback_
.have_result());
1310 // Makes sure the proxy client socket's source gets the expected NetLog events
1311 // and only the expected NetLog events (No SpdySession events).
1312 TEST_P(SpdyProxyClientSocketTest
, NetLog
) {
1313 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
1314 MockWrite writes
[] = {
1315 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
1318 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
1319 scoped_ptr
<SpdyFrame
> msg1(ConstructBodyFrame(kMsg1
, kLen1
));
1320 MockRead reads
[] = {
1321 CreateMockRead(*resp
, 1, ASYNC
),
1322 CreateMockRead(*msg1
, 2, ASYNC
),
1323 MockRead(ASYNC
, 0, 3), // EOF
1326 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
1328 AssertConnectSucceeds();
1330 Run(1); // SpdySession consumes the next read and sends it to
1331 // sock_ to be buffered.
1332 AssertSyncReadEquals(kMsg1
, kLen1
);
1334 NetLog::Source sock_source
= sock_
->NetLog().source();
1337 CapturingNetLog::CapturedEntryList entry_list
;
1338 net_log_
.GetEntriesForSource(sock_source
, &entry_list
);
1340 ASSERT_EQ(entry_list
.size(), 10u);
1341 EXPECT_TRUE(LogContainsBeginEvent(entry_list
, 0, NetLog::TYPE_SOCKET_ALIVE
));
1342 EXPECT_TRUE(LogContainsEvent(entry_list
, 1,
1343 NetLog::TYPE_SPDY_PROXY_CLIENT_SESSION
,
1344 NetLog::PHASE_NONE
));
1345 EXPECT_TRUE(LogContainsBeginEvent(entry_list
, 2,
1346 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_SEND_REQUEST
));
1347 EXPECT_TRUE(LogContainsEvent(entry_list
, 3,
1348 NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS
,
1349 NetLog::PHASE_NONE
));
1350 EXPECT_TRUE(LogContainsEndEvent(entry_list
, 4,
1351 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_SEND_REQUEST
));
1352 EXPECT_TRUE(LogContainsBeginEvent(entry_list
, 5,
1353 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_READ_HEADERS
));
1354 EXPECT_TRUE(LogContainsEvent(entry_list
, 6,
1355 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS
,
1356 NetLog::PHASE_NONE
));
1357 EXPECT_TRUE(LogContainsEndEvent(entry_list
, 7,
1358 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_READ_HEADERS
));
1359 EXPECT_TRUE(LogContainsEvent(entry_list
, 8,
1360 NetLog::TYPE_SOCKET_BYTES_RECEIVED
,
1361 NetLog::PHASE_NONE
));
1362 EXPECT_TRUE(LogContainsEndEvent(entry_list
, 9, NetLog::TYPE_SOCKET_ALIVE
));
1365 // CompletionCallback that causes the SpdyProxyClientSocket to be
1366 // deleted when Run is invoked.
1367 class DeleteSockCallback
: public TestCompletionCallbackBase
{
1369 explicit DeleteSockCallback(scoped_ptr
<SpdyProxyClientSocket
>* sock
)
1371 callback_(base::Bind(&DeleteSockCallback::OnComplete
,
1372 base::Unretained(this))) {
1375 virtual ~DeleteSockCallback() {
1378 const CompletionCallback
& callback() const { return callback_
; }
1381 void OnComplete(int result
) {
1386 scoped_ptr
<SpdyProxyClientSocket
>* sock_
;
1387 CompletionCallback callback_
;
1389 DISALLOW_COPY_AND_ASSIGN(DeleteSockCallback
);
1392 // If the socket is Reset when both a read and write are pending, and the
1393 // read callback causes the socket to be deleted, the write callback should
1395 TEST_P(SpdyProxyClientSocketTest
, RstWithReadAndWritePendingDelete
) {
1396 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
1397 MockWrite writes
[] = {
1398 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
1399 MockWrite(ASYNC
, ERR_ABORTED
, 3),
1402 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
1403 scoped_ptr
<SpdyFrame
> rst(
1404 spdy_util_
.ConstructSpdyRstStream(1, RST_STREAM_CANCEL
));
1405 MockRead reads
[] = {
1406 CreateMockRead(*resp
, 1, ASYNC
),
1407 CreateMockRead(*rst
, 2, ASYNC
),
1408 MockRead(ASYNC
, 0, 4), // EOF
1411 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
1413 AssertConnectSucceeds();
1415 EXPECT_TRUE(sock_
->IsConnected());
1417 DeleteSockCallback
read_callback(&sock_
);
1419 scoped_refptr
<IOBuffer
> read_buf(new IOBuffer(kLen1
));
1420 ASSERT_EQ(ERR_IO_PENDING
,
1421 sock_
->Read(read_buf
.get(), kLen1
, read_callback
.callback()));
1423 scoped_refptr
<IOBufferWithSize
> write_buf(CreateBuffer(kMsg1
, kLen1
));
1427 write_buf
.get(), write_buf
->size(), write_callback_
.callback()));
1431 EXPECT_FALSE(sock_
.get());
1432 EXPECT_TRUE(read_callback
.have_result());
1433 EXPECT_FALSE(write_callback_
.have_result());