[Android] Remove android_commands uses from build/android/.
[chromium-blink-merge.git] / net / spdy / spdy_proxy_client_socket_unittest.cc
blobc870f18bdf703a284723436529dc27334c053d61
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/spdy/spdy_proxy_client_socket.h"
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "net/base/address_list.h"
11 #include "net/base/test_completion_callback.h"
12 #include "net/base/winsock_init.h"
13 #include "net/dns/mock_host_resolver.h"
14 #include "net/http/http_response_headers.h"
15 #include "net/http/http_response_info.h"
16 #include "net/log/capturing_net_log.h"
17 #include "net/log/net_log.h"
18 #include "net/log/net_log_unittest.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 //-----------------------------------------------------------------------------
33 namespace {
35 static const char kRequestUrl[] = "https://www.google.com/";
36 static const char kOriginHost[] = "www.google.com";
37 static const int kOriginPort = 443;
38 static const char kOriginHostPort[] = "www.google.com:443";
39 static const char kProxyUrl[] = "https://myproxy:6121/";
40 static const char kProxyHost[] = "myproxy";
41 static const int kProxyPort = 6121;
42 static const char kUserAgent[] = "Mozilla/1.0";
44 static const int kStreamId = 1;
46 static const char kMsg1[] = "\0hello!\xff";
47 static const int kLen1 = 8;
48 static const char kMsg2[] = "\0a2345678\0";
49 static const int kLen2 = 10;
50 static const char kMsg3[] = "bye!";
51 static const int kLen3 = 4;
52 static const char kMsg33[] = "bye!bye!";
53 static const int kLen33 = kLen3 + kLen3;
54 static const char kMsg333[] = "bye!bye!bye!";
55 static const int kLen333 = kLen3 + kLen3 + kLen3;
57 static const char kRedirectUrl[] = "https://example.com/";
59 } // anonymous namespace
61 namespace net {
63 class SpdyProxyClientSocketTest
64 : public PlatformTest,
65 public testing::WithParamInterface<NextProto> {
66 public:
67 SpdyProxyClientSocketTest();
69 void TearDown() override;
71 protected:
72 void Initialize(MockRead* reads, size_t reads_count, MockWrite* writes,
73 size_t writes_count);
74 void PopulateConnectRequestIR(SpdyHeaderBlock* syn_ir);
75 void PopulateConnectReplyIR(SpdyHeaderBlock* block, 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,
95 int num_reads);
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),
101 "MyRealm1",
102 HttpAuth::AUTH_SCHEME_BASIC,
103 "Basic realm=MyRealm1",
104 AuthCredentials(kFoo, kBar),
105 "/");
108 void Run(int steps) {
109 data_->StopAfter(steps);
110 data_->Run();
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_;
124 private:
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_;
133 GURL url_;
134 HostPortPair proxy_host_port_;
135 HostPortPair endpoint_host_port_pair_;
136 ProxyServer proxy_;
137 SpdySessionKey endpoint_spdy_session_key_;
139 DISALLOW_COPY_AND_ASSIGN(SpdyProxyClientSocketTest);
142 INSTANTIATE_TEST_CASE_P(NextProto,
143 SpdyProxyClientSocketTest,
144 testing::Values(kProtoSPDY31,
145 kProtoSPDY4_14,
146 kProtoSPDY4));
148 SpdyProxyClientSocketTest::SpdyProxyClientSocketTest()
149 : spdy_util_(GetParam()),
150 session_(NULL),
151 read_buf_(NULL),
152 session_deps_(GetParam()),
153 connect_data_(SYNCHRONOUS, OK),
154 framer_(spdy_util_.spdy_version(), false),
155 user_agent_(kUserAgent),
156 url_(kRequestUrl),
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_,
161 proxy_,
162 PRIVACY_MODE_DISABLED) {
163 session_deps_.net_log = net_log_.bound().net_log();
166 void SpdyProxyClientSocketTest::TearDown() {
167 if (session_.get() != NULL)
168 session_->spdy_session_pool()->CloseAllSessions();
170 // Empty the current queue.
171 base::MessageLoop::current()->RunUntilIdle();
172 PlatformTest::TearDown();
175 void SpdyProxyClientSocketTest::Initialize(MockRead* reads,
176 size_t reads_count,
177 MockWrite* writes,
178 size_t writes_count) {
179 data_.reset(new DeterministicSocketData(reads, reads_count,
180 writes, writes_count));
181 data_->set_connect_data(connect_data_);
182 data_->SetStop(2);
184 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
185 data_.get());
186 session_deps_.host_resolver->set_synchronous_mode(true);
188 session_ = SpdySessionDependencies::SpdyCreateSessionDeterministic(
189 &session_deps_);
191 // Creates the SPDY session and stream.
192 spdy_session_ =
193 CreateInsecureSpdySession(
194 session_, endpoint_spdy_session_key_, BoundNetLog());
195 base::WeakPtr<SpdyStream> spdy_stream(
196 CreateStreamSynchronously(
197 SPDY_BIDIRECTIONAL_STREAM, spdy_session_, url_, LOWEST,
198 net_log_.bound()));
199 ASSERT_TRUE(spdy_stream.get() != NULL);
201 // Create the SpdyProxyClientSocket.
202 sock_.reset(new SpdyProxyClientSocket(
203 spdy_stream, user_agent_, endpoint_host_port_pair_, proxy_host_port_,
204 net_log_.bound(), session_->http_auth_cache(),
205 session_->http_auth_handler_factory()));
208 scoped_refptr<IOBufferWithSize> SpdyProxyClientSocketTest::CreateBuffer(
209 const char* data, int size) {
210 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(size));
211 memcpy(buf->data(), data, size);
212 return buf;
215 void SpdyProxyClientSocketTest::AssertConnectSucceeds() {
216 ASSERT_EQ(ERR_IO_PENDING, sock_->Connect(read_callback_.callback()));
217 data_->Run();
218 ASSERT_EQ(OK, read_callback_.WaitForResult());
221 void SpdyProxyClientSocketTest::AssertConnectFails(int result) {
222 ASSERT_EQ(ERR_IO_PENDING, sock_->Connect(read_callback_.callback()));
223 data_->Run();
224 ASSERT_EQ(result, read_callback_.WaitForResult());
227 void SpdyProxyClientSocketTest::AssertConnectionEstablished() {
228 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
229 ASSERT_TRUE(response != NULL);
230 ASSERT_EQ(200, response->headers->response_code());
233 void SpdyProxyClientSocketTest::AssertSyncReadEquals(const char* data,
234 int len) {
235 scoped_refptr<IOBuffer> buf(new IOBuffer(len));
236 ASSERT_EQ(len, sock_->Read(buf.get(), len, CompletionCallback()));
237 ASSERT_EQ(std::string(data, len), std::string(buf->data(), len));
238 ASSERT_TRUE(sock_->IsConnected());
241 void SpdyProxyClientSocketTest::AssertAsyncReadEquals(const char* data,
242 int len) {
243 data_->StopAfter(1);
244 // Issue the read, which will be completed asynchronously
245 scoped_refptr<IOBuffer> buf(new IOBuffer(len));
246 ASSERT_EQ(ERR_IO_PENDING,
247 sock_->Read(buf.get(), len, read_callback_.callback()));
248 EXPECT_TRUE(sock_->IsConnected());
249 data_->Run();
251 EXPECT_TRUE(sock_->IsConnected());
253 // Now the read will return
254 EXPECT_EQ(len, read_callback_.WaitForResult());
255 ASSERT_EQ(std::string(data, len), std::string(buf->data(), len));
258 void SpdyProxyClientSocketTest::AssertReadStarts(const char* data,
259 int len) {
260 data_->StopAfter(1);
261 // Issue the read, which will be completed asynchronously
262 read_buf_ = new IOBuffer(len);
263 ASSERT_EQ(ERR_IO_PENDING,
264 sock_->Read(read_buf_.get(), len, read_callback_.callback()));
265 EXPECT_TRUE(sock_->IsConnected());
268 void SpdyProxyClientSocketTest::AssertReadReturns(const char* data,
269 int len) {
270 EXPECT_TRUE(sock_->IsConnected());
272 // Now the read will return
273 EXPECT_EQ(len, read_callback_.WaitForResult());
274 ASSERT_EQ(std::string(data, len), std::string(read_buf_->data(), len));
277 void SpdyProxyClientSocketTest::AssertAsyncWriteSucceeds(const char* data,
278 int len) {
279 AssertWriteReturns(data, len, ERR_IO_PENDING);
280 data_->RunFor(1);
281 AssertWriteLength(len);
284 void SpdyProxyClientSocketTest::AssertWriteReturns(const char* data,
285 int len,
286 int rv) {
287 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(data, len));
288 EXPECT_EQ(rv,
289 sock_->Write(buf.get(), buf->size(), write_callback_.callback()));
292 void SpdyProxyClientSocketTest::AssertWriteLength(int len) {
293 EXPECT_EQ(len, write_callback_.WaitForResult());
296 void SpdyProxyClientSocketTest::AssertAsyncWriteWithReadsSucceeds(
297 const char* data, int len, int num_reads) {
298 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(data, len));
300 EXPECT_EQ(ERR_IO_PENDING,
301 sock_->Write(buf.get(), buf->size(), write_callback_.callback()));
303 for (int i = 0; i < num_reads; i++) {
304 Run(1);
305 AssertSyncReadEquals(kMsg2, kLen2);
308 write_callback_.WaitForResult();
311 void SpdyProxyClientSocketTest::PopulateConnectRequestIR(
312 SpdyHeaderBlock* block) {
313 (*block)[spdy_util_.GetMethodKey()] = "CONNECT";
314 (*block)[spdy_util_.GetPathKey()] = kOriginHostPort;
315 (*block)[spdy_util_.GetHostKey()] = kOriginHost;
316 (*block)["user-agent"] = kUserAgent;
317 spdy_util_.MaybeAddVersionHeader(block);
320 void SpdyProxyClientSocketTest::PopulateConnectReplyIR(SpdyHeaderBlock* block,
321 const char* status) {
322 (*block)[spdy_util_.GetStatusKey()] = status;
323 spdy_util_.MaybeAddVersionHeader(block);
326 // Constructs a standard SPDY SYN_STREAM frame for a CONNECT request.
327 SpdyFrame*
328 SpdyProxyClientSocketTest::ConstructConnectRequestFrame() {
329 SpdyHeaderBlock block;
330 PopulateConnectRequestIR(&block);
331 return spdy_util_.ConstructSpdySyn(kStreamId, block, LOWEST, false, false);
334 // Constructs a SPDY SYN_STREAM frame for a CONNECT request which includes
335 // Proxy-Authorization headers.
336 SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectAuthRequestFrame() {
337 SpdyHeaderBlock block;
338 PopulateConnectRequestIR(&block);
339 block["proxy-authorization"] = "Basic Zm9vOmJhcg==";
340 return spdy_util_.ConstructSpdySyn(kStreamId, block, LOWEST, false, false);
343 // Constructs a standard SPDY SYN_REPLY frame to match the SPDY CONNECT.
344 SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectReplyFrame() {
345 SpdyHeaderBlock block;
346 PopulateConnectReplyIR(&block, "200");
347 SpdySynReplyIR reply_ir(kStreamId);
348 return spdy_util_.ConstructSpdyReply(kStreamId, block);
351 // Constructs a standard SPDY SYN_REPLY frame to match the SPDY CONNECT,
352 // including Proxy-Authenticate headers.
353 SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectAuthReplyFrame() {
354 SpdyHeaderBlock block;
355 PopulateConnectReplyIR(&block, "407");
356 block["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
357 return spdy_util_.ConstructSpdyReply(kStreamId, block);
360 // Constructs a SPDY SYN_REPLY frame with an HTTP 302 redirect.
361 SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectRedirectReplyFrame() {
362 SpdyHeaderBlock block;
363 PopulateConnectReplyIR(&block, "302");
364 block["location"] = kRedirectUrl;
365 block["set-cookie"] = "foo=bar";
366 return spdy_util_.ConstructSpdyReply(kStreamId, block);
369 // Constructs a SPDY SYN_REPLY frame with an HTTP 500 error.
370 SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectErrorReplyFrame() {
371 SpdyHeaderBlock block;
372 PopulateConnectReplyIR(&block, "500");
373 return spdy_util_.ConstructSpdyReply(kStreamId, block);
376 SpdyFrame* SpdyProxyClientSocketTest::ConstructBodyFrame(
377 const char* data,
378 int length) {
379 return framer_.CreateDataFrame(kStreamId, data, length, DATA_FLAG_NONE);
382 // ----------- Connect
384 TEST_P(SpdyProxyClientSocketTest, ConnectSendsCorrectRequest) {
385 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
386 MockWrite writes[] = {
387 CreateMockWrite(*conn, 0, SYNCHRONOUS),
390 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
391 MockRead reads[] = {
392 CreateMockRead(*resp, 1, ASYNC),
393 MockRead(ASYNC, 0, 2), // EOF
396 Initialize(reads, arraysize(reads), writes, arraysize(writes));
398 ASSERT_FALSE(sock_->IsConnected());
400 AssertConnectSucceeds();
402 AssertConnectionEstablished();
405 TEST_P(SpdyProxyClientSocketTest, ConnectWithAuthRequested) {
406 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
407 MockWrite writes[] = {
408 CreateMockWrite(*conn, 0, SYNCHRONOUS),
411 scoped_ptr<SpdyFrame> resp(ConstructConnectAuthReplyFrame());
412 MockRead reads[] = {
413 CreateMockRead(*resp, 1, ASYNC),
414 MockRead(ASYNC, 0, 2), // EOF
417 Initialize(reads, arraysize(reads), writes, arraysize(writes));
419 AssertConnectFails(ERR_PROXY_AUTH_REQUESTED);
421 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
422 ASSERT_TRUE(response != NULL);
423 ASSERT_EQ(407, response->headers->response_code());
426 TEST_P(SpdyProxyClientSocketTest, ConnectWithAuthCredentials) {
427 scoped_ptr<SpdyFrame> conn(ConstructConnectAuthRequestFrame());
428 MockWrite writes[] = {
429 CreateMockWrite(*conn, 0, SYNCHRONOUS),
432 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
433 MockRead reads[] = {
434 CreateMockRead(*resp, 1, ASYNC),
435 MockRead(ASYNC, 0, 2), // EOF
438 Initialize(reads, arraysize(reads), writes, arraysize(writes));
439 AddAuthToCache();
441 AssertConnectSucceeds();
443 AssertConnectionEstablished();
446 TEST_P(SpdyProxyClientSocketTest, ConnectRedirects) {
447 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
448 scoped_ptr<SpdyFrame> rst(
449 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
450 MockWrite writes[] = {
451 CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 2),
454 scoped_ptr<SpdyFrame> resp(ConstructConnectRedirectReplyFrame());
455 MockRead reads[] = {
456 CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3), // EOF
459 Initialize(reads, arraysize(reads), writes, arraysize(writes));
461 AssertConnectFails(ERR_HTTPS_PROXY_TUNNEL_RESPONSE);
463 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
464 ASSERT_TRUE(response != NULL);
466 const HttpResponseHeaders* headers = response->headers.get();
467 ASSERT_EQ(302, headers->response_code());
468 ASSERT_FALSE(headers->HasHeader("set-cookie"));
469 ASSERT_TRUE(headers->HasHeaderValue("content-length", "0"));
471 std::string location;
472 ASSERT_TRUE(headers->IsRedirect(&location));
473 ASSERT_EQ(location, kRedirectUrl);
475 // Let the RST_STREAM write while |rst| is in-scope.
476 base::MessageLoop::current()->RunUntilIdle();
479 TEST_P(SpdyProxyClientSocketTest, ConnectFails) {
480 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
481 MockWrite writes[] = {
482 CreateMockWrite(*conn, 0, SYNCHRONOUS),
485 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
486 MockRead reads[] = {
487 MockRead(ASYNC, 0, 1), // EOF
490 Initialize(reads, arraysize(reads), writes, arraysize(writes));
492 ASSERT_FALSE(sock_->IsConnected());
494 AssertConnectFails(ERR_CONNECTION_CLOSED);
496 ASSERT_FALSE(sock_->IsConnected());
499 // ----------- WasEverUsed
501 TEST_P(SpdyProxyClientSocketTest, WasEverUsedReturnsCorrectValues) {
502 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
503 scoped_ptr<SpdyFrame> rst(
504 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
505 MockWrite writes[] = {
506 CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 2),
509 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
510 MockRead reads[] = {
511 CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3), // EOF
514 Initialize(reads, arraysize(reads), writes, arraysize(writes));
516 EXPECT_FALSE(sock_->WasEverUsed());
517 AssertConnectSucceeds();
518 EXPECT_TRUE(sock_->WasEverUsed());
519 sock_->Disconnect();
520 EXPECT_TRUE(sock_->WasEverUsed());
522 // Let the RST_STREAM write while |rst| is in-scope.
523 base::MessageLoop::current()->RunUntilIdle();
526 // ----------- GetPeerAddress
528 TEST_P(SpdyProxyClientSocketTest, GetPeerAddressReturnsCorrectValues) {
529 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
530 MockWrite writes[] = {
531 CreateMockWrite(*conn, 0, SYNCHRONOUS),
534 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
535 MockRead reads[] = {
536 CreateMockRead(*resp, 1, ASYNC),
537 MockRead(ASYNC, 0, 2), // EOF
540 Initialize(reads, arraysize(reads), writes, arraysize(writes));
542 net::IPEndPoint addr;
543 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr));
545 AssertConnectSucceeds();
546 EXPECT_TRUE(sock_->IsConnected());
547 EXPECT_EQ(OK, sock_->GetPeerAddress(&addr));
549 Run(1);
551 EXPECT_FALSE(sock_->IsConnected());
552 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr));
554 sock_->Disconnect();
556 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr));
559 // ----------- Write
561 TEST_P(SpdyProxyClientSocketTest, WriteSendsDataInDataFrame) {
562 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
563 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
564 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
565 MockWrite writes[] = {
566 CreateMockWrite(*conn, 0, SYNCHRONOUS),
567 CreateMockWrite(*msg1, 2, SYNCHRONOUS),
568 CreateMockWrite(*msg2, 3, SYNCHRONOUS),
571 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
572 MockRead reads[] = {
573 CreateMockRead(*resp, 1, ASYNC),
574 MockRead(ASYNC, 0, 4), // EOF
577 Initialize(reads, arraysize(reads), writes, arraysize(writes));
579 AssertConnectSucceeds();
581 AssertAsyncWriteSucceeds(kMsg1, kLen1);
582 AssertAsyncWriteSucceeds(kMsg2, kLen2);
585 TEST_P(SpdyProxyClientSocketTest, WriteSplitsLargeDataIntoMultipleFrames) {
586 std::string chunk_data(kMaxSpdyFrameChunkSize, 'x');
587 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
588 scoped_ptr<SpdyFrame> chunk(ConstructBodyFrame(chunk_data.data(),
589 chunk_data.length()));
590 MockWrite writes[] = {
591 CreateMockWrite(*conn, 0, SYNCHRONOUS),
592 CreateMockWrite(*chunk, 2, SYNCHRONOUS),
593 CreateMockWrite(*chunk, 3, SYNCHRONOUS),
594 CreateMockWrite(*chunk, 4, SYNCHRONOUS)
597 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
598 MockRead reads[] = {
599 CreateMockRead(*resp, 1, ASYNC),
600 MockRead(ASYNC, 0, 5), // EOF
603 Initialize(reads, arraysize(reads), writes, arraysize(writes));
605 AssertConnectSucceeds();
607 std::string big_data(kMaxSpdyFrameChunkSize * 3, 'x');
608 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(big_data.data(),
609 big_data.length()));
611 EXPECT_EQ(ERR_IO_PENDING,
612 sock_->Write(buf.get(), buf->size(), write_callback_.callback()));
613 data_->RunFor(3);
615 EXPECT_EQ(buf->size(), write_callback_.WaitForResult());
618 // ----------- Read
620 TEST_P(SpdyProxyClientSocketTest, ReadReadsDataInDataFrame) {
621 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
622 MockWrite writes[] = {
623 CreateMockWrite(*conn, 0, SYNCHRONOUS),
626 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
627 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
628 MockRead reads[] = {
629 CreateMockRead(*resp, 1, ASYNC),
630 CreateMockRead(*msg1, 2, ASYNC),
631 MockRead(ASYNC, 0, 3), // EOF
634 Initialize(reads, arraysize(reads), writes, arraysize(writes));
636 AssertConnectSucceeds();
638 Run(1); // SpdySession consumes the next read and sends it to
639 // sock_ to be buffered.
640 AssertSyncReadEquals(kMsg1, kLen1);
643 TEST_P(SpdyProxyClientSocketTest, ReadDataFromBufferedFrames) {
644 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
645 MockWrite writes[] = {
646 CreateMockWrite(*conn, 0, SYNCHRONOUS),
649 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
650 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
651 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
652 MockRead reads[] = {
653 CreateMockRead(*resp, 1, ASYNC),
654 CreateMockRead(*msg1, 2, ASYNC),
655 CreateMockRead(*msg2, 3, ASYNC),
656 MockRead(ASYNC, 0, 4), // EOF
659 Initialize(reads, arraysize(reads), writes, arraysize(writes));
661 AssertConnectSucceeds();
663 Run(1); // SpdySession consumes the next read and sends it to
664 // sock_ to be buffered.
665 AssertSyncReadEquals(kMsg1, kLen1);
666 Run(1); // SpdySession consumes the next read and sends it to
667 // sock_ to be buffered.
668 AssertSyncReadEquals(kMsg2, kLen2);
671 TEST_P(SpdyProxyClientSocketTest, ReadDataMultipleBufferedFrames) {
672 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
673 MockWrite writes[] = {
674 CreateMockWrite(*conn, 0, SYNCHRONOUS),
677 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
678 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
679 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
680 MockRead reads[] = {
681 CreateMockRead(*resp, 1, ASYNC),
682 CreateMockRead(*msg1, 2, ASYNC),
683 CreateMockRead(*msg2, 3, ASYNC),
684 MockRead(ASYNC, 0, 4), // EOF
687 Initialize(reads, arraysize(reads), writes, arraysize(writes));
689 AssertConnectSucceeds();
691 Run(2); // SpdySession consumes the next two reads and sends then to
692 // sock_ to be buffered.
693 AssertSyncReadEquals(kMsg1, kLen1);
694 AssertSyncReadEquals(kMsg2, kLen2);
697 TEST_P(SpdyProxyClientSocketTest,
698 LargeReadWillMergeDataFromDifferentFrames) {
699 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
700 MockWrite writes[] = {
701 CreateMockWrite(*conn, 0, SYNCHRONOUS),
704 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
705 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
706 scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
707 MockRead reads[] = {
708 CreateMockRead(*resp, 1, ASYNC),
709 CreateMockRead(*msg3, 2, ASYNC),
710 CreateMockRead(*msg3, 3, ASYNC),
711 MockRead(ASYNC, 0, 4), // EOF
714 Initialize(reads, arraysize(reads), writes, arraysize(writes));
716 AssertConnectSucceeds();
718 Run(2); // SpdySession consumes the next two reads and sends then to
719 // sock_ to be buffered.
720 // The payload from two data frames, each with kMsg3 will be combined
721 // together into a single read().
722 AssertSyncReadEquals(kMsg33, kLen33);
725 TEST_P(SpdyProxyClientSocketTest, MultipleShortReadsThenMoreRead) {
726 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
727 MockWrite writes[] = {
728 CreateMockWrite(*conn, 0, SYNCHRONOUS),
731 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
732 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
733 scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
734 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
735 MockRead reads[] = {
736 CreateMockRead(*resp, 1, ASYNC),
737 CreateMockRead(*msg1, 2, ASYNC),
738 CreateMockRead(*msg3, 3, ASYNC),
739 CreateMockRead(*msg3, 4, ASYNC),
740 CreateMockRead(*msg2, 5, ASYNC),
741 MockRead(ASYNC, 0, 6), // EOF
744 Initialize(reads, arraysize(reads), writes, arraysize(writes));
746 AssertConnectSucceeds();
748 Run(4); // SpdySession consumes the next four reads and sends then to
749 // sock_ to be buffered.
750 AssertSyncReadEquals(kMsg1, kLen1);
751 // The payload from two data frames, each with kMsg3 will be combined
752 // together into a single read().
753 AssertSyncReadEquals(kMsg33, kLen33);
754 AssertSyncReadEquals(kMsg2, kLen2);
757 TEST_P(SpdyProxyClientSocketTest, ReadWillSplitDataFromLargeFrame) {
758 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
759 MockWrite writes[] = {
760 CreateMockWrite(*conn, 0, SYNCHRONOUS),
763 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
764 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
765 scoped_ptr<SpdyFrame> msg33(ConstructBodyFrame(kMsg33, kLen33));
766 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
767 MockRead reads[] = {
768 CreateMockRead(*resp, 1, ASYNC),
769 CreateMockRead(*msg1, 2, ASYNC),
770 CreateMockRead(*msg33, 3, ASYNC),
771 MockRead(ASYNC, 0, 4), // EOF
774 Initialize(reads, arraysize(reads), writes, arraysize(writes));
776 AssertConnectSucceeds();
778 Run(2); // SpdySession consumes the next two reads and sends then to
779 // sock_ to be buffered.
780 AssertSyncReadEquals(kMsg1, kLen1);
781 // The payload from the single large data frame will be read across
782 // two different reads.
783 AssertSyncReadEquals(kMsg3, kLen3);
784 AssertSyncReadEquals(kMsg3, kLen3);
787 TEST_P(SpdyProxyClientSocketTest, MultipleReadsFromSameLargeFrame) {
788 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
789 MockWrite writes[] = {
790 CreateMockWrite(*conn, 0, SYNCHRONOUS),
793 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
794 scoped_ptr<SpdyFrame> msg333(ConstructBodyFrame(kMsg333, kLen333));
795 MockRead reads[] = {
796 CreateMockRead(*resp, 1, ASYNC),
797 CreateMockRead(*msg333, 2, ASYNC),
798 MockRead(ASYNC, 0, 3), // EOF
801 Initialize(reads, arraysize(reads), writes, arraysize(writes));
803 AssertConnectSucceeds();
805 Run(1); // SpdySession consumes the next read and sends it to
806 // sock_ to be buffered.
807 // The payload from the single large data frame will be read across
808 // two different reads.
809 AssertSyncReadEquals(kMsg33, kLen33);
811 // Now attempt to do a read of more data than remains buffered
812 scoped_refptr<IOBuffer> buf(new IOBuffer(kLen33));
813 ASSERT_EQ(kLen3, sock_->Read(buf.get(), kLen33, read_callback_.callback()));
814 ASSERT_EQ(std::string(kMsg3, kLen3), std::string(buf->data(), kLen3));
815 ASSERT_TRUE(sock_->IsConnected());
818 TEST_P(SpdyProxyClientSocketTest, ReadAuthResponseBody) {
819 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
820 MockWrite writes[] = {
821 CreateMockWrite(*conn, 0, SYNCHRONOUS),
824 scoped_ptr<SpdyFrame> resp(ConstructConnectAuthReplyFrame());
825 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
826 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
827 MockRead reads[] = {
828 CreateMockRead(*resp, 1, ASYNC),
829 CreateMockRead(*msg1, 2, ASYNC),
830 CreateMockRead(*msg2, 3, ASYNC),
831 MockRead(ASYNC, 0, 4), // EOF
834 Initialize(reads, arraysize(reads), writes, arraysize(writes));
836 AssertConnectFails(ERR_PROXY_AUTH_REQUESTED);
838 Run(2); // SpdySession consumes the next two reads and sends then to
839 // sock_ to be buffered.
840 AssertSyncReadEquals(kMsg1, kLen1);
841 AssertSyncReadEquals(kMsg2, kLen2);
844 TEST_P(SpdyProxyClientSocketTest, ReadErrorResponseBody) {
845 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
846 MockWrite writes[] = {
847 CreateMockWrite(*conn, 0, SYNCHRONOUS),
850 scoped_ptr<SpdyFrame> resp(ConstructConnectErrorReplyFrame());
851 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
852 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
853 MockRead reads[] = {
854 CreateMockRead(*resp, 1, ASYNC),
855 CreateMockRead(*msg1, 2, ASYNC),
856 CreateMockRead(*msg2, 3, ASYNC),
857 MockRead(ASYNC, 0, 4), // EOF
860 Initialize(reads, arraysize(reads), writes, arraysize(writes));
862 AssertConnectFails(ERR_TUNNEL_CONNECTION_FAILED);
865 // ----------- Reads and Writes
867 TEST_P(SpdyProxyClientSocketTest, AsyncReadAroundWrite) {
868 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
869 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
870 MockWrite writes[] = {
871 CreateMockWrite(*conn, 0, SYNCHRONOUS),
872 CreateMockWrite(*msg2, 3, SYNCHRONOUS),
875 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
876 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
877 scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
878 MockRead reads[] = {
879 CreateMockRead(*resp, 1, ASYNC),
880 CreateMockRead(*msg1, 2, ASYNC), // sync read
881 CreateMockRead(*msg3, 4, ASYNC), // async read
882 MockRead(ASYNC, 0, 5), // EOF
885 Initialize(reads, arraysize(reads), writes, arraysize(writes));
887 AssertConnectSucceeds();
889 Run(1);
890 AssertSyncReadEquals(kMsg1, kLen1);
892 AssertReadStarts(kMsg3, kLen3);
893 // Read should block until after the write succeeds
895 AssertAsyncWriteSucceeds(kMsg2, kLen2); // Runs 1 step
897 ASSERT_FALSE(read_callback_.have_result());
898 Run(1);
899 // Now the read will return
900 AssertReadReturns(kMsg3, kLen3);
903 TEST_P(SpdyProxyClientSocketTest, AsyncWriteAroundReads) {
904 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
905 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
906 MockWrite writes[] = {
907 CreateMockWrite(*conn, 0, SYNCHRONOUS),
908 CreateMockWrite(*msg2, 4, ASYNC),
911 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
912 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
913 scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
914 MockRead reads[] = {
915 CreateMockRead(*resp, 1, ASYNC),
916 CreateMockRead(*msg1, 2, ASYNC),
917 CreateMockRead(*msg3, 3, ASYNC),
918 MockRead(ASYNC, 0, 5), // EOF
921 Initialize(reads, arraysize(reads), writes, arraysize(writes));
923 AssertConnectSucceeds();
925 Run(1);
926 AssertSyncReadEquals(kMsg1, kLen1);
927 // Write should block until the read completes
928 AssertWriteReturns(kMsg2, kLen2, ERR_IO_PENDING);
930 AssertAsyncReadEquals(kMsg3, kLen3);
932 ASSERT_FALSE(write_callback_.have_result());
934 // Now the write will complete
935 Run(1);
936 AssertWriteLength(kLen2);
939 // ----------- Reading/Writing on Closed socket
941 // Reading from an already closed socket should return 0
942 TEST_P(SpdyProxyClientSocketTest, ReadOnClosedSocketReturnsZero) {
943 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
944 MockWrite writes[] = {
945 CreateMockWrite(*conn, 0, SYNCHRONOUS),
948 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
949 MockRead reads[] = {
950 CreateMockRead(*resp, 1, ASYNC),
951 MockRead(ASYNC, 0, 2), // EOF
954 Initialize(reads, arraysize(reads), writes, arraysize(writes));
956 AssertConnectSucceeds();
958 Run(1);
960 ASSERT_FALSE(sock_->IsConnected());
961 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
962 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
963 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
964 ASSERT_FALSE(sock_->IsConnectedAndIdle());
967 // Read pending when socket is closed should return 0
968 TEST_P(SpdyProxyClientSocketTest, PendingReadOnCloseReturnsZero) {
969 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
970 MockWrite writes[] = {
971 CreateMockWrite(*conn, 0, SYNCHRONOUS),
974 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
975 MockRead reads[] = {
976 CreateMockRead(*resp, 1, ASYNC),
977 MockRead(ASYNC, 0, 2), // EOF
980 Initialize(reads, arraysize(reads), writes, arraysize(writes));
982 AssertConnectSucceeds();
984 AssertReadStarts(kMsg1, kLen1);
986 Run(1);
988 ASSERT_EQ(0, read_callback_.WaitForResult());
991 // Reading from a disconnected socket is an error
992 TEST_P(SpdyProxyClientSocketTest,
993 ReadOnDisconnectSocketReturnsNotConnected) {
994 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
995 scoped_ptr<SpdyFrame> rst(
996 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
997 MockWrite writes[] = {
998 CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 2),
1001 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1002 MockRead reads[] = {
1003 CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3), // EOF
1006 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1008 AssertConnectSucceeds();
1010 sock_->Disconnect();
1012 ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED,
1013 sock_->Read(NULL, 1, CompletionCallback()));
1015 // Let the RST_STREAM write while |rst| is in-scope.
1016 base::MessageLoop::current()->RunUntilIdle();
1019 // Reading buffered data from an already closed socket should return
1020 // buffered data, then 0.
1021 TEST_P(SpdyProxyClientSocketTest, ReadOnClosedSocketReturnsBufferedData) {
1022 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1023 MockWrite writes[] = {
1024 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1027 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1028 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
1029 MockRead reads[] = {
1030 CreateMockRead(*resp, 1, ASYNC),
1031 CreateMockRead(*msg1, 2, ASYNC),
1032 MockRead(ASYNC, 0, 3), // EOF
1035 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1037 AssertConnectSucceeds();
1039 Run(2);
1041 ASSERT_FALSE(sock_->IsConnected());
1042 scoped_refptr<IOBuffer> buf(new IOBuffer(kLen1));
1043 ASSERT_EQ(kLen1, sock_->Read(buf.get(), kLen1, CompletionCallback()));
1044 ASSERT_EQ(std::string(kMsg1, kLen1), std::string(buf->data(), kLen1));
1046 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
1047 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
1048 sock_->Disconnect();
1049 ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED,
1050 sock_->Read(NULL, 1, CompletionCallback()));
1053 // Calling Write() on a closed socket is an error
1054 TEST_P(SpdyProxyClientSocketTest, WriteOnClosedStream) {
1055 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1056 MockWrite writes[] = {
1057 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1060 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1061 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
1062 MockRead reads[] = {
1063 CreateMockRead(*resp, 1, ASYNC),
1064 MockRead(ASYNC, 0, 2), // EOF
1067 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1069 AssertConnectSucceeds();
1071 Run(1); // Read EOF which will close the stream
1072 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
1073 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED,
1074 sock_->Write(buf.get(), buf->size(), CompletionCallback()));
1077 // Calling Write() on a disconnected socket is an error
1078 TEST_P(SpdyProxyClientSocketTest, WriteOnDisconnectedSocket) {
1079 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1080 scoped_ptr<SpdyFrame> rst(
1081 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
1082 MockWrite writes[] = {
1083 CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 2),
1086 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1087 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
1088 MockRead reads[] = {
1089 CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3), // EOF
1092 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1094 AssertConnectSucceeds();
1096 sock_->Disconnect();
1098 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
1099 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED,
1100 sock_->Write(buf.get(), buf->size(), CompletionCallback()));
1102 // Let the RST_STREAM write while |rst| is in-scope.
1103 base::MessageLoop::current()->RunUntilIdle();
1106 // If the socket is closed with a pending Write(), the callback
1107 // should be called with ERR_CONNECTION_CLOSED.
1108 TEST_P(SpdyProxyClientSocketTest, WritePendingOnClose) {
1109 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1110 MockWrite writes[] = {
1111 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1112 MockWrite(ASYNC, ERR_ABORTED, 2),
1115 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1116 MockRead reads[] = {
1117 CreateMockRead(*resp, 1, ASYNC),
1118 MockRead(ASYNC, 0, 3), // EOF
1121 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1123 AssertConnectSucceeds();
1125 EXPECT_TRUE(sock_->IsConnected());
1127 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
1128 EXPECT_EQ(ERR_IO_PENDING,
1129 sock_->Write(buf.get(), buf->size(), write_callback_.callback()));
1131 CloseSpdySession(ERR_ABORTED, std::string());
1133 EXPECT_EQ(ERR_CONNECTION_CLOSED, write_callback_.WaitForResult());
1136 // If the socket is Disconnected with a pending Write(), the callback
1137 // should not be called.
1138 TEST_P(SpdyProxyClientSocketTest, DisconnectWithWritePending) {
1139 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1140 scoped_ptr<SpdyFrame> rst(
1141 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
1142 MockWrite writes[] = {
1143 CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 2),
1144 MockWrite(SYNCHRONOUS, 0, 3), // EOF
1147 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1148 MockRead reads[] = {
1149 CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 4), // EOF
1152 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1154 AssertConnectSucceeds();
1156 EXPECT_TRUE(sock_->IsConnected());
1158 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
1159 EXPECT_EQ(ERR_IO_PENDING,
1160 sock_->Write(buf.get(), buf->size(), write_callback_.callback()));
1162 sock_->Disconnect();
1164 EXPECT_FALSE(sock_->IsConnected());
1165 EXPECT_FALSE(write_callback_.have_result());
1167 // Let the RST_STREAM write while |rst| is in-scope.
1168 base::MessageLoop::current()->RunUntilIdle();
1171 // If the socket is Disconnected with a pending Read(), the callback
1172 // should not be called.
1173 TEST_P(SpdyProxyClientSocketTest, DisconnectWithReadPending) {
1174 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1175 scoped_ptr<SpdyFrame> rst(
1176 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
1177 MockWrite writes[] = {
1178 CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 2),
1181 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1182 MockRead reads[] = {
1183 CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3), // EOF
1186 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1188 AssertConnectSucceeds();
1190 EXPECT_TRUE(sock_->IsConnected());
1192 scoped_refptr<IOBuffer> buf(new IOBuffer(kLen1));
1193 ASSERT_EQ(ERR_IO_PENDING,
1194 sock_->Read(buf.get(), kLen1, read_callback_.callback()));
1196 sock_->Disconnect();
1198 EXPECT_FALSE(sock_->IsConnected());
1199 EXPECT_FALSE(read_callback_.have_result());
1201 // Let the RST_STREAM write while |rst| is in-scope.
1202 base::MessageLoop::current()->RunUntilIdle();
1205 // If the socket is Reset when both a read and write are pending,
1206 // both should be called back.
1207 TEST_P(SpdyProxyClientSocketTest, RstWithReadAndWritePending) {
1208 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1209 MockWrite writes[] = {
1210 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1211 MockWrite(ASYNC, ERR_ABORTED, 3),
1214 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1215 scoped_ptr<SpdyFrame> rst(
1216 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
1217 MockRead reads[] = {
1218 CreateMockRead(*resp, 1, ASYNC),
1219 CreateMockRead(*rst, 2, ASYNC),
1220 MockRead(ASYNC, 0, 4) // EOF
1223 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1225 AssertConnectSucceeds();
1227 EXPECT_TRUE(sock_->IsConnected());
1229 scoped_refptr<IOBuffer> read_buf(new IOBuffer(kLen1));
1230 ASSERT_EQ(ERR_IO_PENDING,
1231 sock_->Read(read_buf.get(), kLen1, read_callback_.callback()));
1233 scoped_refptr<IOBufferWithSize> write_buf(CreateBuffer(kMsg1, kLen1));
1234 EXPECT_EQ(
1235 ERR_IO_PENDING,
1236 sock_->Write(
1237 write_buf.get(), write_buf->size(), write_callback_.callback()));
1239 Run(2);
1241 EXPECT_TRUE(sock_.get());
1242 EXPECT_TRUE(read_callback_.have_result());
1243 EXPECT_TRUE(write_callback_.have_result());
1245 // Let the RST_STREAM write while |rst| is in-scope.
1246 base::MessageLoop::current()->RunUntilIdle();
1249 // Makes sure the proxy client socket's source gets the expected NetLog events
1250 // and only the expected NetLog events (No SpdySession events).
1251 TEST_P(SpdyProxyClientSocketTest, NetLog) {
1252 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1253 scoped_ptr<SpdyFrame> rst(
1254 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
1255 MockWrite writes[] = {
1256 CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 3),
1259 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1260 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
1261 MockRead reads[] = {
1262 CreateMockRead(*resp, 1, ASYNC), CreateMockRead(*msg1, 2, ASYNC),
1263 MockRead(ASYNC, 0, 4), // EOF
1266 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1268 AssertConnectSucceeds();
1270 Run(1); // SpdySession consumes the next read and sends it to
1271 // sock_ to be buffered.
1272 AssertSyncReadEquals(kMsg1, kLen1);
1274 NetLog::Source sock_source = sock_->NetLog().source();
1275 sock_.reset();
1277 CapturingNetLog::CapturedEntryList entry_list;
1278 net_log_.GetEntriesForSource(sock_source, &entry_list);
1280 ASSERT_EQ(entry_list.size(), 10u);
1281 EXPECT_TRUE(LogContainsBeginEvent(entry_list, 0, NetLog::TYPE_SOCKET_ALIVE));
1282 EXPECT_TRUE(LogContainsEvent(entry_list, 1,
1283 NetLog::TYPE_HTTP2_PROXY_CLIENT_SESSION,
1284 NetLog::PHASE_NONE));
1285 EXPECT_TRUE(LogContainsBeginEvent(entry_list, 2,
1286 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_SEND_REQUEST));
1287 EXPECT_TRUE(LogContainsEvent(entry_list, 3,
1288 NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
1289 NetLog::PHASE_NONE));
1290 EXPECT_TRUE(LogContainsEndEvent(entry_list, 4,
1291 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_SEND_REQUEST));
1292 EXPECT_TRUE(LogContainsBeginEvent(entry_list, 5,
1293 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_READ_HEADERS));
1294 EXPECT_TRUE(LogContainsEvent(entry_list, 6,
1295 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
1296 NetLog::PHASE_NONE));
1297 EXPECT_TRUE(LogContainsEndEvent(entry_list, 7,
1298 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_READ_HEADERS));
1299 EXPECT_TRUE(LogContainsEvent(entry_list, 8,
1300 NetLog::TYPE_SOCKET_BYTES_RECEIVED,
1301 NetLog::PHASE_NONE));
1302 EXPECT_TRUE(LogContainsEndEvent(entry_list, 9, NetLog::TYPE_SOCKET_ALIVE));
1304 // Let the RST_STREAM write while |rst| is in-scope.
1305 base::MessageLoop::current()->RunUntilIdle();
1308 // CompletionCallback that causes the SpdyProxyClientSocket to be
1309 // deleted when Run is invoked.
1310 class DeleteSockCallback : public TestCompletionCallbackBase {
1311 public:
1312 explicit DeleteSockCallback(scoped_ptr<SpdyProxyClientSocket>* sock)
1313 : sock_(sock),
1314 callback_(base::Bind(&DeleteSockCallback::OnComplete,
1315 base::Unretained(this))) {
1318 ~DeleteSockCallback() override {}
1320 const CompletionCallback& callback() const { return callback_; }
1322 private:
1323 void OnComplete(int result) {
1324 sock_->reset(NULL);
1325 SetResult(result);
1328 scoped_ptr<SpdyProxyClientSocket>* sock_;
1329 CompletionCallback callback_;
1331 DISALLOW_COPY_AND_ASSIGN(DeleteSockCallback);
1334 // If the socket is Reset when both a read and write are pending, and the
1335 // read callback causes the socket to be deleted, the write callback should
1336 // not be called.
1337 TEST_P(SpdyProxyClientSocketTest, RstWithReadAndWritePendingDelete) {
1338 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1339 MockWrite writes[] = {
1340 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1341 MockWrite(ASYNC, ERR_ABORTED, 3),
1344 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1345 scoped_ptr<SpdyFrame> rst(
1346 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
1347 MockRead reads[] = {
1348 CreateMockRead(*resp, 1, ASYNC),
1349 CreateMockRead(*rst, 2, ASYNC),
1350 MockRead(ASYNC, 0, 4), // EOF
1353 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1355 AssertConnectSucceeds();
1357 EXPECT_TRUE(sock_->IsConnected());
1359 DeleteSockCallback read_callback(&sock_);
1361 scoped_refptr<IOBuffer> read_buf(new IOBuffer(kLen1));
1362 ASSERT_EQ(ERR_IO_PENDING,
1363 sock_->Read(read_buf.get(), kLen1, read_callback.callback()));
1365 scoped_refptr<IOBufferWithSize> write_buf(CreateBuffer(kMsg1, kLen1));
1366 EXPECT_EQ(
1367 ERR_IO_PENDING,
1368 sock_->Write(
1369 write_buf.get(), write_buf->size(), write_callback_.callback()));
1371 Run(1);
1373 EXPECT_FALSE(sock_.get());
1374 EXPECT_TRUE(read_callback.have_result());
1375 EXPECT_FALSE(write_callback_.have_result());
1377 // Let the RST_STREAM write while |rst| is in-scope.
1378 base::MessageLoop::current()->RunUntilIdle();
1381 } // namespace net