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/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/socket_test_util.h"
21 #include "net/socket/tcp_client_socket.h"
22 #include "net/spdy/buffered_spdy_framer.h"
23 #include "net/spdy/spdy_http_utils.h"
24 #include "net/spdy/spdy_protocol.h"
25 #include "net/spdy/spdy_session_pool.h"
26 #include "net/spdy/spdy_test_util_common.h"
27 #include "net/spdy/spdy_test_util_spdy3.h"
28 #include "testing/gtest/include/gtest/gtest.h"
29 #include "testing/platform_test.h"
31 using namespace net::test_spdy3
;
33 //-----------------------------------------------------------------------------
37 static const char kRequestUrl
[] = "https://www.google.com/";
38 static const char kOriginHost
[] = "www.google.com";
39 static const int kOriginPort
= 443;
40 static const char kOriginHostPort
[] = "www.google.com:443";
41 static const char kProxyUrl
[] = "https://myproxy:6121/";
42 static const char kProxyHost
[] = "myproxy";
43 static const int kProxyPort
= 6121;
44 static const char kUserAgent
[] = "Mozilla/1.0";
46 static const int kStreamId
= 1;
48 static const char kMsg1
[] = "\0hello!\xff";
49 static const int kLen1
= 8;
50 static const char kMsg2
[] = "\00012345678\0";
51 static const int kLen2
= 10;
52 static const char kMsg3
[] = "bye!";
53 static const int kLen3
= 4;
54 static const char kMsg33
[] = "bye!bye!";
55 static const int kLen33
= kLen3
+ kLen3
;
56 static const char kMsg333
[] = "bye!bye!bye!";
57 static const int kLen333
= kLen3
+ kLen3
+ kLen3
;
59 static const char kRedirectUrl
[] = "https://example.com/";
61 } // anonymous namespace
65 class SpdyProxyClientSocketSpdy3Test
: public PlatformTest
{
67 SpdyProxyClientSocketSpdy3Test();
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(ASCIIToUTF16("foo"));
97 const base::string16
kBar(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 scoped_ptr
<SpdyProxyClientSocket
> sock_
;
112 TestCompletionCallback read_callback_
;
113 TestCompletionCallback write_callback_
;
114 scoped_ptr
<DeterministicSocketData
> data_
;
115 CapturingBoundNetLog net_log_
;
118 scoped_refptr
<HttpNetworkSession
> session_
;
119 scoped_refptr
<IOBuffer
> read_buf_
;
120 SpdySessionDependencies session_deps_
;
121 MockConnect connect_data_
;
122 scoped_refptr
<SpdySession
> spdy_session_
;
123 scoped_refptr
<SpdyStream
> spdy_stream_
;
124 BufferedSpdyFramer framer_
;
126 std::string user_agent_
;
128 HostPortPair proxy_host_port_
;
129 HostPortPair endpoint_host_port_pair_
;
131 HostPortProxyPair endpoint_host_port_proxy_pair_
;
132 scoped_refptr
<TransportSocketParams
> transport_params_
;
134 DISALLOW_COPY_AND_ASSIGN(SpdyProxyClientSocketSpdy3Test
);
137 SpdyProxyClientSocketSpdy3Test::SpdyProxyClientSocketSpdy3Test()
143 connect_data_(SYNCHRONOUS
, OK
),
147 user_agent_(kUserAgent
),
149 proxy_host_port_(kProxyHost
, kProxyPort
),
150 endpoint_host_port_pair_(kOriginHost
, kOriginPort
),
151 proxy_(ProxyServer::SCHEME_HTTPS
, proxy_host_port_
),
152 endpoint_host_port_proxy_pair_(endpoint_host_port_pair_
, proxy_
),
153 transport_params_(new TransportSocketParams(proxy_host_port_
,
157 OnHostResolutionCallback())) {
158 session_deps_
.net_log
= net_log_
.bound().net_log();
161 void SpdyProxyClientSocketSpdy3Test::TearDown() {
163 if (session_
!= NULL
)
164 session_
->spdy_session_pool()->CloseAllSessions();
166 // Empty the current queue.
167 MessageLoop::current()->RunUntilIdle();
168 PlatformTest::TearDown();
171 void SpdyProxyClientSocketSpdy3Test::Initialize(MockRead
* reads
,
174 size_t writes_count
) {
175 data_
.reset(new DeterministicSocketData(reads
, reads_count
,
176 writes
, writes_count
));
177 data_
->set_connect_data(connect_data_
);
180 session_deps_
.deterministic_socket_factory
->AddSocketDataProvider(
182 session_deps_
.host_resolver
->set_synchronous_mode(true);
184 session_
= SpdySessionDependencies::SpdyCreateSessionDeterministic(
187 // Creates a new spdy session.
189 session_
->spdy_session_pool()->Get(endpoint_host_port_proxy_pair_
,
192 // Perform the TCP connect.
193 scoped_ptr
<ClientSocketHandle
> connection(new ClientSocketHandle
);
195 connection
->Init(endpoint_host_port_pair_
.ToString(),
196 transport_params_
, LOWEST
, CompletionCallback(),
197 session_
->GetTransportSocketPool(
198 HttpNetworkSession::NORMAL_SOCKET_POOL
),
200 spdy_session_
->InitializeWithSocket(connection
.release(), false, OK
);
202 // Create the SPDY Stream.
204 CreateStreamSynchronously(spdy_session_
, url_
, LOWEST
, net_log_
.bound());
205 ASSERT_TRUE(spdy_stream_
.get() != NULL
);
207 // Create the SpdyProxyClientSocket.
209 new SpdyProxyClientSocket(spdy_stream_
, user_agent_
,
210 endpoint_host_port_pair_
, url_
,
211 proxy_host_port_
, net_log_
.bound(),
212 session_
->http_auth_cache(),
213 session_
->http_auth_handler_factory()));
216 scoped_refptr
<IOBufferWithSize
> SpdyProxyClientSocketSpdy3Test::CreateBuffer(
217 const char* data
, int size
) {
218 scoped_refptr
<IOBufferWithSize
> buf(new IOBufferWithSize(size
));
219 memcpy(buf
->data(), data
, size
);
223 void SpdyProxyClientSocketSpdy3Test::AssertConnectSucceeds() {
224 ASSERT_EQ(ERR_IO_PENDING
, sock_
->Connect(read_callback_
.callback()));
226 ASSERT_EQ(OK
, read_callback_
.WaitForResult());
229 void SpdyProxyClientSocketSpdy3Test::AssertConnectFails(int result
) {
230 ASSERT_EQ(ERR_IO_PENDING
, sock_
->Connect(read_callback_
.callback()));
232 ASSERT_EQ(result
, read_callback_
.WaitForResult());
235 void SpdyProxyClientSocketSpdy3Test::AssertConnectionEstablished() {
236 const HttpResponseInfo
* response
= sock_
->GetConnectResponseInfo();
237 ASSERT_TRUE(response
!= NULL
);
238 ASSERT_EQ(200, response
->headers
->response_code());
239 ASSERT_EQ("Connection Established", response
->headers
->GetStatusText());
242 void SpdyProxyClientSocketSpdy3Test::AssertSyncReadEquals(const char* data
,
244 scoped_refptr
<IOBuffer
> buf(new IOBuffer(len
));
245 ASSERT_EQ(len
, sock_
->Read(buf
, len
, CompletionCallback()));
246 ASSERT_EQ(std::string(data
, len
), std::string(buf
->data(), len
));
247 ASSERT_TRUE(sock_
->IsConnected());
250 void SpdyProxyClientSocketSpdy3Test::AssertAsyncReadEquals(const char* data
,
253 // Issue the read, which will be completed asynchronously
254 scoped_refptr
<IOBuffer
> buf(new IOBuffer(len
));
255 ASSERT_EQ(ERR_IO_PENDING
, sock_
->Read(buf
, len
, read_callback_
.callback()));
256 EXPECT_TRUE(sock_
->IsConnected());
259 EXPECT_TRUE(sock_
->IsConnected());
261 // Now the read will return
262 EXPECT_EQ(len
, read_callback_
.WaitForResult());
263 ASSERT_EQ(std::string(data
, len
), std::string(buf
->data(), len
));
266 void SpdyProxyClientSocketSpdy3Test::AssertReadStarts(const char* data
,
269 // Issue the read, which will be completed asynchronously
270 read_buf_
= new IOBuffer(len
);
271 ASSERT_EQ(ERR_IO_PENDING
,
272 sock_
->Read(read_buf_
, len
, read_callback_
.callback()));
273 EXPECT_TRUE(sock_
->IsConnected());
276 void SpdyProxyClientSocketSpdy3Test::AssertReadReturns(const char* data
,
278 EXPECT_TRUE(sock_
->IsConnected());
280 // Now the read will return
281 EXPECT_EQ(len
, read_callback_
.WaitForResult());
282 ASSERT_EQ(std::string(data
, len
), std::string(read_buf_
->data(), len
));
285 void SpdyProxyClientSocketSpdy3Test::AssertAsyncWriteSucceeds(const char* data
,
287 AssertWriteReturns(data
, len
, ERR_IO_PENDING
);
289 AssertWriteLength(len
);
292 void SpdyProxyClientSocketSpdy3Test::AssertWriteReturns(const char* data
,
295 scoped_refptr
<IOBufferWithSize
> buf(CreateBuffer(data
, len
));
296 EXPECT_EQ(rv
, sock_
->Write(buf
, buf
->size(), write_callback_
.callback()));
299 void SpdyProxyClientSocketSpdy3Test::AssertWriteLength(int len
) {
300 EXPECT_EQ(len
, write_callback_
.WaitForResult());
303 void SpdyProxyClientSocketSpdy3Test::AssertAsyncWriteWithReadsSucceeds(
304 const char* data
, int len
, int num_reads
) {
305 scoped_refptr
<IOBufferWithSize
> buf(CreateBuffer(data
, len
));
307 EXPECT_EQ(ERR_IO_PENDING
, sock_
->Write(buf
, buf
->size(),
308 write_callback_
.callback()));
310 for (int i
= 0; i
< num_reads
; i
++) {
312 AssertSyncReadEquals(kMsg2
, kLen2
);
315 write_callback_
.WaitForResult();
318 // Constructs a standard SPDY SYN_STREAM frame for a CONNECT request.
320 SpdyProxyClientSocketSpdy3Test::ConstructConnectRequestFrame() {
321 const SpdyHeaderInfo kSynStartHeader
= {
325 net::ConvertRequestPriorityToSpdyPriority(LOWEST
, 3),
334 const char* const kConnectHeaders
[] = {
335 ":method", "CONNECT",
336 ":path", kOriginHostPort
,
337 ":host", kOriginHost
,
338 "user-agent", kUserAgent
,
339 ":version", "HTTP/1.1",
341 return ConstructSpdyFrame(
342 kSynStartHeader
, NULL
, 0, kConnectHeaders
, arraysize(kConnectHeaders
)/2);
345 // Constructs a SPDY SYN_STREAM frame for a CONNECT request which includes
346 // Proxy-Authorization headers.
348 SpdyProxyClientSocketSpdy3Test::ConstructConnectAuthRequestFrame() {
349 const SpdyHeaderInfo kSynStartHeader
= {
353 net::ConvertRequestPriorityToSpdyPriority(LOWEST
, 3),
362 const char* const kConnectHeaders
[] = {
363 ":method", "CONNECT",
364 ":path", kOriginHostPort
,
365 ":host", kOriginHost
,
366 "user-agent", kUserAgent
,
367 ":version", "HTTP/1.1",
368 "proxy-authorization", "Basic Zm9vOmJhcg==",
370 return ConstructSpdyFrame(
371 kSynStartHeader
, NULL
, 0, kConnectHeaders
, arraysize(kConnectHeaders
)/2);
374 // Constructs a standard SPDY SYN_REPLY frame to match the SPDY CONNECT.
375 SpdyFrame
* SpdyProxyClientSocketSpdy3Test::ConstructConnectReplyFrame() {
376 const char* const kStandardReplyHeaders
[] = {
377 ":status", "200 Connection Established",
378 ":version", "HTTP/1.1"
380 return ConstructSpdyControlFrame(NULL
,
387 kStandardReplyHeaders
,
388 arraysize(kStandardReplyHeaders
));
391 // Constructs a standard SPDY SYN_REPLY frame to match the SPDY CONNECT.
393 SpdyProxyClientSocketSpdy3Test::ConstructConnectAuthReplyFrame() {
394 const char* const kStandardReplyHeaders
[] = {
395 ":status", "407 Proxy Authentication Required",
396 ":version", "HTTP/1.1",
397 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
400 return ConstructSpdyControlFrame(NULL
,
407 kStandardReplyHeaders
,
408 arraysize(kStandardReplyHeaders
));
411 // Constructs a SPDY SYN_REPLY frame with an HTTP 302 redirect.
413 SpdyProxyClientSocketSpdy3Test::ConstructConnectRedirectReplyFrame() {
414 const char* const kStandardReplyHeaders
[] = {
415 ":status", "302 Found",
416 ":version", "HTTP/1.1",
417 "location", kRedirectUrl
,
418 "set-cookie", "foo=bar"
421 return ConstructSpdyControlFrame(NULL
,
428 kStandardReplyHeaders
,
429 arraysize(kStandardReplyHeaders
));
432 // Constructs a SPDY SYN_REPLY frame with an HTTP 500 error.
434 SpdyProxyClientSocketSpdy3Test::ConstructConnectErrorReplyFrame() {
435 const char* const kStandardReplyHeaders
[] = {
436 ":status", "500 Internal Server Error",
437 ":version", "HTTP/1.1",
440 return ConstructSpdyControlFrame(NULL
,
447 kStandardReplyHeaders
,
448 arraysize(kStandardReplyHeaders
));
451 SpdyFrame
* SpdyProxyClientSocketSpdy3Test::ConstructBodyFrame(
454 return framer_
.CreateDataFrame(kStreamId
, data
, length
, DATA_FLAG_NONE
);
457 // ----------- Connect
459 TEST_F(SpdyProxyClientSocketSpdy3Test
, ConnectSendsCorrectRequest
) {
460 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
461 MockWrite writes
[] = {
462 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
465 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
467 CreateMockRead(*resp
, 1, ASYNC
),
468 MockRead(ASYNC
, 0, 2), // EOF
471 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
473 ASSERT_FALSE(sock_
->IsConnected());
475 AssertConnectSucceeds();
477 AssertConnectionEstablished();
480 TEST_F(SpdyProxyClientSocketSpdy3Test
, ConnectWithAuthRequested
) {
481 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
482 MockWrite writes
[] = {
483 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
486 scoped_ptr
<SpdyFrame
> resp(ConstructConnectAuthReplyFrame());
488 CreateMockRead(*resp
, 1, ASYNC
),
489 MockRead(ASYNC
, 0, 2), // EOF
492 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
494 AssertConnectFails(ERR_PROXY_AUTH_REQUESTED
);
496 const HttpResponseInfo
* response
= sock_
->GetConnectResponseInfo();
497 ASSERT_TRUE(response
!= NULL
);
498 ASSERT_EQ(407, response
->headers
->response_code());
499 ASSERT_EQ("Proxy Authentication Required",
500 response
->headers
->GetStatusText());
503 TEST_F(SpdyProxyClientSocketSpdy3Test
, ConnectWithAuthCredentials
) {
504 scoped_ptr
<SpdyFrame
> conn(ConstructConnectAuthRequestFrame());
505 MockWrite writes
[] = {
506 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
509 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
511 CreateMockRead(*resp
, 1, ASYNC
),
512 MockRead(ASYNC
, 0, 2), // EOF
515 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
518 AssertConnectSucceeds();
520 AssertConnectionEstablished();
523 TEST_F(SpdyProxyClientSocketSpdy3Test
, ConnectRedirects
) {
524 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
525 MockWrite writes
[] = {
526 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
529 scoped_ptr
<SpdyFrame
> resp(ConstructConnectRedirectReplyFrame());
531 CreateMockRead(*resp
, 1, ASYNC
),
532 MockRead(ASYNC
, 0, 2), // EOF
535 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
537 AssertConnectFails(ERR_HTTPS_PROXY_TUNNEL_RESPONSE
);
539 const HttpResponseInfo
* response
= sock_
->GetConnectResponseInfo();
540 ASSERT_TRUE(response
!= NULL
);
542 const HttpResponseHeaders
* headers
= response
->headers
;
543 ASSERT_EQ(302, headers
->response_code());
544 ASSERT_FALSE(headers
->HasHeader("set-cookie"));
545 ASSERT_TRUE(headers
->HasHeaderValue("content-length", "0"));
547 std::string location
;
548 ASSERT_TRUE(headers
->IsRedirect(&location
));
549 ASSERT_EQ(location
, kRedirectUrl
);
552 TEST_F(SpdyProxyClientSocketSpdy3Test
, ConnectFails
) {
553 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
554 MockWrite writes
[] = {
555 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
558 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
560 MockRead(ASYNC
, 0, 1), // EOF
563 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
565 ASSERT_FALSE(sock_
->IsConnected());
567 AssertConnectFails(ERR_CONNECTION_CLOSED
);
569 ASSERT_FALSE(sock_
->IsConnected());
572 // ----------- WasEverUsed
574 TEST_F(SpdyProxyClientSocketSpdy3Test
, WasEverUsedReturnsCorrectValues
) {
575 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
576 MockWrite writes
[] = {
577 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
580 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
582 CreateMockRead(*resp
, 1, ASYNC
),
583 MockRead(ASYNC
, 0, 2), // EOF
586 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
588 EXPECT_FALSE(sock_
->WasEverUsed());
589 AssertConnectSucceeds();
590 EXPECT_TRUE(sock_
->WasEverUsed());
592 EXPECT_TRUE(sock_
->WasEverUsed());
595 // ----------- GetPeerAddress
597 TEST_F(SpdyProxyClientSocketSpdy3Test
, GetPeerAddressReturnsCorrectValues
) {
598 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
599 MockWrite writes
[] = {
600 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
603 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
605 CreateMockRead(*resp
, 1, ASYNC
),
606 MockRead(ASYNC
, 0, 2), // EOF
609 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
611 net::IPEndPoint addr
;
612 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED
, sock_
->GetPeerAddress(&addr
));
614 AssertConnectSucceeds();
615 EXPECT_TRUE(sock_
->IsConnected());
616 EXPECT_EQ(OK
, sock_
->GetPeerAddress(&addr
));
620 EXPECT_FALSE(sock_
->IsConnected());
621 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED
, sock_
->GetPeerAddress(&addr
));
625 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED
, sock_
->GetPeerAddress(&addr
));
630 TEST_F(SpdyProxyClientSocketSpdy3Test
, WriteSendsDataInDataFrame
) {
631 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
632 scoped_ptr
<SpdyFrame
> msg1(ConstructBodyFrame(kMsg1
, kLen1
));
633 scoped_ptr
<SpdyFrame
> msg2(ConstructBodyFrame(kMsg2
, kLen2
));
634 MockWrite writes
[] = {
635 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
636 CreateMockWrite(*msg1
, 2, SYNCHRONOUS
),
637 CreateMockWrite(*msg2
, 3, SYNCHRONOUS
),
640 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
642 CreateMockRead(*resp
, 1, ASYNC
),
643 MockRead(ASYNC
, 0, 4), // EOF
646 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
648 AssertConnectSucceeds();
650 AssertAsyncWriteSucceeds(kMsg1
, kLen1
);
651 AssertAsyncWriteSucceeds(kMsg2
, kLen2
);
654 TEST_F(SpdyProxyClientSocketSpdy3Test
, WriteSplitsLargeDataIntoMultipleFrames
) {
655 std::string
chunk_data(kMaxSpdyFrameChunkSize
, 'x');
656 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
657 scoped_ptr
<SpdyFrame
> chunk(ConstructBodyFrame(chunk_data
.data(),
658 chunk_data
.length()));
659 MockWrite writes
[] = {
660 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
661 CreateMockWrite(*chunk
, 2, SYNCHRONOUS
),
662 CreateMockWrite(*chunk
, 3, SYNCHRONOUS
),
663 CreateMockWrite(*chunk
, 4, SYNCHRONOUS
)
666 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
668 CreateMockRead(*resp
, 1, ASYNC
),
669 MockRead(ASYNC
, 0, 5), // EOF
672 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
674 AssertConnectSucceeds();
676 std::string
big_data(kMaxSpdyFrameChunkSize
* 3, 'x');
677 scoped_refptr
<IOBufferWithSize
> buf(CreateBuffer(big_data
.data(),
680 EXPECT_EQ(ERR_IO_PENDING
, sock_
->Write(buf
, buf
->size(),
681 write_callback_
.callback()));
684 EXPECT_EQ(buf
->size(), write_callback_
.WaitForResult());
689 TEST_F(SpdyProxyClientSocketSpdy3Test
, ReadReadsDataInDataFrame
) {
690 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
691 MockWrite writes
[] = {
692 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
695 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
696 scoped_ptr
<SpdyFrame
> msg1(ConstructBodyFrame(kMsg1
, kLen1
));
698 CreateMockRead(*resp
, 1, ASYNC
),
699 CreateMockRead(*msg1
, 2, ASYNC
),
700 MockRead(ASYNC
, 0, 3), // EOF
703 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
705 AssertConnectSucceeds();
707 Run(1); // SpdySession consumes the next read and sends it to
708 // sock_ to be buffered.
709 AssertSyncReadEquals(kMsg1
, kLen1
);
712 TEST_F(SpdyProxyClientSocketSpdy3Test
, ReadDataFromBufferedFrames
) {
713 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
714 MockWrite writes
[] = {
715 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
718 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
719 scoped_ptr
<SpdyFrame
> msg1(ConstructBodyFrame(kMsg1
, kLen1
));
720 scoped_ptr
<SpdyFrame
> msg2(ConstructBodyFrame(kMsg2
, kLen2
));
722 CreateMockRead(*resp
, 1, ASYNC
),
723 CreateMockRead(*msg1
, 2, ASYNC
),
724 CreateMockRead(*msg2
, 3, ASYNC
),
725 MockRead(ASYNC
, 0, 4), // EOF
728 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
730 AssertConnectSucceeds();
732 Run(1); // SpdySession consumes the next read and sends it to
733 // sock_ to be buffered.
734 AssertSyncReadEquals(kMsg1
, kLen1
);
735 Run(1); // SpdySession consumes the next read and sends it to
736 // sock_ to be buffered.
737 AssertSyncReadEquals(kMsg2
, kLen2
);
740 TEST_F(SpdyProxyClientSocketSpdy3Test
, ReadDataMultipleBufferedFrames
) {
741 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
742 MockWrite writes
[] = {
743 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
746 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
747 scoped_ptr
<SpdyFrame
> msg1(ConstructBodyFrame(kMsg1
, kLen1
));
748 scoped_ptr
<SpdyFrame
> msg2(ConstructBodyFrame(kMsg2
, kLen2
));
750 CreateMockRead(*resp
, 1, ASYNC
),
751 CreateMockRead(*msg1
, 2, ASYNC
),
752 CreateMockRead(*msg2
, 3, ASYNC
),
753 MockRead(ASYNC
, 0, 4), // EOF
756 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
758 AssertConnectSucceeds();
760 Run(2); // SpdySession consumes the next two reads and sends then to
761 // sock_ to be buffered.
762 AssertSyncReadEquals(kMsg1
, kLen1
);
763 AssertSyncReadEquals(kMsg2
, kLen2
);
766 TEST_F(SpdyProxyClientSocketSpdy3Test
,
767 LargeReadWillMergeDataFromDifferentFrames
) {
768 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
769 MockWrite writes
[] = {
770 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
773 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
774 scoped_ptr
<SpdyFrame
> msg1(ConstructBodyFrame(kMsg1
, kLen1
));
775 scoped_ptr
<SpdyFrame
> msg3(ConstructBodyFrame(kMsg3
, kLen3
));
777 CreateMockRead(*resp
, 1, ASYNC
),
778 CreateMockRead(*msg3
, 2, ASYNC
),
779 CreateMockRead(*msg3
, 3, ASYNC
),
780 MockRead(ASYNC
, 0, 4), // EOF
783 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
785 AssertConnectSucceeds();
787 Run(2); // SpdySession consumes the next two reads and sends then to
788 // sock_ to be buffered.
789 // The payload from two data frames, each with kMsg3 will be combined
790 // together into a single read().
791 AssertSyncReadEquals(kMsg33
, kLen33
);
794 TEST_F(SpdyProxyClientSocketSpdy3Test
, MultipleShortReadsThenMoreRead
) {
795 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
796 MockWrite writes
[] = {
797 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
800 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
801 scoped_ptr
<SpdyFrame
> msg1(ConstructBodyFrame(kMsg1
, kLen1
));
802 scoped_ptr
<SpdyFrame
> msg3(ConstructBodyFrame(kMsg3
, kLen3
));
803 scoped_ptr
<SpdyFrame
> msg2(ConstructBodyFrame(kMsg2
, kLen2
));
805 CreateMockRead(*resp
, 1, ASYNC
),
806 CreateMockRead(*msg1
, 2, ASYNC
),
807 CreateMockRead(*msg3
, 3, ASYNC
),
808 CreateMockRead(*msg3
, 4, ASYNC
),
809 CreateMockRead(*msg2
, 5, ASYNC
),
810 MockRead(ASYNC
, 0, 6), // EOF
813 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
815 AssertConnectSucceeds();
817 Run(4); // SpdySession consumes the next four reads and sends then to
818 // sock_ to be buffered.
819 AssertSyncReadEquals(kMsg1
, kLen1
);
820 // The payload from two data frames, each with kMsg3 will be combined
821 // together into a single read().
822 AssertSyncReadEquals(kMsg33
, kLen33
);
823 AssertSyncReadEquals(kMsg2
, kLen2
);
826 TEST_F(SpdyProxyClientSocketSpdy3Test
, ReadWillSplitDataFromLargeFrame
) {
827 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
828 MockWrite writes
[] = {
829 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
832 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
833 scoped_ptr
<SpdyFrame
> msg1(ConstructBodyFrame(kMsg1
, kLen1
));
834 scoped_ptr
<SpdyFrame
> msg33(ConstructBodyFrame(kMsg33
, kLen33
));
835 scoped_ptr
<SpdyFrame
> msg2(ConstructBodyFrame(kMsg2
, kLen2
));
837 CreateMockRead(*resp
, 1, ASYNC
),
838 CreateMockRead(*msg1
, 2, ASYNC
),
839 CreateMockRead(*msg33
, 3, ASYNC
),
840 MockRead(ASYNC
, 0, 4), // EOF
843 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
845 AssertConnectSucceeds();
847 Run(2); // SpdySession consumes the next two reads and sends then to
848 // sock_ to be buffered.
849 AssertSyncReadEquals(kMsg1
, kLen1
);
850 // The payload from the single large data frame will be read across
851 // two different reads.
852 AssertSyncReadEquals(kMsg3
, kLen3
);
853 AssertSyncReadEquals(kMsg3
, kLen3
);
856 TEST_F(SpdyProxyClientSocketSpdy3Test
, MultipleReadsFromSameLargeFrame
) {
857 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
858 MockWrite writes
[] = {
859 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
862 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
863 scoped_ptr
<SpdyFrame
> msg333(ConstructBodyFrame(kMsg333
, kLen333
));
865 CreateMockRead(*resp
, 1, ASYNC
),
866 CreateMockRead(*msg333
, 2, ASYNC
),
867 MockRead(ASYNC
, 0, 3), // EOF
870 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
872 AssertConnectSucceeds();
874 Run(1); // SpdySession consumes the next read and sends it to
875 // sock_ to be buffered.
876 // The payload from the single large data frame will be read across
877 // two different reads.
878 AssertSyncReadEquals(kMsg33
, kLen33
);
880 // Now attempt to do a read of more data than remains buffered
881 scoped_refptr
<IOBuffer
> buf(new IOBuffer(kLen33
));
882 ASSERT_EQ(kLen3
, sock_
->Read(buf
, kLen33
, read_callback_
.callback()));
883 ASSERT_EQ(std::string(kMsg3
, kLen3
), std::string(buf
->data(), kLen3
));
884 ASSERT_TRUE(sock_
->IsConnected());
887 TEST_F(SpdyProxyClientSocketSpdy3Test
, ReadAuthResponseBody
) {
888 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
889 MockWrite writes
[] = {
890 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
893 scoped_ptr
<SpdyFrame
> resp(ConstructConnectAuthReplyFrame());
894 scoped_ptr
<SpdyFrame
> msg1(ConstructBodyFrame(kMsg1
, kLen1
));
895 scoped_ptr
<SpdyFrame
> msg2(ConstructBodyFrame(kMsg2
, kLen2
));
897 CreateMockRead(*resp
, 1, ASYNC
),
898 CreateMockRead(*msg1
, 2, ASYNC
),
899 CreateMockRead(*msg2
, 3, ASYNC
),
900 MockRead(ASYNC
, 0, 4), // EOF
903 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
905 AssertConnectFails(ERR_PROXY_AUTH_REQUESTED
);
907 Run(2); // SpdySession consumes the next two reads and sends then to
908 // sock_ to be buffered.
909 AssertSyncReadEquals(kMsg1
, kLen1
);
910 AssertSyncReadEquals(kMsg2
, kLen2
);
913 TEST_F(SpdyProxyClientSocketSpdy3Test
, ReadErrorResponseBody
) {
914 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
915 MockWrite writes
[] = {
916 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
919 scoped_ptr
<SpdyFrame
> resp(ConstructConnectErrorReplyFrame());
920 scoped_ptr
<SpdyFrame
> msg1(ConstructBodyFrame(kMsg1
, kLen1
));
921 scoped_ptr
<SpdyFrame
> msg2(ConstructBodyFrame(kMsg2
, kLen2
));
923 CreateMockRead(*resp
, 1, ASYNC
),
924 CreateMockRead(*msg1
, 2, ASYNC
),
925 CreateMockRead(*msg2
, 3, ASYNC
),
926 MockRead(ASYNC
, 0, 4), // EOF
929 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
931 AssertConnectFails(ERR_TUNNEL_CONNECTION_FAILED
);
934 // ----------- Reads and Writes
936 TEST_F(SpdyProxyClientSocketSpdy3Test
, AsyncReadAroundWrite
) {
937 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
938 scoped_ptr
<SpdyFrame
> msg2(ConstructBodyFrame(kMsg2
, kLen2
));
939 MockWrite writes
[] = {
940 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
941 CreateMockWrite(*msg2
, 3, SYNCHRONOUS
),
944 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
945 scoped_ptr
<SpdyFrame
> msg1(ConstructBodyFrame(kMsg1
, kLen1
));
946 scoped_ptr
<SpdyFrame
> msg3(ConstructBodyFrame(kMsg3
, kLen3
));
948 CreateMockRead(*resp
, 1, ASYNC
),
949 CreateMockRead(*msg1
, 2, ASYNC
), // sync read
950 CreateMockRead(*msg3
, 4, ASYNC
), // async read
951 MockRead(ASYNC
, 0, 5), // EOF
954 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
956 AssertConnectSucceeds();
959 AssertSyncReadEquals(kMsg1
, kLen1
);
961 AssertReadStarts(kMsg3
, kLen3
);
962 // Read should block until after the write succeeds
964 AssertAsyncWriteSucceeds(kMsg2
, kLen2
); // Runs 1 step
966 ASSERT_FALSE(read_callback_
.have_result());
968 // Now the read will return
969 AssertReadReturns(kMsg3
, kLen3
);
972 TEST_F(SpdyProxyClientSocketSpdy3Test
, AsyncWriteAroundReads
) {
973 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
974 scoped_ptr
<SpdyFrame
> msg2(ConstructBodyFrame(kMsg2
, kLen2
));
975 MockWrite writes
[] = {
976 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
977 CreateMockWrite(*msg2
, 4, ASYNC
),
980 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
981 scoped_ptr
<SpdyFrame
> msg1(ConstructBodyFrame(kMsg1
, kLen1
));
982 scoped_ptr
<SpdyFrame
> msg3(ConstructBodyFrame(kMsg3
, kLen3
));
984 CreateMockRead(*resp
, 1, ASYNC
),
985 CreateMockRead(*msg1
, 2, ASYNC
),
986 CreateMockRead(*msg3
, 3, ASYNC
),
987 MockRead(ASYNC
, 0, 5), // EOF
990 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
992 AssertConnectSucceeds();
995 AssertSyncReadEquals(kMsg1
, kLen1
);
996 // Write should block until the read completes
997 AssertWriteReturns(kMsg2
, kLen2
, ERR_IO_PENDING
);
999 AssertAsyncReadEquals(kMsg3
, kLen3
);
1001 ASSERT_FALSE(write_callback_
.have_result());
1003 // Now the write will complete
1005 AssertWriteLength(kLen2
);
1008 // ----------- Reading/Writing on Closed socket
1010 // Reading from an already closed socket should return 0
1011 TEST_F(SpdyProxyClientSocketSpdy3Test
, ReadOnClosedSocketReturnsZero
) {
1012 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
1013 MockWrite writes
[] = {
1014 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
1017 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
1018 MockRead reads
[] = {
1019 CreateMockRead(*resp
, 1, ASYNC
),
1020 MockRead(ASYNC
, 0, 2), // EOF
1023 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
1025 AssertConnectSucceeds();
1029 ASSERT_FALSE(sock_
->IsConnected());
1030 ASSERT_EQ(0, sock_
->Read(NULL
, 1, CompletionCallback()));
1031 ASSERT_EQ(0, sock_
->Read(NULL
, 1, CompletionCallback()));
1032 ASSERT_EQ(0, sock_
->Read(NULL
, 1, CompletionCallback()));
1033 ASSERT_FALSE(sock_
->IsConnectedAndIdle());
1036 // Read pending when socket is closed should return 0
1037 TEST_F(SpdyProxyClientSocketSpdy3Test
, PendingReadOnCloseReturnsZero
) {
1038 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
1039 MockWrite writes
[] = {
1040 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
1043 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
1044 MockRead reads
[] = {
1045 CreateMockRead(*resp
, 1, ASYNC
),
1046 MockRead(ASYNC
, 0, 2), // EOF
1049 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
1051 AssertConnectSucceeds();
1053 AssertReadStarts(kMsg1
, kLen1
);
1057 ASSERT_EQ(0, read_callback_
.WaitForResult());
1060 // Reading from a disconnected socket is an error
1061 TEST_F(SpdyProxyClientSocketSpdy3Test
,
1062 ReadOnDisconnectSocketReturnsNotConnected
) {
1063 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
1064 MockWrite writes
[] = {
1065 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
1068 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
1069 MockRead reads
[] = {
1070 CreateMockRead(*resp
, 1, ASYNC
),
1071 MockRead(ASYNC
, 0, 2), // EOF
1074 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
1076 AssertConnectSucceeds();
1078 sock_
->Disconnect();
1080 ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED
,
1081 sock_
->Read(NULL
, 1, CompletionCallback()));
1084 // Reading buffered data from an already closed socket should return
1085 // buffered data, then 0.
1086 TEST_F(SpdyProxyClientSocketSpdy3Test
, ReadOnClosedSocketReturnsBufferedData
) {
1087 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
1088 MockWrite writes
[] = {
1089 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
1092 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
1093 scoped_ptr
<SpdyFrame
> msg1(ConstructBodyFrame(kMsg1
, kLen1
));
1094 MockRead reads
[] = {
1095 CreateMockRead(*resp
, 1, ASYNC
),
1096 CreateMockRead(*msg1
, 2, ASYNC
),
1097 MockRead(ASYNC
, 0, 3), // EOF
1100 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
1102 AssertConnectSucceeds();
1106 ASSERT_FALSE(sock_
->IsConnected());
1107 scoped_refptr
<IOBuffer
> buf(new IOBuffer(kLen1
));
1108 ASSERT_EQ(kLen1
, sock_
->Read(buf
, kLen1
, CompletionCallback()));
1109 ASSERT_EQ(std::string(kMsg1
, kLen1
), std::string(buf
->data(), kLen1
));
1111 ASSERT_EQ(0, sock_
->Read(NULL
, 1, CompletionCallback()));
1112 ASSERT_EQ(0, sock_
->Read(NULL
, 1, CompletionCallback()));
1113 sock_
->Disconnect();
1114 ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED
,
1115 sock_
->Read(NULL
, 1, CompletionCallback()));
1118 // Calling Write() on a closed socket is an error
1119 TEST_F(SpdyProxyClientSocketSpdy3Test
, WriteOnClosedStream
) {
1120 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
1121 MockWrite writes
[] = {
1122 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
1125 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
1126 scoped_ptr
<SpdyFrame
> msg1(ConstructBodyFrame(kMsg1
, kLen1
));
1127 MockRead reads
[] = {
1128 CreateMockRead(*resp
, 1, ASYNC
),
1129 MockRead(ASYNC
, 0, 2), // EOF
1132 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
1134 AssertConnectSucceeds();
1136 Run(1); // Read EOF which will close the stream
1137 scoped_refptr
<IOBufferWithSize
> buf(CreateBuffer(kMsg1
, kLen1
));
1138 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED
,
1139 sock_
->Write(buf
, buf
->size(), CompletionCallback()));
1142 // Calling Write() on a disconnected socket is an error
1143 TEST_F(SpdyProxyClientSocketSpdy3Test
, WriteOnDisconnectedSocket
) {
1144 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
1145 MockWrite writes
[] = {
1146 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
1149 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
1150 scoped_ptr
<SpdyFrame
> msg1(ConstructBodyFrame(kMsg1
, kLen1
));
1151 MockRead reads
[] = {
1152 CreateMockRead(*resp
, 1, ASYNC
),
1153 MockRead(ASYNC
, 0, 2), // EOF
1156 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
1158 AssertConnectSucceeds();
1160 sock_
->Disconnect();
1162 scoped_refptr
<IOBufferWithSize
> buf(CreateBuffer(kMsg1
, kLen1
));
1163 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED
,
1164 sock_
->Write(buf
, buf
->size(), CompletionCallback()));
1167 // If the socket is closed with a pending Write(), the callback
1168 // should be called with ERR_CONNECTION_CLOSED.
1169 TEST_F(SpdyProxyClientSocketSpdy3Test
, WritePendingOnClose
) {
1170 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
1171 MockWrite writes
[] = {
1172 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
1173 MockWrite(ASYNC
, ERR_IO_PENDING
, 2),
1176 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
1177 MockRead reads
[] = {
1178 CreateMockRead(*resp
, 1, ASYNC
),
1179 MockRead(ASYNC
, 0, 3), // EOF
1182 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
1184 AssertConnectSucceeds();
1186 EXPECT_TRUE(sock_
->IsConnected());
1188 scoped_refptr
<IOBufferWithSize
> buf(CreateBuffer(kMsg1
, kLen1
));
1189 EXPECT_EQ(ERR_IO_PENDING
,
1190 sock_
->Write(buf
, buf
->size(), write_callback_
.callback()));
1194 EXPECT_EQ(ERR_CONNECTION_CLOSED
, write_callback_
.WaitForResult());
1197 // If the socket is Disconnected with a pending Write(), the callback
1198 // should not be called.
1199 TEST_F(SpdyProxyClientSocketSpdy3Test
, DisconnectWithWritePending
) {
1200 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
1201 MockWrite writes
[] = {
1202 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
1203 MockWrite(SYNCHRONOUS
, 0, 2), // EOF
1206 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
1207 MockRead reads
[] = {
1208 CreateMockRead(*resp
, 1, ASYNC
),
1209 MockRead(ASYNC
, 0, 3), // EOF
1212 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
1214 AssertConnectSucceeds();
1216 EXPECT_TRUE(sock_
->IsConnected());
1218 scoped_refptr
<IOBufferWithSize
> buf(CreateBuffer(kMsg1
, kLen1
));
1219 EXPECT_EQ(ERR_IO_PENDING
,
1220 sock_
->Write(buf
, buf
->size(), write_callback_
.callback()));
1222 sock_
->Disconnect();
1224 EXPECT_FALSE(sock_
->IsConnected());
1225 EXPECT_FALSE(write_callback_
.have_result());
1228 // If the socket is Disconnected with a pending Read(), the callback
1229 // should not be called.
1230 TEST_F(SpdyProxyClientSocketSpdy3Test
, DisconnectWithReadPending
) {
1231 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
1232 MockWrite writes
[] = {
1233 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
1236 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
1237 MockRead reads
[] = {
1238 CreateMockRead(*resp
, 1, ASYNC
),
1239 MockRead(ASYNC
, 0, 2), // EOF
1242 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
1244 AssertConnectSucceeds();
1246 EXPECT_TRUE(sock_
->IsConnected());
1248 scoped_refptr
<IOBuffer
> buf(new IOBuffer(kLen1
));
1249 ASSERT_EQ(ERR_IO_PENDING
,
1250 sock_
->Read(buf
, kLen1
, read_callback_
.callback()));
1252 sock_
->Disconnect();
1254 EXPECT_FALSE(sock_
->IsConnected());
1255 EXPECT_FALSE(read_callback_
.have_result());
1258 // If the socket is Reset when both a read and write are pending,
1259 // both should be called back.
1260 TEST_F(SpdyProxyClientSocketSpdy3Test
, RstWithReadAndWritePending
) {
1261 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
1262 MockWrite writes
[] = {
1263 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
1264 MockWrite(ASYNC
, ERR_IO_PENDING
, 2),
1267 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
1268 scoped_ptr
<SpdyFrame
> rst(ConstructSpdyRstStream(1, RST_STREAM_CANCEL
));
1269 MockRead reads
[] = {
1270 CreateMockRead(*resp
, 1, ASYNC
),
1271 CreateMockRead(*rst
, 3, ASYNC
),
1274 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
1276 AssertConnectSucceeds();
1278 EXPECT_TRUE(sock_
->IsConnected());
1280 scoped_refptr
<IOBuffer
> read_buf(new IOBuffer(kLen1
));
1281 ASSERT_EQ(ERR_IO_PENDING
,
1282 sock_
->Read(read_buf
, kLen1
, read_callback_
.callback()));
1284 scoped_refptr
<IOBufferWithSize
> write_buf(CreateBuffer(kMsg1
, kLen1
));
1285 EXPECT_EQ(ERR_IO_PENDING
,
1286 sock_
->Write(write_buf
, write_buf
->size(),
1287 write_callback_
.callback()));
1291 EXPECT_TRUE(sock_
.get());
1292 EXPECT_TRUE(read_callback_
.have_result());
1293 EXPECT_TRUE(write_callback_
.have_result());
1296 // Makes sure the proxy client socket's source gets the expected NetLog events
1297 // and only the expected NetLog events (No SpdySession events).
1298 TEST_F(SpdyProxyClientSocketSpdy3Test
, NetLog
) {
1299 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
1300 MockWrite writes
[] = {
1301 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
1304 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
1305 scoped_ptr
<SpdyFrame
> msg1(ConstructBodyFrame(kMsg1
, kLen1
));
1306 MockRead reads
[] = {
1307 CreateMockRead(*resp
, 1, ASYNC
),
1308 CreateMockRead(*msg1
, 2, ASYNC
),
1309 MockRead(ASYNC
, 0, 3), // EOF
1312 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
1314 AssertConnectSucceeds();
1316 Run(1); // SpdySession consumes the next read and sends it to
1317 // sock_ to be buffered.
1318 AssertSyncReadEquals(kMsg1
, kLen1
);
1320 NetLog::Source sock_source
= sock_
->NetLog().source();
1323 CapturingNetLog::CapturedEntryList entry_list
;
1324 net_log_
.GetEntriesForSource(sock_source
, &entry_list
);
1326 ASSERT_EQ(entry_list
.size(), 10u);
1327 EXPECT_TRUE(LogContainsBeginEvent(entry_list
, 0, NetLog::TYPE_SOCKET_ALIVE
));
1328 EXPECT_TRUE(LogContainsEvent(entry_list
, 1,
1329 NetLog::TYPE_SPDY_PROXY_CLIENT_SESSION
,
1330 NetLog::PHASE_NONE
));
1331 EXPECT_TRUE(LogContainsBeginEvent(entry_list
, 2,
1332 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_SEND_REQUEST
));
1333 EXPECT_TRUE(LogContainsEvent(entry_list
, 3,
1334 NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS
,
1335 NetLog::PHASE_NONE
));
1336 EXPECT_TRUE(LogContainsEndEvent(entry_list
, 4,
1337 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_SEND_REQUEST
));
1338 EXPECT_TRUE(LogContainsBeginEvent(entry_list
, 5,
1339 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_READ_HEADERS
));
1340 EXPECT_TRUE(LogContainsEvent(entry_list
, 6,
1341 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS
,
1342 NetLog::PHASE_NONE
));
1343 EXPECT_TRUE(LogContainsEndEvent(entry_list
, 7,
1344 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_READ_HEADERS
));
1345 EXPECT_TRUE(LogContainsEvent(entry_list
, 8,
1346 NetLog::TYPE_SOCKET_BYTES_RECEIVED
,
1347 NetLog::PHASE_NONE
));
1348 EXPECT_TRUE(LogContainsEndEvent(entry_list
, 9, NetLog::TYPE_SOCKET_ALIVE
));
1351 // CompletionCallback that causes the SpdyProxyClientSocket to be
1352 // deleted when Run is invoked.
1353 class DeleteSockCallback
: public TestCompletionCallbackBase
{
1355 explicit DeleteSockCallback(scoped_ptr
<SpdyProxyClientSocket
>* sock
)
1357 ALLOW_THIS_IN_INITIALIZER_LIST(callback_(
1358 base::Bind(&DeleteSockCallback::OnComplete
,
1359 base::Unretained(this)))) {
1362 virtual ~DeleteSockCallback() {
1365 const CompletionCallback
& callback() const { return callback_
; }
1368 void OnComplete(int result
) {
1373 scoped_ptr
<SpdyProxyClientSocket
>* sock_
;
1374 CompletionCallback callback_
;
1376 DISALLOW_COPY_AND_ASSIGN(DeleteSockCallback
);
1379 // If the socket is Reset when both a read and write are pending, and the
1380 // read callback causes the socket to be deleted, the write callback should
1382 TEST_F(SpdyProxyClientSocketSpdy3Test
, RstWithReadAndWritePendingDelete
) {
1383 scoped_ptr
<SpdyFrame
> conn(ConstructConnectRequestFrame());
1384 MockWrite writes
[] = {
1385 CreateMockWrite(*conn
, 0, SYNCHRONOUS
),
1386 MockWrite(ASYNC
, ERR_IO_PENDING
, 2),
1389 scoped_ptr
<SpdyFrame
> resp(ConstructConnectReplyFrame());
1390 scoped_ptr
<SpdyFrame
> rst(ConstructSpdyRstStream(1, RST_STREAM_CANCEL
));
1391 MockRead reads
[] = {
1392 CreateMockRead(*resp
, 1, ASYNC
),
1393 CreateMockRead(*rst
, 3, ASYNC
),
1396 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
1398 AssertConnectSucceeds();
1400 EXPECT_TRUE(sock_
->IsConnected());
1402 DeleteSockCallback
read_callback(&sock_
);
1404 scoped_refptr
<IOBuffer
> read_buf(new IOBuffer(kLen1
));
1405 ASSERT_EQ(ERR_IO_PENDING
,
1406 sock_
->Read(read_buf
, kLen1
, read_callback
.callback()));
1408 scoped_refptr
<IOBufferWithSize
> write_buf(CreateBuffer(kMsg1
, kLen1
));
1409 EXPECT_EQ(ERR_IO_PENDING
, sock_
->Write(write_buf
, write_buf
->size(),
1410 write_callback_
.callback()));
1414 EXPECT_FALSE(sock_
.get());
1415 EXPECT_TRUE(read_callback
.have_result());
1416 EXPECT_FALSE(write_callback_
.have_result());