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 void PopulateConnectRequestIR(SpdySynStreamIR* syn_ir);
75 void PopulateConnectReplyIR(SpdySynReplyIR* reply_ir, const char* status);
76 SpdyFrame* ConstructConnectRequestFrame();
77 SpdyFrame* ConstructConnectAuthRequestFrame();
78 SpdyFrame* ConstructConnectReplyFrame();
79 SpdyFrame* ConstructConnectAuthReplyFrame();
80 SpdyFrame* ConstructConnectRedirectReplyFrame();
81 SpdyFrame* ConstructConnectErrorReplyFrame();
82 SpdyFrame* ConstructBodyFrame(const char* data, int length);
83 scoped_refptr<IOBufferWithSize> CreateBuffer(const char* data, int size);
84 void AssertConnectSucceeds();
85 void AssertConnectFails(int result);
86 void AssertConnectionEstablished();
87 void AssertSyncReadEquals(const char* data, int len);
88 void AssertAsyncReadEquals(const char* data, int len);
89 void AssertReadStarts(const char* data, int len);
90 void AssertReadReturns(const char* data, int len);
91 void AssertAsyncWriteSucceeds(const char* data, int len);
92 void AssertWriteReturns(const char* data, int len, int rv);
93 void AssertWriteLength(int len);
94 void AssertAsyncWriteWithReadsSucceeds(const char* data, int len,
97 void AddAuthToCache() {
98 const base::string16 kFoo(base::ASCIIToUTF16("foo"));
99 const base::string16 kBar(base::ASCIIToUTF16("bar"));
100 session_->http_auth_cache()->Add(GURL(kProxyUrl),
102 HttpAuth::AUTH_SCHEME_BASIC,
103 "Basic realm=MyRealm1",
104 AuthCredentials(kFoo, kBar),
108 void Run(int steps) {
109 data_->StopAfter(steps);
113 void CloseSpdySession(net::Error error, const std::string& description) {
114 spdy_session_->CloseSessionOnError(error, description);
117 SpdyTestUtil spdy_util_;
118 scoped_ptr<SpdyProxyClientSocket> sock_;
119 TestCompletionCallback read_callback_;
120 TestCompletionCallback write_callback_;
121 scoped_ptr<DeterministicSocketData> data_;
122 CapturingBoundNetLog net_log_;
125 scoped_refptr<HttpNetworkSession> session_;
126 scoped_refptr<IOBuffer> read_buf_;
127 SpdySessionDependencies session_deps_;
128 MockConnect connect_data_;
129 base::WeakPtr<SpdySession> spdy_session_;
130 BufferedSpdyFramer framer_;
132 std::string user_agent_;
134 HostPortPair proxy_host_port_;
135 HostPortPair endpoint_host_port_pair_;
137 SpdySessionKey endpoint_spdy_session_key_;
139 DISALLOW_COPY_AND_ASSIGN(SpdyProxyClientSocketTest);
142 INSTANTIATE_TEST_CASE_P(
144 SpdyProxyClientSocketTest,
145 testing::Values(kProtoDeprecatedSPDY2,
146 kProtoSPDY3, kProtoSPDY31, kProtoSPDY4));
148 SpdyProxyClientSocketTest::SpdyProxyClientSocketTest()
149 : spdy_util_(GetParam()),
152 session_deps_(GetParam()),
153 connect_data_(SYNCHRONOUS, OK),
154 framer_(spdy_util_.spdy_version(), false),
155 user_agent_(kUserAgent),
157 proxy_host_port_(kProxyHost, kProxyPort),
158 endpoint_host_port_pair_(kOriginHost, kOriginPort),
159 proxy_(ProxyServer::SCHEME_HTTPS, proxy_host_port_),
160 endpoint_spdy_session_key_(endpoint_host_port_pair_,
162 PRIVACY_MODE_DISABLED) {
163 session_deps_.net_log = net_log_.bound().net_log();
166 void SpdyProxyClientSocketTest::TearDown() {
168 if (session_.get() != NULL)
169 session_->spdy_session_pool()->CloseAllSessions();
171 // Empty the current queue.
172 base::MessageLoop::current()->RunUntilIdle();
173 PlatformTest::TearDown();
176 void SpdyProxyClientSocketTest::Initialize(MockRead* reads,
179 size_t writes_count) {
180 data_.reset(new DeterministicSocketData(reads, reads_count,
181 writes, writes_count));
182 data_->set_connect_data(connect_data_);
185 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
187 session_deps_.host_resolver->set_synchronous_mode(true);
189 session_ = SpdySessionDependencies::SpdyCreateSessionDeterministic(
192 // Creates the SPDY session and stream.
194 CreateInsecureSpdySession(
195 session_, endpoint_spdy_session_key_, BoundNetLog());
196 base::WeakPtr<SpdyStream> spdy_stream(
197 CreateStreamSynchronously(
198 SPDY_BIDIRECTIONAL_STREAM, spdy_session_, url_, LOWEST,
200 ASSERT_TRUE(spdy_stream.get() != NULL);
202 // Create the SpdyProxyClientSocket.
204 new SpdyProxyClientSocket(spdy_stream, user_agent_,
205 endpoint_host_port_pair_, url_,
206 proxy_host_port_, net_log_.bound(),
207 session_->http_auth_cache(),
208 session_->http_auth_handler_factory()));
211 scoped_refptr<IOBufferWithSize> SpdyProxyClientSocketTest::CreateBuffer(
212 const char* data, int size) {
213 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(size));
214 memcpy(buf->data(), data, size);
218 void SpdyProxyClientSocketTest::AssertConnectSucceeds() {
219 ASSERT_EQ(ERR_IO_PENDING, sock_->Connect(read_callback_.callback()));
221 ASSERT_EQ(OK, read_callback_.WaitForResult());
224 void SpdyProxyClientSocketTest::AssertConnectFails(int result) {
225 ASSERT_EQ(ERR_IO_PENDING, sock_->Connect(read_callback_.callback()));
227 ASSERT_EQ(result, read_callback_.WaitForResult());
230 void SpdyProxyClientSocketTest::AssertConnectionEstablished() {
231 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
232 ASSERT_TRUE(response != NULL);
233 ASSERT_EQ(200, response->headers->response_code());
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 void SpdyProxyClientSocketTest::PopulateConnectRequestIR(
315 SpdySynStreamIR* syn_ir) {
316 spdy_util_.SetPriority(LOWEST, syn_ir);
317 syn_ir->SetHeader(spdy_util_.GetMethodKey(), "CONNECT");
318 syn_ir->SetHeader(spdy_util_.GetPathKey(), kOriginHostPort);
319 syn_ir->SetHeader(spdy_util_.GetHostKey(), kOriginHost);
320 syn_ir->SetHeader("user-agent", kUserAgent);
321 spdy_util_.MaybeAddVersionHeader(syn_ir);
324 void SpdyProxyClientSocketTest::PopulateConnectReplyIR(SpdySynReplyIR* reply_ir,
325 const char* status) {
326 reply_ir->SetHeader(spdy_util_.GetStatusKey(), status);
327 spdy_util_.MaybeAddVersionHeader(reply_ir);
330 // Constructs a standard SPDY SYN_STREAM frame for a CONNECT request.
332 SpdyProxyClientSocketTest::ConstructConnectRequestFrame() {
333 SpdySynStreamIR syn_ir(kStreamId);
334 PopulateConnectRequestIR(&syn_ir);
335 return spdy_util_.CreateFramer(false)->SerializeFrame(syn_ir);
338 // Constructs a SPDY SYN_STREAM frame for a CONNECT request which includes
339 // Proxy-Authorization headers.
340 SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectAuthRequestFrame() {
341 SpdySynStreamIR syn_ir(kStreamId);
342 PopulateConnectRequestIR(&syn_ir);
343 syn_ir.SetHeader("proxy-authorization", "Basic Zm9vOmJhcg==");
344 return spdy_util_.CreateFramer(false)->SerializeFrame(syn_ir);
347 // Constructs a standard SPDY SYN_REPLY frame to match the SPDY CONNECT.
348 SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectReplyFrame() {
349 SpdySynReplyIR reply_ir(kStreamId);
350 PopulateConnectReplyIR(&reply_ir, "200");
351 return spdy_util_.CreateFramer(false)->SerializeFrame(reply_ir);
354 // Constructs a standard SPDY SYN_REPLY frame to match the SPDY CONNECT,
355 // including Proxy-Authenticate headers.
356 SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectAuthReplyFrame() {
357 SpdySynReplyIR reply_ir(kStreamId);
358 PopulateConnectReplyIR(&reply_ir, "407");
359 reply_ir.SetHeader("proxy-authenticate", "Basic realm=\"MyRealm1\"");
360 return framer_.SerializeFrame(reply_ir);
363 // Constructs a SPDY SYN_REPLY frame with an HTTP 302 redirect.
364 SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectRedirectReplyFrame() {
365 SpdySynReplyIR reply_ir(kStreamId);
366 PopulateConnectReplyIR(&reply_ir, "302");
367 reply_ir.SetHeader("location", kRedirectUrl);
368 reply_ir.SetHeader("set-cookie", "foo=bar");
369 return framer_.SerializeFrame(reply_ir);
372 // Constructs a SPDY SYN_REPLY frame with an HTTP 500 error.
373 SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectErrorReplyFrame() {
374 SpdySynReplyIR reply_ir(kStreamId);
375 PopulateConnectReplyIR(&reply_ir, "500");
376 return framer_.SerializeFrame(reply_ir);
379 SpdyFrame* SpdyProxyClientSocketTest::ConstructBodyFrame(
382 return framer_.CreateDataFrame(kStreamId, data, length, DATA_FLAG_NONE);
385 // ----------- Connect
387 TEST_P(SpdyProxyClientSocketTest, ConnectSendsCorrectRequest) {
388 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
389 MockWrite writes[] = {
390 CreateMockWrite(*conn, 0, SYNCHRONOUS),
393 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
395 CreateMockRead(*resp, 1, ASYNC),
396 MockRead(ASYNC, 0, 2), // EOF
399 Initialize(reads, arraysize(reads), writes, arraysize(writes));
401 ASSERT_FALSE(sock_->IsConnected());
403 AssertConnectSucceeds();
405 AssertConnectionEstablished();
408 TEST_P(SpdyProxyClientSocketTest, ConnectWithAuthRequested) {
409 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
410 MockWrite writes[] = {
411 CreateMockWrite(*conn, 0, SYNCHRONOUS),
414 scoped_ptr<SpdyFrame> resp(ConstructConnectAuthReplyFrame());
416 CreateMockRead(*resp, 1, ASYNC),
417 MockRead(ASYNC, 0, 2), // EOF
420 Initialize(reads, arraysize(reads), writes, arraysize(writes));
422 AssertConnectFails(ERR_PROXY_AUTH_REQUESTED);
424 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
425 ASSERT_TRUE(response != NULL);
426 ASSERT_EQ(407, response->headers->response_code());
429 TEST_P(SpdyProxyClientSocketTest, ConnectWithAuthCredentials) {
430 scoped_ptr<SpdyFrame> conn(ConstructConnectAuthRequestFrame());
431 MockWrite writes[] = {
432 CreateMockWrite(*conn, 0, SYNCHRONOUS),
435 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
437 CreateMockRead(*resp, 1, ASYNC),
438 MockRead(ASYNC, 0, 2), // EOF
441 Initialize(reads, arraysize(reads), writes, arraysize(writes));
444 AssertConnectSucceeds();
446 AssertConnectionEstablished();
449 TEST_P(SpdyProxyClientSocketTest, ConnectRedirects) {
450 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
451 MockWrite writes[] = {
452 CreateMockWrite(*conn, 0, SYNCHRONOUS),
455 scoped_ptr<SpdyFrame> resp(ConstructConnectRedirectReplyFrame());
457 CreateMockRead(*resp, 1, ASYNC),
458 MockRead(ASYNC, 0, 2), // EOF
461 Initialize(reads, arraysize(reads), writes, arraysize(writes));
463 AssertConnectFails(ERR_HTTPS_PROXY_TUNNEL_RESPONSE);
465 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
466 ASSERT_TRUE(response != NULL);
468 const HttpResponseHeaders* headers = response->headers.get();
469 ASSERT_EQ(302, headers->response_code());
470 ASSERT_FALSE(headers->HasHeader("set-cookie"));
471 ASSERT_TRUE(headers->HasHeaderValue("content-length", "0"));
473 std::string location;
474 ASSERT_TRUE(headers->IsRedirect(&location));
475 ASSERT_EQ(location, kRedirectUrl);
478 TEST_P(SpdyProxyClientSocketTest, ConnectFails) {
479 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
480 MockWrite writes[] = {
481 CreateMockWrite(*conn, 0, SYNCHRONOUS),
484 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
486 MockRead(ASYNC, 0, 1), // EOF
489 Initialize(reads, arraysize(reads), writes, arraysize(writes));
491 ASSERT_FALSE(sock_->IsConnected());
493 AssertConnectFails(ERR_CONNECTION_CLOSED);
495 ASSERT_FALSE(sock_->IsConnected());
498 // ----------- WasEverUsed
500 TEST_P(SpdyProxyClientSocketTest, WasEverUsedReturnsCorrectValues) {
501 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
502 MockWrite writes[] = {
503 CreateMockWrite(*conn, 0, SYNCHRONOUS),
506 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
508 CreateMockRead(*resp, 1, ASYNC),
509 MockRead(ASYNC, 0, 2), // EOF
512 Initialize(reads, arraysize(reads), writes, arraysize(writes));
514 EXPECT_FALSE(sock_->WasEverUsed());
515 AssertConnectSucceeds();
516 EXPECT_TRUE(sock_->WasEverUsed());
518 EXPECT_TRUE(sock_->WasEverUsed());
521 // ----------- GetPeerAddress
523 TEST_P(SpdyProxyClientSocketTest, GetPeerAddressReturnsCorrectValues) {
524 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
525 MockWrite writes[] = {
526 CreateMockWrite(*conn, 0, SYNCHRONOUS),
529 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
531 CreateMockRead(*resp, 1, ASYNC),
532 MockRead(ASYNC, 0, 2), // EOF
535 Initialize(reads, arraysize(reads), writes, arraysize(writes));
537 net::IPEndPoint addr;
538 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr));
540 AssertConnectSucceeds();
541 EXPECT_TRUE(sock_->IsConnected());
542 EXPECT_EQ(OK, sock_->GetPeerAddress(&addr));
546 EXPECT_FALSE(sock_->IsConnected());
547 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr));
551 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr));
556 TEST_P(SpdyProxyClientSocketTest, WriteSendsDataInDataFrame) {
557 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
558 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
559 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
560 MockWrite writes[] = {
561 CreateMockWrite(*conn, 0, SYNCHRONOUS),
562 CreateMockWrite(*msg1, 2, SYNCHRONOUS),
563 CreateMockWrite(*msg2, 3, SYNCHRONOUS),
566 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
568 CreateMockRead(*resp, 1, ASYNC),
569 MockRead(ASYNC, 0, 4), // EOF
572 Initialize(reads, arraysize(reads), writes, arraysize(writes));
574 AssertConnectSucceeds();
576 AssertAsyncWriteSucceeds(kMsg1, kLen1);
577 AssertAsyncWriteSucceeds(kMsg2, kLen2);
580 TEST_P(SpdyProxyClientSocketTest, WriteSplitsLargeDataIntoMultipleFrames) {
581 std::string chunk_data(kMaxSpdyFrameChunkSize, 'x');
582 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
583 scoped_ptr<SpdyFrame> chunk(ConstructBodyFrame(chunk_data.data(),
584 chunk_data.length()));
585 MockWrite writes[] = {
586 CreateMockWrite(*conn, 0, SYNCHRONOUS),
587 CreateMockWrite(*chunk, 2, SYNCHRONOUS),
588 CreateMockWrite(*chunk, 3, SYNCHRONOUS),
589 CreateMockWrite(*chunk, 4, SYNCHRONOUS)
592 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
594 CreateMockRead(*resp, 1, ASYNC),
595 MockRead(ASYNC, 0, 5), // EOF
598 Initialize(reads, arraysize(reads), writes, arraysize(writes));
600 AssertConnectSucceeds();
602 std::string big_data(kMaxSpdyFrameChunkSize * 3, 'x');
603 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(big_data.data(),
606 EXPECT_EQ(ERR_IO_PENDING,
607 sock_->Write(buf.get(), buf->size(), write_callback_.callback()));
610 EXPECT_EQ(buf->size(), write_callback_.WaitForResult());
615 TEST_P(SpdyProxyClientSocketTest, ReadReadsDataInDataFrame) {
616 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
617 MockWrite writes[] = {
618 CreateMockWrite(*conn, 0, SYNCHRONOUS),
621 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
622 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
624 CreateMockRead(*resp, 1, ASYNC),
625 CreateMockRead(*msg1, 2, ASYNC),
626 MockRead(ASYNC, 0, 3), // EOF
629 Initialize(reads, arraysize(reads), writes, arraysize(writes));
631 AssertConnectSucceeds();
633 Run(1); // SpdySession consumes the next read and sends it to
634 // sock_ to be buffered.
635 AssertSyncReadEquals(kMsg1, kLen1);
638 TEST_P(SpdyProxyClientSocketTest, ReadDataFromBufferedFrames) {
639 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
640 MockWrite writes[] = {
641 CreateMockWrite(*conn, 0, SYNCHRONOUS),
644 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
645 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
646 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
648 CreateMockRead(*resp, 1, ASYNC),
649 CreateMockRead(*msg1, 2, ASYNC),
650 CreateMockRead(*msg2, 3, ASYNC),
651 MockRead(ASYNC, 0, 4), // EOF
654 Initialize(reads, arraysize(reads), writes, arraysize(writes));
656 AssertConnectSucceeds();
658 Run(1); // SpdySession consumes the next read and sends it to
659 // sock_ to be buffered.
660 AssertSyncReadEquals(kMsg1, kLen1);
661 Run(1); // SpdySession consumes the next read and sends it to
662 // sock_ to be buffered.
663 AssertSyncReadEquals(kMsg2, kLen2);
666 TEST_P(SpdyProxyClientSocketTest, ReadDataMultipleBufferedFrames) {
667 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
668 MockWrite writes[] = {
669 CreateMockWrite(*conn, 0, SYNCHRONOUS),
672 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
673 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
674 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
676 CreateMockRead(*resp, 1, ASYNC),
677 CreateMockRead(*msg1, 2, ASYNC),
678 CreateMockRead(*msg2, 3, ASYNC),
679 MockRead(ASYNC, 0, 4), // EOF
682 Initialize(reads, arraysize(reads), writes, arraysize(writes));
684 AssertConnectSucceeds();
686 Run(2); // SpdySession consumes the next two reads and sends then to
687 // sock_ to be buffered.
688 AssertSyncReadEquals(kMsg1, kLen1);
689 AssertSyncReadEquals(kMsg2, kLen2);
692 TEST_P(SpdyProxyClientSocketTest,
693 LargeReadWillMergeDataFromDifferentFrames) {
694 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
695 MockWrite writes[] = {
696 CreateMockWrite(*conn, 0, SYNCHRONOUS),
699 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
700 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
701 scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
703 CreateMockRead(*resp, 1, ASYNC),
704 CreateMockRead(*msg3, 2, ASYNC),
705 CreateMockRead(*msg3, 3, ASYNC),
706 MockRead(ASYNC, 0, 4), // EOF
709 Initialize(reads, arraysize(reads), writes, arraysize(writes));
711 AssertConnectSucceeds();
713 Run(2); // SpdySession consumes the next two reads and sends then to
714 // sock_ to be buffered.
715 // The payload from two data frames, each with kMsg3 will be combined
716 // together into a single read().
717 AssertSyncReadEquals(kMsg33, kLen33);
720 TEST_P(SpdyProxyClientSocketTest, MultipleShortReadsThenMoreRead) {
721 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
722 MockWrite writes[] = {
723 CreateMockWrite(*conn, 0, SYNCHRONOUS),
726 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
727 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
728 scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
729 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
731 CreateMockRead(*resp, 1, ASYNC),
732 CreateMockRead(*msg1, 2, ASYNC),
733 CreateMockRead(*msg3, 3, ASYNC),
734 CreateMockRead(*msg3, 4, ASYNC),
735 CreateMockRead(*msg2, 5, ASYNC),
736 MockRead(ASYNC, 0, 6), // EOF
739 Initialize(reads, arraysize(reads), writes, arraysize(writes));
741 AssertConnectSucceeds();
743 Run(4); // SpdySession consumes the next four reads and sends then to
744 // sock_ to be buffered.
745 AssertSyncReadEquals(kMsg1, kLen1);
746 // The payload from two data frames, each with kMsg3 will be combined
747 // together into a single read().
748 AssertSyncReadEquals(kMsg33, kLen33);
749 AssertSyncReadEquals(kMsg2, kLen2);
752 TEST_P(SpdyProxyClientSocketTest, ReadWillSplitDataFromLargeFrame) {
753 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
754 MockWrite writes[] = {
755 CreateMockWrite(*conn, 0, SYNCHRONOUS),
758 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
759 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
760 scoped_ptr<SpdyFrame> msg33(ConstructBodyFrame(kMsg33, kLen33));
761 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
763 CreateMockRead(*resp, 1, ASYNC),
764 CreateMockRead(*msg1, 2, ASYNC),
765 CreateMockRead(*msg33, 3, ASYNC),
766 MockRead(ASYNC, 0, 4), // EOF
769 Initialize(reads, arraysize(reads), writes, arraysize(writes));
771 AssertConnectSucceeds();
773 Run(2); // SpdySession consumes the next two reads and sends then to
774 // sock_ to be buffered.
775 AssertSyncReadEquals(kMsg1, kLen1);
776 // The payload from the single large data frame will be read across
777 // two different reads.
778 AssertSyncReadEquals(kMsg3, kLen3);
779 AssertSyncReadEquals(kMsg3, kLen3);
782 TEST_P(SpdyProxyClientSocketTest, MultipleReadsFromSameLargeFrame) {
783 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
784 MockWrite writes[] = {
785 CreateMockWrite(*conn, 0, SYNCHRONOUS),
788 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
789 scoped_ptr<SpdyFrame> msg333(ConstructBodyFrame(kMsg333, kLen333));
791 CreateMockRead(*resp, 1, ASYNC),
792 CreateMockRead(*msg333, 2, ASYNC),
793 MockRead(ASYNC, 0, 3), // EOF
796 Initialize(reads, arraysize(reads), writes, arraysize(writes));
798 AssertConnectSucceeds();
800 Run(1); // SpdySession consumes the next read and sends it to
801 // sock_ to be buffered.
802 // The payload from the single large data frame will be read across
803 // two different reads.
804 AssertSyncReadEquals(kMsg33, kLen33);
806 // Now attempt to do a read of more data than remains buffered
807 scoped_refptr<IOBuffer> buf(new IOBuffer(kLen33));
808 ASSERT_EQ(kLen3, sock_->Read(buf.get(), kLen33, read_callback_.callback()));
809 ASSERT_EQ(std::string(kMsg3, kLen3), std::string(buf->data(), kLen3));
810 ASSERT_TRUE(sock_->IsConnected());
813 TEST_P(SpdyProxyClientSocketTest, ReadAuthResponseBody) {
814 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
815 MockWrite writes[] = {
816 CreateMockWrite(*conn, 0, SYNCHRONOUS),
819 scoped_ptr<SpdyFrame> resp(ConstructConnectAuthReplyFrame());
820 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
821 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
823 CreateMockRead(*resp, 1, ASYNC),
824 CreateMockRead(*msg1, 2, ASYNC),
825 CreateMockRead(*msg2, 3, ASYNC),
826 MockRead(ASYNC, 0, 4), // EOF
829 Initialize(reads, arraysize(reads), writes, arraysize(writes));
831 AssertConnectFails(ERR_PROXY_AUTH_REQUESTED);
833 Run(2); // SpdySession consumes the next two reads and sends then to
834 // sock_ to be buffered.
835 AssertSyncReadEquals(kMsg1, kLen1);
836 AssertSyncReadEquals(kMsg2, kLen2);
839 TEST_P(SpdyProxyClientSocketTest, ReadErrorResponseBody) {
840 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
841 MockWrite writes[] = {
842 CreateMockWrite(*conn, 0, SYNCHRONOUS),
845 scoped_ptr<SpdyFrame> resp(ConstructConnectErrorReplyFrame());
846 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
847 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
849 CreateMockRead(*resp, 1, ASYNC),
850 CreateMockRead(*msg1, 2, ASYNC),
851 CreateMockRead(*msg2, 3, ASYNC),
852 MockRead(ASYNC, 0, 4), // EOF
855 Initialize(reads, arraysize(reads), writes, arraysize(writes));
857 AssertConnectFails(ERR_TUNNEL_CONNECTION_FAILED);
860 // ----------- Reads and Writes
862 TEST_P(SpdyProxyClientSocketTest, AsyncReadAroundWrite) {
863 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
864 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
865 MockWrite writes[] = {
866 CreateMockWrite(*conn, 0, SYNCHRONOUS),
867 CreateMockWrite(*msg2, 3, SYNCHRONOUS),
870 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
871 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
872 scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
874 CreateMockRead(*resp, 1, ASYNC),
875 CreateMockRead(*msg1, 2, ASYNC), // sync read
876 CreateMockRead(*msg3, 4, ASYNC), // async read
877 MockRead(ASYNC, 0, 5), // EOF
880 Initialize(reads, arraysize(reads), writes, arraysize(writes));
882 AssertConnectSucceeds();
885 AssertSyncReadEquals(kMsg1, kLen1);
887 AssertReadStarts(kMsg3, kLen3);
888 // Read should block until after the write succeeds
890 AssertAsyncWriteSucceeds(kMsg2, kLen2); // Runs 1 step
892 ASSERT_FALSE(read_callback_.have_result());
894 // Now the read will return
895 AssertReadReturns(kMsg3, kLen3);
898 TEST_P(SpdyProxyClientSocketTest, AsyncWriteAroundReads) {
899 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
900 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
901 MockWrite writes[] = {
902 CreateMockWrite(*conn, 0, SYNCHRONOUS),
903 CreateMockWrite(*msg2, 4, ASYNC),
906 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
907 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
908 scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
910 CreateMockRead(*resp, 1, ASYNC),
911 CreateMockRead(*msg1, 2, ASYNC),
912 CreateMockRead(*msg3, 3, ASYNC),
913 MockRead(ASYNC, 0, 5), // EOF
916 Initialize(reads, arraysize(reads), writes, arraysize(writes));
918 AssertConnectSucceeds();
921 AssertSyncReadEquals(kMsg1, kLen1);
922 // Write should block until the read completes
923 AssertWriteReturns(kMsg2, kLen2, ERR_IO_PENDING);
925 AssertAsyncReadEquals(kMsg3, kLen3);
927 ASSERT_FALSE(write_callback_.have_result());
929 // Now the write will complete
931 AssertWriteLength(kLen2);
934 // ----------- Reading/Writing on Closed socket
936 // Reading from an already closed socket should return 0
937 TEST_P(SpdyProxyClientSocketTest, ReadOnClosedSocketReturnsZero) {
938 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
939 MockWrite writes[] = {
940 CreateMockWrite(*conn, 0, SYNCHRONOUS),
943 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
945 CreateMockRead(*resp, 1, ASYNC),
946 MockRead(ASYNC, 0, 2), // EOF
949 Initialize(reads, arraysize(reads), writes, arraysize(writes));
951 AssertConnectSucceeds();
955 ASSERT_FALSE(sock_->IsConnected());
956 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
957 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
958 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
959 ASSERT_FALSE(sock_->IsConnectedAndIdle());
962 // Read pending when socket is closed should return 0
963 TEST_P(SpdyProxyClientSocketTest, PendingReadOnCloseReturnsZero) {
964 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
965 MockWrite writes[] = {
966 CreateMockWrite(*conn, 0, SYNCHRONOUS),
969 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
971 CreateMockRead(*resp, 1, ASYNC),
972 MockRead(ASYNC, 0, 2), // EOF
975 Initialize(reads, arraysize(reads), writes, arraysize(writes));
977 AssertConnectSucceeds();
979 AssertReadStarts(kMsg1, kLen1);
983 ASSERT_EQ(0, read_callback_.WaitForResult());
986 // Reading from a disconnected socket is an error
987 TEST_P(SpdyProxyClientSocketTest,
988 ReadOnDisconnectSocketReturnsNotConnected) {
989 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
990 MockWrite writes[] = {
991 CreateMockWrite(*conn, 0, SYNCHRONOUS),
994 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
996 CreateMockRead(*resp, 1, ASYNC),
997 MockRead(ASYNC, 0, 2), // EOF
1000 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1002 AssertConnectSucceeds();
1004 sock_->Disconnect();
1006 ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED,
1007 sock_->Read(NULL, 1, CompletionCallback()));
1010 // Reading buffered data from an already closed socket should return
1011 // buffered data, then 0.
1012 TEST_P(SpdyProxyClientSocketTest, ReadOnClosedSocketReturnsBufferedData) {
1013 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1014 MockWrite writes[] = {
1015 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1018 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1019 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
1020 MockRead reads[] = {
1021 CreateMockRead(*resp, 1, ASYNC),
1022 CreateMockRead(*msg1, 2, ASYNC),
1023 MockRead(ASYNC, 0, 3), // EOF
1026 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1028 AssertConnectSucceeds();
1032 ASSERT_FALSE(sock_->IsConnected());
1033 scoped_refptr<IOBuffer> buf(new IOBuffer(kLen1));
1034 ASSERT_EQ(kLen1, sock_->Read(buf.get(), kLen1, CompletionCallback()));
1035 ASSERT_EQ(std::string(kMsg1, kLen1), std::string(buf->data(), kLen1));
1037 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
1038 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
1039 sock_->Disconnect();
1040 ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED,
1041 sock_->Read(NULL, 1, CompletionCallback()));
1044 // Calling Write() on a closed socket is an error
1045 TEST_P(SpdyProxyClientSocketTest, WriteOnClosedStream) {
1046 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1047 MockWrite writes[] = {
1048 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1051 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1052 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
1053 MockRead reads[] = {
1054 CreateMockRead(*resp, 1, ASYNC),
1055 MockRead(ASYNC, 0, 2), // EOF
1058 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1060 AssertConnectSucceeds();
1062 Run(1); // Read EOF which will close the stream
1063 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
1064 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED,
1065 sock_->Write(buf.get(), buf->size(), CompletionCallback()));
1068 // Calling Write() on a disconnected socket is an error
1069 TEST_P(SpdyProxyClientSocketTest, WriteOnDisconnectedSocket) {
1070 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1071 MockWrite writes[] = {
1072 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1075 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1076 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
1077 MockRead reads[] = {
1078 CreateMockRead(*resp, 1, ASYNC),
1079 MockRead(ASYNC, 0, 2), // EOF
1082 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1084 AssertConnectSucceeds();
1086 sock_->Disconnect();
1088 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
1089 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED,
1090 sock_->Write(buf.get(), buf->size(), CompletionCallback()));
1093 // If the socket is closed with a pending Write(), the callback
1094 // should be called with ERR_CONNECTION_CLOSED.
1095 TEST_P(SpdyProxyClientSocketTest, WritePendingOnClose) {
1096 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1097 MockWrite writes[] = {
1098 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1099 MockWrite(ASYNC, ERR_ABORTED, 2),
1102 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1103 MockRead reads[] = {
1104 CreateMockRead(*resp, 1, ASYNC),
1105 MockRead(ASYNC, 0, 3), // EOF
1108 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1110 AssertConnectSucceeds();
1112 EXPECT_TRUE(sock_->IsConnected());
1114 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
1115 EXPECT_EQ(ERR_IO_PENDING,
1116 sock_->Write(buf.get(), buf->size(), write_callback_.callback()));
1118 CloseSpdySession(ERR_ABORTED, std::string());
1120 EXPECT_EQ(ERR_CONNECTION_CLOSED, write_callback_.WaitForResult());
1123 // If the socket is Disconnected with a pending Write(), the callback
1124 // should not be called.
1125 TEST_P(SpdyProxyClientSocketTest, DisconnectWithWritePending) {
1126 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1127 MockWrite writes[] = {
1128 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1129 MockWrite(SYNCHRONOUS, 0, 2), // EOF
1132 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1133 MockRead reads[] = {
1134 CreateMockRead(*resp, 1, ASYNC),
1135 MockRead(ASYNC, 0, 3), // EOF
1138 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1140 AssertConnectSucceeds();
1142 EXPECT_TRUE(sock_->IsConnected());
1144 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
1145 EXPECT_EQ(ERR_IO_PENDING,
1146 sock_->Write(buf.get(), buf->size(), write_callback_.callback()));
1148 sock_->Disconnect();
1150 EXPECT_FALSE(sock_->IsConnected());
1151 EXPECT_FALSE(write_callback_.have_result());
1154 // If the socket is Disconnected with a pending Read(), the callback
1155 // should not be called.
1156 TEST_P(SpdyProxyClientSocketTest, DisconnectWithReadPending) {
1157 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1158 MockWrite writes[] = {
1159 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1162 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1163 MockRead reads[] = {
1164 CreateMockRead(*resp, 1, ASYNC),
1165 MockRead(ASYNC, 0, 2), // EOF
1168 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1170 AssertConnectSucceeds();
1172 EXPECT_TRUE(sock_->IsConnected());
1174 scoped_refptr<IOBuffer> buf(new IOBuffer(kLen1));
1175 ASSERT_EQ(ERR_IO_PENDING,
1176 sock_->Read(buf.get(), kLen1, read_callback_.callback()));
1178 sock_->Disconnect();
1180 EXPECT_FALSE(sock_->IsConnected());
1181 EXPECT_FALSE(read_callback_.have_result());
1184 // If the socket is Reset when both a read and write are pending,
1185 // both should be called back.
1186 TEST_P(SpdyProxyClientSocketTest, RstWithReadAndWritePending) {
1187 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1188 MockWrite writes[] = {
1189 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1190 MockWrite(ASYNC, ERR_ABORTED, 3),
1193 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1194 scoped_ptr<SpdyFrame> rst(
1195 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
1196 MockRead reads[] = {
1197 CreateMockRead(*resp, 1, ASYNC),
1198 CreateMockRead(*rst, 2, ASYNC),
1199 MockRead(ASYNC, 0, 4) // EOF
1202 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1204 AssertConnectSucceeds();
1206 EXPECT_TRUE(sock_->IsConnected());
1208 scoped_refptr<IOBuffer> read_buf(new IOBuffer(kLen1));
1209 ASSERT_EQ(ERR_IO_PENDING,
1210 sock_->Read(read_buf.get(), kLen1, read_callback_.callback()));
1212 scoped_refptr<IOBufferWithSize> write_buf(CreateBuffer(kMsg1, kLen1));
1216 write_buf.get(), write_buf->size(), write_callback_.callback()));
1220 EXPECT_TRUE(sock_.get());
1221 EXPECT_TRUE(read_callback_.have_result());
1222 EXPECT_TRUE(write_callback_.have_result());
1225 // Makes sure the proxy client socket's source gets the expected NetLog events
1226 // and only the expected NetLog events (No SpdySession events).
1227 TEST_P(SpdyProxyClientSocketTest, NetLog) {
1228 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1229 MockWrite writes[] = {
1230 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1233 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1234 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
1235 MockRead reads[] = {
1236 CreateMockRead(*resp, 1, ASYNC),
1237 CreateMockRead(*msg1, 2, ASYNC),
1238 MockRead(ASYNC, 0, 3), // EOF
1241 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1243 AssertConnectSucceeds();
1245 Run(1); // SpdySession consumes the next read and sends it to
1246 // sock_ to be buffered.
1247 AssertSyncReadEquals(kMsg1, kLen1);
1249 NetLog::Source sock_source = sock_->NetLog().source();
1252 CapturingNetLog::CapturedEntryList entry_list;
1253 net_log_.GetEntriesForSource(sock_source, &entry_list);
1255 ASSERT_EQ(entry_list.size(), 10u);
1256 EXPECT_TRUE(LogContainsBeginEvent(entry_list, 0, NetLog::TYPE_SOCKET_ALIVE));
1257 EXPECT_TRUE(LogContainsEvent(entry_list, 1,
1258 NetLog::TYPE_SPDY_PROXY_CLIENT_SESSION,
1259 NetLog::PHASE_NONE));
1260 EXPECT_TRUE(LogContainsBeginEvent(entry_list, 2,
1261 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_SEND_REQUEST));
1262 EXPECT_TRUE(LogContainsEvent(entry_list, 3,
1263 NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
1264 NetLog::PHASE_NONE));
1265 EXPECT_TRUE(LogContainsEndEvent(entry_list, 4,
1266 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_SEND_REQUEST));
1267 EXPECT_TRUE(LogContainsBeginEvent(entry_list, 5,
1268 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_READ_HEADERS));
1269 EXPECT_TRUE(LogContainsEvent(entry_list, 6,
1270 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
1271 NetLog::PHASE_NONE));
1272 EXPECT_TRUE(LogContainsEndEvent(entry_list, 7,
1273 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_READ_HEADERS));
1274 EXPECT_TRUE(LogContainsEvent(entry_list, 8,
1275 NetLog::TYPE_SOCKET_BYTES_RECEIVED,
1276 NetLog::PHASE_NONE));
1277 EXPECT_TRUE(LogContainsEndEvent(entry_list, 9, NetLog::TYPE_SOCKET_ALIVE));
1280 // CompletionCallback that causes the SpdyProxyClientSocket to be
1281 // deleted when Run is invoked.
1282 class DeleteSockCallback : public TestCompletionCallbackBase {
1284 explicit DeleteSockCallback(scoped_ptr<SpdyProxyClientSocket>* sock)
1286 callback_(base::Bind(&DeleteSockCallback::OnComplete,
1287 base::Unretained(this))) {
1290 virtual ~DeleteSockCallback() {
1293 const CompletionCallback& callback() const { return callback_; }
1296 void OnComplete(int result) {
1301 scoped_ptr<SpdyProxyClientSocket>* sock_;
1302 CompletionCallback callback_;
1304 DISALLOW_COPY_AND_ASSIGN(DeleteSockCallback);
1307 // If the socket is Reset when both a read and write are pending, and the
1308 // read callback causes the socket to be deleted, the write callback should
1310 TEST_P(SpdyProxyClientSocketTest, RstWithReadAndWritePendingDelete) {
1311 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1312 MockWrite writes[] = {
1313 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1314 MockWrite(ASYNC, ERR_ABORTED, 3),
1317 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1318 scoped_ptr<SpdyFrame> rst(
1319 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
1320 MockRead reads[] = {
1321 CreateMockRead(*resp, 1, ASYNC),
1322 CreateMockRead(*rst, 2, ASYNC),
1323 MockRead(ASYNC, 0, 4), // EOF
1326 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1328 AssertConnectSucceeds();
1330 EXPECT_TRUE(sock_->IsConnected());
1332 DeleteSockCallback read_callback(&sock_);
1334 scoped_refptr<IOBuffer> read_buf(new IOBuffer(kLen1));
1335 ASSERT_EQ(ERR_IO_PENDING,
1336 sock_->Read(read_buf.get(), kLen1, read_callback.callback()));
1338 scoped_refptr<IOBufferWithSize> write_buf(CreateBuffer(kMsg1, kLen1));
1342 write_buf.get(), write_buf->size(), write_callback_.callback()));
1346 EXPECT_FALSE(sock_.get());
1347 EXPECT_TRUE(read_callback.have_result());
1348 EXPECT_FALSE(write_callback_.have_result());