Android NTP: Most visited tile clicks should have PageTransition.AUTO_BOOKMARK
[chromium-blink-merge.git] / net / spdy / spdy_proxy_client_socket_unittest.cc
blobcec88be2ff776ae3a8b765c7ebc9af910f629526
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/net_log.h"
17 #include "net/log/test_net_log.h"
18 #include "net/log/test_net_log_entry.h"
19 #include "net/log/test_net_log_util.h"
20 #include "net/socket/client_socket_factory.h"
21 #include "net/socket/next_proto.h"
22 #include "net/socket/socket_test_util.h"
23 #include "net/socket/tcp_client_socket.h"
24 #include "net/spdy/buffered_spdy_framer.h"
25 #include "net/spdy/spdy_http_utils.h"
26 #include "net/spdy/spdy_protocol.h"
27 #include "net/spdy/spdy_session_pool.h"
28 #include "net/spdy/spdy_test_util_common.h"
29 #include "testing/gtest/include/gtest/gtest.h"
30 #include "testing/platform_test.h"
32 //-----------------------------------------------------------------------------
34 namespace {
36 static const char kRequestUrl[] = "https://www.google.com/";
37 static const char kOriginHost[] = "www.google.com";
38 static const int kOriginPort = 443;
39 static const char kOriginHostPort[] = "www.google.com:443";
40 static const char kProxyUrl[] = "https://myproxy:6121/";
41 static const char kProxyHost[] = "myproxy";
42 static const int kProxyPort = 6121;
43 static const char kUserAgent[] = "Mozilla/1.0";
45 static const int kStreamId = 1;
47 static const char kMsg1[] = "\0hello!\xff";
48 static const int kLen1 = 8;
49 static const char kMsg2[] = "\0a2345678\0";
50 static const int kLen2 = 10;
51 static const char kMsg3[] = "bye!";
52 static const int kLen3 = 4;
53 static const char kMsg33[] = "bye!bye!";
54 static const int kLen33 = kLen3 + kLen3;
55 static const char kMsg333[] = "bye!bye!bye!";
56 static const int kLen333 = kLen3 + kLen3 + kLen3;
58 static const char kRedirectUrl[] = "https://example.com/";
60 } // anonymous namespace
62 namespace net {
64 class SpdyProxyClientSocketTest
65 : public PlatformTest,
66 public testing::WithParamInterface<NextProto> {
67 public:
68 SpdyProxyClientSocketTest();
70 void TearDown() override;
72 protected:
73 void Initialize(MockRead* reads, size_t reads_count, MockWrite* writes,
74 size_t writes_count);
75 void PopulateConnectRequestIR(SpdyHeaderBlock* syn_ir);
76 void PopulateConnectReplyIR(SpdyHeaderBlock* block, const char* status);
77 SpdyFrame* ConstructConnectRequestFrame();
78 SpdyFrame* ConstructConnectAuthRequestFrame();
79 SpdyFrame* ConstructConnectReplyFrame();
80 SpdyFrame* ConstructConnectAuthReplyFrame();
81 SpdyFrame* ConstructConnectRedirectReplyFrame();
82 SpdyFrame* ConstructConnectErrorReplyFrame();
83 SpdyFrame* ConstructBodyFrame(const char* data, int length);
84 scoped_refptr<IOBufferWithSize> CreateBuffer(const char* data, int size);
85 void AssertConnectSucceeds();
86 void AssertConnectFails(int result);
87 void AssertConnectionEstablished();
88 void AssertSyncReadEquals(const char* data, int len);
89 void AssertAsyncReadEquals(const char* data, int len);
90 void AssertReadStarts(const char* data, int len);
91 void AssertReadReturns(const char* data, int len);
92 void AssertAsyncWriteSucceeds(const char* data, int len);
93 void AssertWriteReturns(const char* data, int len, int rv);
94 void AssertWriteLength(int len);
95 void AssertAsyncWriteWithReadsSucceeds(const char* data, int len,
96 int num_reads);
98 void AddAuthToCache() {
99 const base::string16 kFoo(base::ASCIIToUTF16("foo"));
100 const base::string16 kBar(base::ASCIIToUTF16("bar"));
101 session_->http_auth_cache()->Add(GURL(kProxyUrl),
102 "MyRealm1",
103 HttpAuth::AUTH_SCHEME_BASIC,
104 "Basic realm=MyRealm1",
105 AuthCredentials(kFoo, kBar),
106 "/");
109 void Run(int steps) {
110 data_->StopAfter(steps);
111 data_->Run();
114 void CloseSpdySession(Error error, const std::string& description) {
115 spdy_session_->CloseSessionOnError(error, description);
118 SpdyTestUtil spdy_util_;
119 scoped_ptr<SpdyProxyClientSocket> sock_;
120 TestCompletionCallback read_callback_;
121 TestCompletionCallback write_callback_;
122 scoped_ptr<DeterministicSocketData> data_;
123 BoundTestNetLog net_log_;
125 private:
126 scoped_refptr<HttpNetworkSession> session_;
127 scoped_refptr<IOBuffer> read_buf_;
128 SpdySessionDependencies session_deps_;
129 MockConnect connect_data_;
130 base::WeakPtr<SpdySession> spdy_session_;
131 BufferedSpdyFramer framer_;
133 std::string user_agent_;
134 GURL url_;
135 HostPortPair proxy_host_port_;
136 HostPortPair endpoint_host_port_pair_;
137 ProxyServer proxy_;
138 SpdySessionKey endpoint_spdy_session_key_;
140 DISALLOW_COPY_AND_ASSIGN(SpdyProxyClientSocketTest);
143 INSTANTIATE_TEST_CASE_P(NextProto,
144 SpdyProxyClientSocketTest,
145 testing::Values(kProtoSPDY31,
146 kProtoHTTP2_14,
147 kProtoHTTP2));
149 SpdyProxyClientSocketTest::SpdyProxyClientSocketTest()
150 : spdy_util_(GetParam()),
151 session_(NULL),
152 read_buf_(NULL),
153 session_deps_(GetParam()),
154 connect_data_(SYNCHRONOUS, OK),
155 framer_(spdy_util_.spdy_version(), false),
156 user_agent_(kUserAgent),
157 url_(kRequestUrl),
158 proxy_host_port_(kProxyHost, kProxyPort),
159 endpoint_host_port_pair_(kOriginHost, kOriginPort),
160 proxy_(ProxyServer::SCHEME_HTTPS, proxy_host_port_),
161 endpoint_spdy_session_key_(endpoint_host_port_pair_,
162 proxy_,
163 PRIVACY_MODE_DISABLED) {
164 session_deps_.net_log = net_log_.bound().net_log();
167 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,
177 size_t reads_count,
178 MockWrite* writes,
179 size_t writes_count) {
180 data_.reset(new DeterministicSocketData(reads, reads_count,
181 writes, writes_count));
182 data_->set_connect_data(connect_data_);
183 data_->SetStop(2);
185 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
186 data_.get());
187 session_deps_.host_resolver->set_synchronous_mode(true);
189 session_ = SpdySessionDependencies::SpdyCreateSessionDeterministic(
190 &session_deps_);
192 // Creates the SPDY session and stream.
193 spdy_session_ =
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,
199 net_log_.bound()));
200 ASSERT_TRUE(spdy_stream.get() != NULL);
202 // Create the SpdyProxyClientSocket.
203 sock_.reset(new SpdyProxyClientSocket(
204 spdy_stream, user_agent_, endpoint_host_port_pair_, proxy_host_port_,
205 net_log_.bound(), session_->http_auth_cache(),
206 session_->http_auth_handler_factory()));
209 scoped_refptr<IOBufferWithSize> SpdyProxyClientSocketTest::CreateBuffer(
210 const char* data, int size) {
211 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(size));
212 memcpy(buf->data(), data, size);
213 return buf;
216 void SpdyProxyClientSocketTest::AssertConnectSucceeds() {
217 ASSERT_EQ(ERR_IO_PENDING, sock_->Connect(read_callback_.callback()));
218 data_->Run();
219 ASSERT_EQ(OK, read_callback_.WaitForResult());
222 void SpdyProxyClientSocketTest::AssertConnectFails(int result) {
223 ASSERT_EQ(ERR_IO_PENDING, sock_->Connect(read_callback_.callback()));
224 data_->Run();
225 ASSERT_EQ(result, read_callback_.WaitForResult());
228 void SpdyProxyClientSocketTest::AssertConnectionEstablished() {
229 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
230 ASSERT_TRUE(response != NULL);
231 ASSERT_EQ(200, response->headers->response_code());
234 void SpdyProxyClientSocketTest::AssertSyncReadEquals(const char* data,
235 int len) {
236 scoped_refptr<IOBuffer> buf(new IOBuffer(len));
237 ASSERT_EQ(len, sock_->Read(buf.get(), len, CompletionCallback()));
238 ASSERT_EQ(std::string(data, len), std::string(buf->data(), len));
239 ASSERT_TRUE(sock_->IsConnected());
242 void SpdyProxyClientSocketTest::AssertAsyncReadEquals(const char* data,
243 int len) {
244 data_->StopAfter(1);
245 // Issue the read, which will be completed asynchronously
246 scoped_refptr<IOBuffer> buf(new IOBuffer(len));
247 ASSERT_EQ(ERR_IO_PENDING,
248 sock_->Read(buf.get(), len, read_callback_.callback()));
249 EXPECT_TRUE(sock_->IsConnected());
250 data_->Run();
252 EXPECT_TRUE(sock_->IsConnected());
254 // Now the read will return
255 EXPECT_EQ(len, read_callback_.WaitForResult());
256 ASSERT_EQ(std::string(data, len), std::string(buf->data(), len));
259 void SpdyProxyClientSocketTest::AssertReadStarts(const char* data,
260 int len) {
261 data_->StopAfter(1);
262 // Issue the read, which will be completed asynchronously
263 read_buf_ = new IOBuffer(len);
264 ASSERT_EQ(ERR_IO_PENDING,
265 sock_->Read(read_buf_.get(), len, read_callback_.callback()));
266 EXPECT_TRUE(sock_->IsConnected());
269 void SpdyProxyClientSocketTest::AssertReadReturns(const char* data,
270 int len) {
271 EXPECT_TRUE(sock_->IsConnected());
273 // Now the read will return
274 EXPECT_EQ(len, read_callback_.WaitForResult());
275 ASSERT_EQ(std::string(data, len), std::string(read_buf_->data(), len));
278 void SpdyProxyClientSocketTest::AssertAsyncWriteSucceeds(const char* data,
279 int len) {
280 AssertWriteReturns(data, len, ERR_IO_PENDING);
281 data_->RunFor(1);
282 AssertWriteLength(len);
285 void SpdyProxyClientSocketTest::AssertWriteReturns(const char* data,
286 int len,
287 int rv) {
288 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(data, len));
289 EXPECT_EQ(rv,
290 sock_->Write(buf.get(), buf->size(), write_callback_.callback()));
293 void SpdyProxyClientSocketTest::AssertWriteLength(int len) {
294 EXPECT_EQ(len, write_callback_.WaitForResult());
297 void SpdyProxyClientSocketTest::AssertAsyncWriteWithReadsSucceeds(
298 const char* data, int len, int num_reads) {
299 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(data, len));
301 EXPECT_EQ(ERR_IO_PENDING,
302 sock_->Write(buf.get(), buf->size(), write_callback_.callback()));
304 for (int i = 0; i < num_reads; i++) {
305 Run(1);
306 AssertSyncReadEquals(kMsg2, kLen2);
309 write_callback_.WaitForResult();
312 void SpdyProxyClientSocketTest::PopulateConnectRequestIR(
313 SpdyHeaderBlock* block) {
314 (*block)[spdy_util_.GetMethodKey()] = "CONNECT";
315 if (spdy_util_.spdy_version() == HTTP2) {
316 (*block)[spdy_util_.GetHostKey()] = kOriginHostPort;
317 } else {
318 (*block)[spdy_util_.GetPathKey()] = kOriginHostPort;
319 (*block)[spdy_util_.GetHostKey()] = kOriginHost;
321 (*block)["user-agent"] = kUserAgent;
322 spdy_util_.MaybeAddVersionHeader(block);
325 void SpdyProxyClientSocketTest::PopulateConnectReplyIR(SpdyHeaderBlock* block,
326 const char* status) {
327 (*block)[spdy_util_.GetStatusKey()] = status;
328 spdy_util_.MaybeAddVersionHeader(block);
331 // Constructs a standard SPDY SYN_STREAM frame for a CONNECT request.
332 SpdyFrame*
333 SpdyProxyClientSocketTest::ConstructConnectRequestFrame() {
334 SpdyHeaderBlock block;
335 PopulateConnectRequestIR(&block);
336 return spdy_util_.ConstructSpdySyn(kStreamId, block, LOWEST, false, false);
339 // Constructs a SPDY SYN_STREAM frame for a CONNECT request which includes
340 // Proxy-Authorization headers.
341 SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectAuthRequestFrame() {
342 SpdyHeaderBlock block;
343 PopulateConnectRequestIR(&block);
344 block["proxy-authorization"] = "Basic Zm9vOmJhcg==";
345 return spdy_util_.ConstructSpdySyn(kStreamId, block, LOWEST, false, false);
348 // Constructs a standard SPDY SYN_REPLY frame to match the SPDY CONNECT.
349 SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectReplyFrame() {
350 SpdyHeaderBlock block;
351 PopulateConnectReplyIR(&block, "200");
352 SpdySynReplyIR reply_ir(kStreamId);
353 return spdy_util_.ConstructSpdyReply(kStreamId, block);
356 // Constructs a standard SPDY SYN_REPLY frame to match the SPDY CONNECT,
357 // including Proxy-Authenticate headers.
358 SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectAuthReplyFrame() {
359 SpdyHeaderBlock block;
360 PopulateConnectReplyIR(&block, "407");
361 block["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
362 return spdy_util_.ConstructSpdyReply(kStreamId, block);
365 // Constructs a SPDY SYN_REPLY frame with an HTTP 302 redirect.
366 SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectRedirectReplyFrame() {
367 SpdyHeaderBlock block;
368 PopulateConnectReplyIR(&block, "302");
369 block["location"] = kRedirectUrl;
370 block["set-cookie"] = "foo=bar";
371 return spdy_util_.ConstructSpdyReply(kStreamId, block);
374 // Constructs a SPDY SYN_REPLY frame with an HTTP 500 error.
375 SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectErrorReplyFrame() {
376 SpdyHeaderBlock block;
377 PopulateConnectReplyIR(&block, "500");
378 return spdy_util_.ConstructSpdyReply(kStreamId, block);
381 SpdyFrame* SpdyProxyClientSocketTest::ConstructBodyFrame(
382 const char* data,
383 int length) {
384 return framer_.CreateDataFrame(kStreamId, data, length, DATA_FLAG_NONE);
387 // ----------- Connect
389 TEST_P(SpdyProxyClientSocketTest, ConnectSendsCorrectRequest) {
390 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
391 MockWrite writes[] = {
392 CreateMockWrite(*conn, 0, SYNCHRONOUS),
395 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
396 MockRead reads[] = {
397 CreateMockRead(*resp, 1, ASYNC),
398 MockRead(ASYNC, 0, 2), // EOF
401 Initialize(reads, arraysize(reads), writes, arraysize(writes));
403 ASSERT_FALSE(sock_->IsConnected());
405 AssertConnectSucceeds();
407 AssertConnectionEstablished();
410 TEST_P(SpdyProxyClientSocketTest, ConnectWithAuthRequested) {
411 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
412 MockWrite writes[] = {
413 CreateMockWrite(*conn, 0, SYNCHRONOUS),
416 scoped_ptr<SpdyFrame> resp(ConstructConnectAuthReplyFrame());
417 MockRead reads[] = {
418 CreateMockRead(*resp, 1, ASYNC),
419 MockRead(ASYNC, 0, 2), // EOF
422 Initialize(reads, arraysize(reads), writes, arraysize(writes));
424 AssertConnectFails(ERR_PROXY_AUTH_REQUESTED);
426 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
427 ASSERT_TRUE(response != NULL);
428 ASSERT_EQ(407, response->headers->response_code());
431 TEST_P(SpdyProxyClientSocketTest, ConnectWithAuthCredentials) {
432 scoped_ptr<SpdyFrame> conn(ConstructConnectAuthRequestFrame());
433 MockWrite writes[] = {
434 CreateMockWrite(*conn, 0, SYNCHRONOUS),
437 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
438 MockRead reads[] = {
439 CreateMockRead(*resp, 1, ASYNC),
440 MockRead(ASYNC, 0, 2), // EOF
443 Initialize(reads, arraysize(reads), writes, arraysize(writes));
444 AddAuthToCache();
446 AssertConnectSucceeds();
448 AssertConnectionEstablished();
451 TEST_P(SpdyProxyClientSocketTest, ConnectRedirects) {
452 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
453 scoped_ptr<SpdyFrame> rst(
454 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
455 MockWrite writes[] = {
456 CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 2),
459 scoped_ptr<SpdyFrame> resp(ConstructConnectRedirectReplyFrame());
460 MockRead reads[] = {
461 CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3), // EOF
464 Initialize(reads, arraysize(reads), writes, arraysize(writes));
466 AssertConnectFails(ERR_HTTPS_PROXY_TUNNEL_RESPONSE);
468 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
469 ASSERT_TRUE(response != NULL);
471 const HttpResponseHeaders* headers = response->headers.get();
472 ASSERT_EQ(302, headers->response_code());
473 ASSERT_FALSE(headers->HasHeader("set-cookie"));
474 ASSERT_TRUE(headers->HasHeaderValue("content-length", "0"));
476 std::string location;
477 ASSERT_TRUE(headers->IsRedirect(&location));
478 ASSERT_EQ(location, kRedirectUrl);
480 // Let the RST_STREAM write while |rst| is in-scope.
481 base::MessageLoop::current()->RunUntilIdle();
484 TEST_P(SpdyProxyClientSocketTest, ConnectFails) {
485 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
486 MockWrite writes[] = {
487 CreateMockWrite(*conn, 0, SYNCHRONOUS),
490 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
491 MockRead reads[] = {
492 MockRead(ASYNC, 0, 1), // EOF
495 Initialize(reads, arraysize(reads), writes, arraysize(writes));
497 ASSERT_FALSE(sock_->IsConnected());
499 AssertConnectFails(ERR_CONNECTION_CLOSED);
501 ASSERT_FALSE(sock_->IsConnected());
504 // ----------- WasEverUsed
506 TEST_P(SpdyProxyClientSocketTest, WasEverUsedReturnsCorrectValues) {
507 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
508 scoped_ptr<SpdyFrame> rst(
509 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
510 MockWrite writes[] = {
511 CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 2),
514 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
515 MockRead reads[] = {
516 CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3), // EOF
519 Initialize(reads, arraysize(reads), writes, arraysize(writes));
521 EXPECT_FALSE(sock_->WasEverUsed());
522 AssertConnectSucceeds();
523 EXPECT_TRUE(sock_->WasEverUsed());
524 sock_->Disconnect();
525 EXPECT_TRUE(sock_->WasEverUsed());
527 // Let the RST_STREAM write while |rst| is in-scope.
528 base::MessageLoop::current()->RunUntilIdle();
531 // ----------- GetPeerAddress
533 TEST_P(SpdyProxyClientSocketTest, GetPeerAddressReturnsCorrectValues) {
534 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
535 MockWrite writes[] = {
536 CreateMockWrite(*conn, 0, SYNCHRONOUS),
539 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
540 MockRead reads[] = {
541 CreateMockRead(*resp, 1, ASYNC),
542 MockRead(ASYNC, 0, 2), // EOF
545 Initialize(reads, arraysize(reads), writes, arraysize(writes));
547 IPEndPoint addr;
548 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr));
550 AssertConnectSucceeds();
551 EXPECT_TRUE(sock_->IsConnected());
552 EXPECT_EQ(OK, sock_->GetPeerAddress(&addr));
554 Run(1);
556 EXPECT_FALSE(sock_->IsConnected());
557 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr));
559 sock_->Disconnect();
561 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr));
564 // ----------- Write
566 TEST_P(SpdyProxyClientSocketTest, WriteSendsDataInDataFrame) {
567 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
568 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
569 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
570 MockWrite writes[] = {
571 CreateMockWrite(*conn, 0, SYNCHRONOUS),
572 CreateMockWrite(*msg1, 2, SYNCHRONOUS),
573 CreateMockWrite(*msg2, 3, SYNCHRONOUS),
576 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
577 MockRead reads[] = {
578 CreateMockRead(*resp, 1, ASYNC),
579 MockRead(ASYNC, 0, 4), // EOF
582 Initialize(reads, arraysize(reads), writes, arraysize(writes));
584 AssertConnectSucceeds();
586 AssertAsyncWriteSucceeds(kMsg1, kLen1);
587 AssertAsyncWriteSucceeds(kMsg2, kLen2);
590 TEST_P(SpdyProxyClientSocketTest, WriteSplitsLargeDataIntoMultipleFrames) {
591 std::string chunk_data(kMaxSpdyFrameChunkSize, 'x');
592 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
593 scoped_ptr<SpdyFrame> chunk(ConstructBodyFrame(chunk_data.data(),
594 chunk_data.length()));
595 MockWrite writes[] = {
596 CreateMockWrite(*conn, 0, SYNCHRONOUS),
597 CreateMockWrite(*chunk, 2, SYNCHRONOUS),
598 CreateMockWrite(*chunk, 3, SYNCHRONOUS),
599 CreateMockWrite(*chunk, 4, SYNCHRONOUS)
602 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
603 MockRead reads[] = {
604 CreateMockRead(*resp, 1, ASYNC),
605 MockRead(ASYNC, 0, 5), // EOF
608 Initialize(reads, arraysize(reads), writes, arraysize(writes));
610 AssertConnectSucceeds();
612 std::string big_data(kMaxSpdyFrameChunkSize * 3, 'x');
613 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(big_data.data(),
614 big_data.length()));
616 EXPECT_EQ(ERR_IO_PENDING,
617 sock_->Write(buf.get(), buf->size(), write_callback_.callback()));
618 data_->RunFor(3);
620 EXPECT_EQ(buf->size(), write_callback_.WaitForResult());
623 // ----------- Read
625 TEST_P(SpdyProxyClientSocketTest, ReadReadsDataInDataFrame) {
626 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
627 MockWrite writes[] = {
628 CreateMockWrite(*conn, 0, SYNCHRONOUS),
631 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
632 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
633 MockRead reads[] = {
634 CreateMockRead(*resp, 1, ASYNC),
635 CreateMockRead(*msg1, 2, ASYNC),
636 MockRead(ASYNC, 0, 3), // EOF
639 Initialize(reads, arraysize(reads), writes, arraysize(writes));
641 AssertConnectSucceeds();
643 Run(1); // SpdySession consumes the next read and sends it to
644 // sock_ to be buffered.
645 AssertSyncReadEquals(kMsg1, kLen1);
648 TEST_P(SpdyProxyClientSocketTest, ReadDataFromBufferedFrames) {
649 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
650 MockWrite writes[] = {
651 CreateMockWrite(*conn, 0, SYNCHRONOUS),
654 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
655 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
656 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
657 MockRead reads[] = {
658 CreateMockRead(*resp, 1, ASYNC),
659 CreateMockRead(*msg1, 2, ASYNC),
660 CreateMockRead(*msg2, 3, ASYNC),
661 MockRead(ASYNC, 0, 4), // EOF
664 Initialize(reads, arraysize(reads), writes, arraysize(writes));
666 AssertConnectSucceeds();
668 Run(1); // SpdySession consumes the next read and sends it to
669 // sock_ to be buffered.
670 AssertSyncReadEquals(kMsg1, kLen1);
671 Run(1); // SpdySession consumes the next read and sends it to
672 // sock_ to be buffered.
673 AssertSyncReadEquals(kMsg2, kLen2);
676 TEST_P(SpdyProxyClientSocketTest, ReadDataMultipleBufferedFrames) {
677 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
678 MockWrite writes[] = {
679 CreateMockWrite(*conn, 0, SYNCHRONOUS),
682 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
683 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
684 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
685 MockRead reads[] = {
686 CreateMockRead(*resp, 1, ASYNC),
687 CreateMockRead(*msg1, 2, ASYNC),
688 CreateMockRead(*msg2, 3, ASYNC),
689 MockRead(ASYNC, 0, 4), // EOF
692 Initialize(reads, arraysize(reads), writes, arraysize(writes));
694 AssertConnectSucceeds();
696 Run(2); // SpdySession consumes the next two reads and sends then to
697 // sock_ to be buffered.
698 AssertSyncReadEquals(kMsg1, kLen1);
699 AssertSyncReadEquals(kMsg2, kLen2);
702 TEST_P(SpdyProxyClientSocketTest,
703 LargeReadWillMergeDataFromDifferentFrames) {
704 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
705 MockWrite writes[] = {
706 CreateMockWrite(*conn, 0, SYNCHRONOUS),
709 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
710 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
711 scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
712 MockRead reads[] = {
713 CreateMockRead(*resp, 1, ASYNC),
714 CreateMockRead(*msg3, 2, ASYNC),
715 CreateMockRead(*msg3, 3, ASYNC),
716 MockRead(ASYNC, 0, 4), // EOF
719 Initialize(reads, arraysize(reads), writes, arraysize(writes));
721 AssertConnectSucceeds();
723 Run(2); // SpdySession consumes the next two reads and sends then to
724 // sock_ to be buffered.
725 // The payload from two data frames, each with kMsg3 will be combined
726 // together into a single read().
727 AssertSyncReadEquals(kMsg33, kLen33);
730 TEST_P(SpdyProxyClientSocketTest, MultipleShortReadsThenMoreRead) {
731 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
732 MockWrite writes[] = {
733 CreateMockWrite(*conn, 0, SYNCHRONOUS),
736 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
737 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
738 scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
739 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
740 MockRead reads[] = {
741 CreateMockRead(*resp, 1, ASYNC),
742 CreateMockRead(*msg1, 2, ASYNC),
743 CreateMockRead(*msg3, 3, ASYNC),
744 CreateMockRead(*msg3, 4, ASYNC),
745 CreateMockRead(*msg2, 5, ASYNC),
746 MockRead(ASYNC, 0, 6), // EOF
749 Initialize(reads, arraysize(reads), writes, arraysize(writes));
751 AssertConnectSucceeds();
753 Run(4); // SpdySession consumes the next four reads and sends then to
754 // sock_ to be buffered.
755 AssertSyncReadEquals(kMsg1, kLen1);
756 // The payload from two data frames, each with kMsg3 will be combined
757 // together into a single read().
758 AssertSyncReadEquals(kMsg33, kLen33);
759 AssertSyncReadEquals(kMsg2, kLen2);
762 TEST_P(SpdyProxyClientSocketTest, ReadWillSplitDataFromLargeFrame) {
763 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
764 MockWrite writes[] = {
765 CreateMockWrite(*conn, 0, SYNCHRONOUS),
768 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
769 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
770 scoped_ptr<SpdyFrame> msg33(ConstructBodyFrame(kMsg33, kLen33));
771 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
772 MockRead reads[] = {
773 CreateMockRead(*resp, 1, ASYNC),
774 CreateMockRead(*msg1, 2, ASYNC),
775 CreateMockRead(*msg33, 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 AssertSyncReadEquals(kMsg1, kLen1);
786 // The payload from the single large data frame will be read across
787 // two different reads.
788 AssertSyncReadEquals(kMsg3, kLen3);
789 AssertSyncReadEquals(kMsg3, kLen3);
792 TEST_P(SpdyProxyClientSocketTest, MultipleReadsFromSameLargeFrame) {
793 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
794 MockWrite writes[] = {
795 CreateMockWrite(*conn, 0, SYNCHRONOUS),
798 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
799 scoped_ptr<SpdyFrame> msg333(ConstructBodyFrame(kMsg333, kLen333));
800 MockRead reads[] = {
801 CreateMockRead(*resp, 1, ASYNC),
802 CreateMockRead(*msg333, 2, ASYNC),
803 MockRead(ASYNC, 0, 3), // EOF
806 Initialize(reads, arraysize(reads), writes, arraysize(writes));
808 AssertConnectSucceeds();
810 Run(1); // SpdySession consumes the next read and sends it to
811 // sock_ to be buffered.
812 // The payload from the single large data frame will be read across
813 // two different reads.
814 AssertSyncReadEquals(kMsg33, kLen33);
816 // Now attempt to do a read of more data than remains buffered
817 scoped_refptr<IOBuffer> buf(new IOBuffer(kLen33));
818 ASSERT_EQ(kLen3, sock_->Read(buf.get(), kLen33, read_callback_.callback()));
819 ASSERT_EQ(std::string(kMsg3, kLen3), std::string(buf->data(), kLen3));
820 ASSERT_TRUE(sock_->IsConnected());
823 TEST_P(SpdyProxyClientSocketTest, ReadAuthResponseBody) {
824 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
825 MockWrite writes[] = {
826 CreateMockWrite(*conn, 0, SYNCHRONOUS),
829 scoped_ptr<SpdyFrame> resp(ConstructConnectAuthReplyFrame());
830 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
831 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
832 MockRead reads[] = {
833 CreateMockRead(*resp, 1, ASYNC),
834 CreateMockRead(*msg1, 2, ASYNC),
835 CreateMockRead(*msg2, 3, ASYNC),
836 MockRead(ASYNC, 0, 4), // EOF
839 Initialize(reads, arraysize(reads), writes, arraysize(writes));
841 AssertConnectFails(ERR_PROXY_AUTH_REQUESTED);
843 Run(2); // SpdySession consumes the next two reads and sends then to
844 // sock_ to be buffered.
845 AssertSyncReadEquals(kMsg1, kLen1);
846 AssertSyncReadEquals(kMsg2, kLen2);
849 TEST_P(SpdyProxyClientSocketTest, ReadErrorResponseBody) {
850 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
851 MockWrite writes[] = {
852 CreateMockWrite(*conn, 0, SYNCHRONOUS),
855 scoped_ptr<SpdyFrame> resp(ConstructConnectErrorReplyFrame());
856 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
857 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
858 MockRead reads[] = {
859 CreateMockRead(*resp, 1, ASYNC),
860 CreateMockRead(*msg1, 2, ASYNC),
861 CreateMockRead(*msg2, 3, ASYNC),
862 MockRead(ASYNC, 0, 4), // EOF
865 Initialize(reads, arraysize(reads), writes, arraysize(writes));
867 AssertConnectFails(ERR_TUNNEL_CONNECTION_FAILED);
870 // ----------- Reads and Writes
872 TEST_P(SpdyProxyClientSocketTest, AsyncReadAroundWrite) {
873 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
874 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
875 MockWrite writes[] = {
876 CreateMockWrite(*conn, 0, SYNCHRONOUS),
877 CreateMockWrite(*msg2, 3, SYNCHRONOUS),
880 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
881 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
882 scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
883 MockRead reads[] = {
884 CreateMockRead(*resp, 1, ASYNC),
885 CreateMockRead(*msg1, 2, ASYNC), // sync read
886 CreateMockRead(*msg3, 4, ASYNC), // async read
887 MockRead(ASYNC, 0, 5), // EOF
890 Initialize(reads, arraysize(reads), writes, arraysize(writes));
892 AssertConnectSucceeds();
894 Run(1);
895 AssertSyncReadEquals(kMsg1, kLen1);
897 AssertReadStarts(kMsg3, kLen3);
898 // Read should block until after the write succeeds
900 AssertAsyncWriteSucceeds(kMsg2, kLen2); // Runs 1 step
902 ASSERT_FALSE(read_callback_.have_result());
903 Run(1);
904 // Now the read will return
905 AssertReadReturns(kMsg3, kLen3);
908 TEST_P(SpdyProxyClientSocketTest, AsyncWriteAroundReads) {
909 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
910 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
911 MockWrite writes[] = {
912 CreateMockWrite(*conn, 0, SYNCHRONOUS),
913 CreateMockWrite(*msg2, 4, ASYNC),
916 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
917 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
918 scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
919 MockRead reads[] = {
920 CreateMockRead(*resp, 1, ASYNC),
921 CreateMockRead(*msg1, 2, ASYNC),
922 CreateMockRead(*msg3, 3, ASYNC),
923 MockRead(ASYNC, 0, 5), // EOF
926 Initialize(reads, arraysize(reads), writes, arraysize(writes));
928 AssertConnectSucceeds();
930 Run(1);
931 AssertSyncReadEquals(kMsg1, kLen1);
932 // Write should block until the read completes
933 AssertWriteReturns(kMsg2, kLen2, ERR_IO_PENDING);
935 AssertAsyncReadEquals(kMsg3, kLen3);
937 ASSERT_FALSE(write_callback_.have_result());
939 // Now the write will complete
940 Run(1);
941 AssertWriteLength(kLen2);
944 // ----------- Reading/Writing on Closed socket
946 // Reading from an already closed socket should return 0
947 TEST_P(SpdyProxyClientSocketTest, ReadOnClosedSocketReturnsZero) {
948 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
949 MockWrite writes[] = {
950 CreateMockWrite(*conn, 0, SYNCHRONOUS),
953 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
954 MockRead reads[] = {
955 CreateMockRead(*resp, 1, ASYNC),
956 MockRead(ASYNC, 0, 2), // EOF
959 Initialize(reads, arraysize(reads), writes, arraysize(writes));
961 AssertConnectSucceeds();
963 Run(1);
965 ASSERT_FALSE(sock_->IsConnected());
966 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
967 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
968 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
969 ASSERT_FALSE(sock_->IsConnectedAndIdle());
972 // Read pending when socket is closed should return 0
973 TEST_P(SpdyProxyClientSocketTest, PendingReadOnCloseReturnsZero) {
974 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
975 MockWrite writes[] = {
976 CreateMockWrite(*conn, 0, SYNCHRONOUS),
979 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
980 MockRead reads[] = {
981 CreateMockRead(*resp, 1, ASYNC),
982 MockRead(ASYNC, 0, 2), // EOF
985 Initialize(reads, arraysize(reads), writes, arraysize(writes));
987 AssertConnectSucceeds();
989 AssertReadStarts(kMsg1, kLen1);
991 Run(1);
993 ASSERT_EQ(0, read_callback_.WaitForResult());
996 // Reading from a disconnected socket is an error
997 TEST_P(SpdyProxyClientSocketTest,
998 ReadOnDisconnectSocketReturnsNotConnected) {
999 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1000 scoped_ptr<SpdyFrame> rst(
1001 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
1002 MockWrite writes[] = {
1003 CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 2),
1006 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1007 MockRead reads[] = {
1008 CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3), // EOF
1011 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1013 AssertConnectSucceeds();
1015 sock_->Disconnect();
1017 ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED,
1018 sock_->Read(NULL, 1, CompletionCallback()));
1020 // Let the RST_STREAM write while |rst| is in-scope.
1021 base::MessageLoop::current()->RunUntilIdle();
1024 // Reading buffered data from an already closed socket should return
1025 // buffered data, then 0.
1026 TEST_P(SpdyProxyClientSocketTest, ReadOnClosedSocketReturnsBufferedData) {
1027 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1028 MockWrite writes[] = {
1029 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1032 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1033 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
1034 MockRead reads[] = {
1035 CreateMockRead(*resp, 1, ASYNC),
1036 CreateMockRead(*msg1, 2, ASYNC),
1037 MockRead(ASYNC, 0, 3), // EOF
1040 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1042 AssertConnectSucceeds();
1044 Run(2);
1046 ASSERT_FALSE(sock_->IsConnected());
1047 scoped_refptr<IOBuffer> buf(new IOBuffer(kLen1));
1048 ASSERT_EQ(kLen1, sock_->Read(buf.get(), kLen1, CompletionCallback()));
1049 ASSERT_EQ(std::string(kMsg1, kLen1), std::string(buf->data(), kLen1));
1051 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
1052 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
1053 sock_->Disconnect();
1054 ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED,
1055 sock_->Read(NULL, 1, CompletionCallback()));
1058 // Calling Write() on a closed socket is an error
1059 TEST_P(SpdyProxyClientSocketTest, WriteOnClosedStream) {
1060 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1061 MockWrite writes[] = {
1062 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1065 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1066 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
1067 MockRead reads[] = {
1068 CreateMockRead(*resp, 1, ASYNC),
1069 MockRead(ASYNC, 0, 2), // EOF
1072 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1074 AssertConnectSucceeds();
1076 Run(1); // Read EOF which will close the stream
1077 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
1078 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED,
1079 sock_->Write(buf.get(), buf->size(), CompletionCallback()));
1082 // Calling Write() on a disconnected socket is an error
1083 TEST_P(SpdyProxyClientSocketTest, WriteOnDisconnectedSocket) {
1084 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1085 scoped_ptr<SpdyFrame> rst(
1086 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
1087 MockWrite writes[] = {
1088 CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 2),
1091 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1092 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
1093 MockRead reads[] = {
1094 CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3), // EOF
1097 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1099 AssertConnectSucceeds();
1101 sock_->Disconnect();
1103 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
1104 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED,
1105 sock_->Write(buf.get(), buf->size(), CompletionCallback()));
1107 // Let the RST_STREAM write while |rst| is in-scope.
1108 base::MessageLoop::current()->RunUntilIdle();
1111 // If the socket is closed with a pending Write(), the callback
1112 // should be called with ERR_CONNECTION_CLOSED.
1113 TEST_P(SpdyProxyClientSocketTest, WritePendingOnClose) {
1114 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1115 MockWrite writes[] = {
1116 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1117 MockWrite(ASYNC, ERR_ABORTED, 2),
1120 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1121 MockRead reads[] = {
1122 CreateMockRead(*resp, 1, ASYNC),
1123 MockRead(ASYNC, 0, 3), // EOF
1126 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1128 AssertConnectSucceeds();
1130 EXPECT_TRUE(sock_->IsConnected());
1132 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
1133 EXPECT_EQ(ERR_IO_PENDING,
1134 sock_->Write(buf.get(), buf->size(), write_callback_.callback()));
1136 CloseSpdySession(ERR_ABORTED, std::string());
1138 EXPECT_EQ(ERR_CONNECTION_CLOSED, write_callback_.WaitForResult());
1141 // If the socket is Disconnected with a pending Write(), the callback
1142 // should not be called.
1143 TEST_P(SpdyProxyClientSocketTest, DisconnectWithWritePending) {
1144 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1145 scoped_ptr<SpdyFrame> rst(
1146 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
1147 MockWrite writes[] = {
1148 CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 2),
1149 MockWrite(SYNCHRONOUS, 0, 3), // EOF
1152 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1153 MockRead reads[] = {
1154 CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 4), // EOF
1157 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1159 AssertConnectSucceeds();
1161 EXPECT_TRUE(sock_->IsConnected());
1163 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
1164 EXPECT_EQ(ERR_IO_PENDING,
1165 sock_->Write(buf.get(), buf->size(), write_callback_.callback()));
1167 sock_->Disconnect();
1169 EXPECT_FALSE(sock_->IsConnected());
1170 EXPECT_FALSE(write_callback_.have_result());
1172 // Let the RST_STREAM write while |rst| is in-scope.
1173 base::MessageLoop::current()->RunUntilIdle();
1176 // If the socket is Disconnected with a pending Read(), the callback
1177 // should not be called.
1178 TEST_P(SpdyProxyClientSocketTest, DisconnectWithReadPending) {
1179 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1180 scoped_ptr<SpdyFrame> rst(
1181 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
1182 MockWrite writes[] = {
1183 CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 2),
1186 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1187 MockRead reads[] = {
1188 CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3), // EOF
1191 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1193 AssertConnectSucceeds();
1195 EXPECT_TRUE(sock_->IsConnected());
1197 scoped_refptr<IOBuffer> buf(new IOBuffer(kLen1));
1198 ASSERT_EQ(ERR_IO_PENDING,
1199 sock_->Read(buf.get(), kLen1, read_callback_.callback()));
1201 sock_->Disconnect();
1203 EXPECT_FALSE(sock_->IsConnected());
1204 EXPECT_FALSE(read_callback_.have_result());
1206 // Let the RST_STREAM write while |rst| is in-scope.
1207 base::MessageLoop::current()->RunUntilIdle();
1210 // If the socket is Reset when both a read and write are pending,
1211 // both should be called back.
1212 TEST_P(SpdyProxyClientSocketTest, RstWithReadAndWritePending) {
1213 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1214 MockWrite writes[] = {
1215 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1216 MockWrite(ASYNC, ERR_ABORTED, 3),
1219 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1220 scoped_ptr<SpdyFrame> rst(
1221 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
1222 MockRead reads[] = {
1223 CreateMockRead(*resp, 1, ASYNC),
1224 CreateMockRead(*rst, 2, ASYNC),
1225 MockRead(ASYNC, 0, 4) // EOF
1228 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1230 AssertConnectSucceeds();
1232 EXPECT_TRUE(sock_->IsConnected());
1234 scoped_refptr<IOBuffer> read_buf(new IOBuffer(kLen1));
1235 ASSERT_EQ(ERR_IO_PENDING,
1236 sock_->Read(read_buf.get(), kLen1, read_callback_.callback()));
1238 scoped_refptr<IOBufferWithSize> write_buf(CreateBuffer(kMsg1, kLen1));
1239 EXPECT_EQ(
1240 ERR_IO_PENDING,
1241 sock_->Write(
1242 write_buf.get(), write_buf->size(), write_callback_.callback()));
1244 Run(2);
1246 EXPECT_TRUE(sock_.get());
1247 EXPECT_TRUE(read_callback_.have_result());
1248 EXPECT_TRUE(write_callback_.have_result());
1250 // Let the RST_STREAM write while |rst| is in-scope.
1251 base::MessageLoop::current()->RunUntilIdle();
1254 // Makes sure the proxy client socket's source gets the expected NetLog events
1255 // and only the expected NetLog events (No SpdySession events).
1256 TEST_P(SpdyProxyClientSocketTest, NetLog) {
1257 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1258 scoped_ptr<SpdyFrame> rst(
1259 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
1260 MockWrite writes[] = {
1261 CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 3),
1264 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1265 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
1266 MockRead reads[] = {
1267 CreateMockRead(*resp, 1, ASYNC), CreateMockRead(*msg1, 2, ASYNC),
1268 MockRead(ASYNC, 0, 4), // EOF
1271 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1273 AssertConnectSucceeds();
1275 Run(1); // SpdySession consumes the next read and sends it to
1276 // sock_ to be buffered.
1277 AssertSyncReadEquals(kMsg1, kLen1);
1279 NetLog::Source sock_source = sock_->NetLog().source();
1280 sock_.reset();
1282 TestNetLogEntry::List entry_list;
1283 net_log_.GetEntriesForSource(sock_source, &entry_list);
1285 ASSERT_EQ(entry_list.size(), 10u);
1286 EXPECT_TRUE(LogContainsBeginEvent(entry_list, 0, NetLog::TYPE_SOCKET_ALIVE));
1287 EXPECT_TRUE(LogContainsEvent(entry_list, 1,
1288 NetLog::TYPE_HTTP2_PROXY_CLIENT_SESSION,
1289 NetLog::PHASE_NONE));
1290 EXPECT_TRUE(LogContainsBeginEvent(entry_list, 2,
1291 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_SEND_REQUEST));
1292 EXPECT_TRUE(LogContainsEvent(entry_list, 3,
1293 NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
1294 NetLog::PHASE_NONE));
1295 EXPECT_TRUE(LogContainsEndEvent(entry_list, 4,
1296 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_SEND_REQUEST));
1297 EXPECT_TRUE(LogContainsBeginEvent(entry_list, 5,
1298 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_READ_HEADERS));
1299 EXPECT_TRUE(LogContainsEvent(entry_list, 6,
1300 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
1301 NetLog::PHASE_NONE));
1302 EXPECT_TRUE(LogContainsEndEvent(entry_list, 7,
1303 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_READ_HEADERS));
1304 EXPECT_TRUE(LogContainsEvent(entry_list, 8,
1305 NetLog::TYPE_SOCKET_BYTES_RECEIVED,
1306 NetLog::PHASE_NONE));
1307 EXPECT_TRUE(LogContainsEndEvent(entry_list, 9, NetLog::TYPE_SOCKET_ALIVE));
1309 // Let the RST_STREAM write while |rst| is in-scope.
1310 base::MessageLoop::current()->RunUntilIdle();
1313 // CompletionCallback that causes the SpdyProxyClientSocket to be
1314 // deleted when Run is invoked.
1315 class DeleteSockCallback : public TestCompletionCallbackBase {
1316 public:
1317 explicit DeleteSockCallback(scoped_ptr<SpdyProxyClientSocket>* sock)
1318 : sock_(sock),
1319 callback_(base::Bind(&DeleteSockCallback::OnComplete,
1320 base::Unretained(this))) {
1323 ~DeleteSockCallback() override {}
1325 const CompletionCallback& callback() const { return callback_; }
1327 private:
1328 void OnComplete(int result) {
1329 sock_->reset(NULL);
1330 SetResult(result);
1333 scoped_ptr<SpdyProxyClientSocket>* sock_;
1334 CompletionCallback callback_;
1336 DISALLOW_COPY_AND_ASSIGN(DeleteSockCallback);
1339 // If the socket is Reset when both a read and write are pending, and the
1340 // read callback causes the socket to be deleted, the write callback should
1341 // not be called.
1342 TEST_P(SpdyProxyClientSocketTest, RstWithReadAndWritePendingDelete) {
1343 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1344 MockWrite writes[] = {
1345 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1346 MockWrite(ASYNC, ERR_ABORTED, 3),
1349 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1350 scoped_ptr<SpdyFrame> rst(
1351 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
1352 MockRead reads[] = {
1353 CreateMockRead(*resp, 1, ASYNC),
1354 CreateMockRead(*rst, 2, ASYNC),
1355 MockRead(ASYNC, 0, 4), // EOF
1358 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1360 AssertConnectSucceeds();
1362 EXPECT_TRUE(sock_->IsConnected());
1364 DeleteSockCallback read_callback(&sock_);
1366 scoped_refptr<IOBuffer> read_buf(new IOBuffer(kLen1));
1367 ASSERT_EQ(ERR_IO_PENDING,
1368 sock_->Read(read_buf.get(), kLen1, read_callback.callback()));
1370 scoped_refptr<IOBufferWithSize> write_buf(CreateBuffer(kMsg1, kLen1));
1371 EXPECT_EQ(
1372 ERR_IO_PENDING,
1373 sock_->Write(
1374 write_buf.get(), write_buf->size(), write_callback_.callback()));
1376 Run(1);
1378 EXPECT_FALSE(sock_.get());
1379 EXPECT_TRUE(read_callback.have_result());
1380 EXPECT_FALSE(write_callback_.have_result());
1382 // Let the RST_STREAM write while |rst| is in-scope.
1383 base::MessageLoop::current()->RunUntilIdle();
1386 } // namespace net