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/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 //-----------------------------------------------------------------------------
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 SpdyProxyClientSocketSpdy3Test
: public PlatformTest
{
65 SpdyProxyClientSocketSpdy3Test();
67 virtual void TearDown();
70 void Initialize(MockRead
* reads
, size_t reads_count
, MockWrite
* writes
,
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
,
93 void AddAuthToCache() {
94 const string16
kFoo(ASCIIToUTF16("foo"));
95 const string16
kBar(ASCIIToUTF16("bar"));
96 session_
->http_auth_cache()->Add(GURL(kProxyUrl
),
98 HttpAuth::AUTH_SCHEME_BASIC
,
99 "Basic realm=MyRealm1",
100 AuthCredentials(kFoo
, kBar
),
104 void Run(int steps
) {
105 data_
->StopAfter(steps
);
109 scoped_ptr
<SpdyProxyClientSocket
> sock_
;
110 TestCompletionCallback read_callback_
;
111 TestCompletionCallback write_callback_
;
112 scoped_ptr
<DeterministicSocketData
> data_
;
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_
;
125 HostPortPair proxy_host_port_
;
126 HostPortPair endpoint_host_port_pair_
;
128 HostPortProxyPair endpoint_host_port_proxy_pair_
;
129 scoped_refptr
<TransportSocketParams
> transport_params_
;
131 DISALLOW_COPY_AND_ASSIGN(SpdyProxyClientSocketSpdy3Test
);
134 SpdyProxyClientSocketSpdy3Test::SpdyProxyClientSocketSpdy3Test()
140 connect_data_(SYNCHRONOUS
, OK
),
144 user_agent_(kUserAgent
),
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_
,
154 OnHostResolutionCallback())) {
157 void SpdyProxyClientSocketSpdy3Test::TearDown() {
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
,
170 size_t writes_count
) {
171 data_
.reset(new DeterministicSocketData(reads
, reads_count
,
172 writes
, writes_count
));
173 data_
->set_connect_data(connect_data_
);
176 session_deps_
.deterministic_socket_factory
->AddSocketDataProvider(
178 session_deps_
.host_resolver
->set_synchronous_mode(true);
180 session_
= SpdySessionDependencies::SpdyCreateSessionDeterministic(
183 // Creates a new spdy session
185 session_
->spdy_session_pool()->Get(endpoint_host_port_proxy_pair_
,
188 // Perform the TCP connect
189 scoped_ptr
<ClientSocketHandle
> connection(new ClientSocketHandle
);
191 connection
->Init(endpoint_host_port_pair_
.ToString(),
192 transport_params_
, LOWEST
, CompletionCallback(),
193 session_
->GetTransportSocketPool(
194 HttpNetworkSession::NORMAL_SOCKET_POOL
),
196 spdy_session_
->InitializeWithSocket(connection
.release(), false, OK
);
198 // Create the SPDY Stream
201 spdy_session_
->CreateStream(url_
, LOWEST
, &spdy_stream_
, BoundNetLog(),
202 CompletionCallback()));
204 // Create the SpdyProxyClientSocket
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
);
219 void SpdyProxyClientSocketSpdy3Test::AssertConnectSucceeds() {
220 ASSERT_EQ(ERR_IO_PENDING
, sock_
->Connect(read_callback_
.callback()));
222 ASSERT_EQ(OK
, read_callback_
.WaitForResult());
225 void SpdyProxyClientSocketSpdy3Test::AssertConnectFails(int result
) {
226 ASSERT_EQ(ERR_IO_PENDING
, sock_
->Connect(read_callback_
.callback()));
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
,
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
,
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());
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
,
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
,
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
,
283 AssertWriteReturns(data
, len
, ERR_IO_PENDING
);
285 AssertWriteLength(len
);
288 void SpdyProxyClientSocketSpdy3Test::AssertWriteReturns(const char* data
,
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
++) {
308 AssertSyncReadEquals(kMsg2
, kLen2
);
311 write_callback_
.WaitForResult();
314 // Constructs a standard SPDY SYN_STREAM frame for a CONNECT request.
316 SpdyProxyClientSocketSpdy3Test::ConstructConnectRequestFrame() {
317 const SpdyHeaderInfo kSynStartHeader
= {
321 net::ConvertRequestPriorityToSpdyPriority(LOWEST
, 3),
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.
344 SpdyProxyClientSocketSpdy3Test::ConstructConnectAuthRequestFrame() {
345 const SpdyHeaderInfo kSynStartHeader
= {
349 net::ConvertRequestPriorityToSpdyPriority(LOWEST
, 3),
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
,
383 kStandardReplyHeaders
,
384 arraysize(kStandardReplyHeaders
));
387 // Constructs a standard SPDY SYN_REPLY frame to match the SPDY CONNECT.
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
,
403 kStandardReplyHeaders
,
404 arraysize(kStandardReplyHeaders
));
407 // Constructs a SPDY SYN_REPLY frame with an HTTP 302 redirect.
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
,
424 kStandardReplyHeaders
,
425 arraysize(kStandardReplyHeaders
));
428 // Constructs a SPDY SYN_REPLY frame with an HTTP 500 error.
430 SpdyProxyClientSocketSpdy3Test::ConstructConnectErrorReplyFrame() {
431 const char* const kStandardReplyHeaders
[] = {
432 ":status", "500 Internal Server Error",
433 ":version", "HTTP/1.1",
436 return ConstructSpdyControlFrame(NULL
,
443 kStandardReplyHeaders
,
444 arraysize(kStandardReplyHeaders
));
447 SpdyFrame
* SpdyProxyClientSocketSpdy3Test::ConstructBodyFrame(
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());
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());
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());
507 CreateMockRead(*resp
, 1, ASYNC
),
508 MockRead(ASYNC
, 0, 2), // EOF
511 Initialize(reads
, arraysize(reads
), writes
, arraysize(writes
));
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());
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());
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());
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());
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());
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
));
616 EXPECT_FALSE(sock_
->IsConnected());
617 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED
, sock_
->GetPeerAddress(&addr
));
621 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED
, sock_
->GetPeerAddress(&addr
));
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());
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());
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(),
676 EXPECT_EQ(ERR_IO_PENDING
, sock_
->Write(buf
, buf
->size(),
677 write_callback_
.callback()));
680 EXPECT_EQ(buf
->size(), write_callback_
.WaitForResult());
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
));
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
));
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
));
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
));
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
));
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
));
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
));
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
));
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
));
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
));
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();
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());
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
));
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();
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
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();
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
);
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();
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()));
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()));
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
{
1296 explicit DeleteSockCallback(scoped_ptr
<SpdyProxyClientSocket
>* 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_
; }
1309 void OnComplete(int 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
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()));
1355 EXPECT_FALSE(sock_
.get());
1356 EXPECT_TRUE(read_callback
.have_result());
1357 EXPECT_FALSE(write_callback_
.have_result());