Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / net / spdy / spdy_proxy_client_socket_unittest.cc
blobe3f370fbe843b66d94ce74797638527ac5ad2002
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 (*block)[spdy_util_.GetPathKey()] = kOriginHostPort;
316 (*block)[spdy_util_.GetHostKey()] = kOriginHost;
317 (*block)["user-agent"] = kUserAgent;
318 spdy_util_.MaybeAddVersionHeader(block);
321 void SpdyProxyClientSocketTest::PopulateConnectReplyIR(SpdyHeaderBlock* block,
322 const char* status) {
323 (*block)[spdy_util_.GetStatusKey()] = status;
324 spdy_util_.MaybeAddVersionHeader(block);
327 // Constructs a standard SPDY SYN_STREAM frame for a CONNECT request.
328 SpdyFrame*
329 SpdyProxyClientSocketTest::ConstructConnectRequestFrame() {
330 SpdyHeaderBlock block;
331 PopulateConnectRequestIR(&block);
332 return spdy_util_.ConstructSpdySyn(kStreamId, block, LOWEST, false, false);
335 // Constructs a SPDY SYN_STREAM frame for a CONNECT request which includes
336 // Proxy-Authorization headers.
337 SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectAuthRequestFrame() {
338 SpdyHeaderBlock block;
339 PopulateConnectRequestIR(&block);
340 block["proxy-authorization"] = "Basic Zm9vOmJhcg==";
341 return spdy_util_.ConstructSpdySyn(kStreamId, block, LOWEST, false, false);
344 // Constructs a standard SPDY SYN_REPLY frame to match the SPDY CONNECT.
345 SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectReplyFrame() {
346 SpdyHeaderBlock block;
347 PopulateConnectReplyIR(&block, "200");
348 SpdySynReplyIR reply_ir(kStreamId);
349 return spdy_util_.ConstructSpdyReply(kStreamId, block);
352 // Constructs a standard SPDY SYN_REPLY frame to match the SPDY CONNECT,
353 // including Proxy-Authenticate headers.
354 SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectAuthReplyFrame() {
355 SpdyHeaderBlock block;
356 PopulateConnectReplyIR(&block, "407");
357 block["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
358 return spdy_util_.ConstructSpdyReply(kStreamId, block);
361 // Constructs a SPDY SYN_REPLY frame with an HTTP 302 redirect.
362 SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectRedirectReplyFrame() {
363 SpdyHeaderBlock block;
364 PopulateConnectReplyIR(&block, "302");
365 block["location"] = kRedirectUrl;
366 block["set-cookie"] = "foo=bar";
367 return spdy_util_.ConstructSpdyReply(kStreamId, block);
370 // Constructs a SPDY SYN_REPLY frame with an HTTP 500 error.
371 SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectErrorReplyFrame() {
372 SpdyHeaderBlock block;
373 PopulateConnectReplyIR(&block, "500");
374 return spdy_util_.ConstructSpdyReply(kStreamId, block);
377 SpdyFrame* SpdyProxyClientSocketTest::ConstructBodyFrame(
378 const char* data,
379 int length) {
380 return framer_.CreateDataFrame(kStreamId, data, length, DATA_FLAG_NONE);
383 // ----------- Connect
385 TEST_P(SpdyProxyClientSocketTest, ConnectSendsCorrectRequest) {
386 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
387 MockWrite writes[] = {
388 CreateMockWrite(*conn, 0, SYNCHRONOUS),
391 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
392 MockRead reads[] = {
393 CreateMockRead(*resp, 1, ASYNC),
394 MockRead(ASYNC, 0, 2), // EOF
397 Initialize(reads, arraysize(reads), writes, arraysize(writes));
399 ASSERT_FALSE(sock_->IsConnected());
401 AssertConnectSucceeds();
403 AssertConnectionEstablished();
406 TEST_P(SpdyProxyClientSocketTest, ConnectWithAuthRequested) {
407 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
408 MockWrite writes[] = {
409 CreateMockWrite(*conn, 0, SYNCHRONOUS),
412 scoped_ptr<SpdyFrame> resp(ConstructConnectAuthReplyFrame());
413 MockRead reads[] = {
414 CreateMockRead(*resp, 1, ASYNC),
415 MockRead(ASYNC, 0, 2), // EOF
418 Initialize(reads, arraysize(reads), writes, arraysize(writes));
420 AssertConnectFails(ERR_PROXY_AUTH_REQUESTED);
422 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
423 ASSERT_TRUE(response != NULL);
424 ASSERT_EQ(407, response->headers->response_code());
427 TEST_P(SpdyProxyClientSocketTest, ConnectWithAuthCredentials) {
428 scoped_ptr<SpdyFrame> conn(ConstructConnectAuthRequestFrame());
429 MockWrite writes[] = {
430 CreateMockWrite(*conn, 0, SYNCHRONOUS),
433 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
434 MockRead reads[] = {
435 CreateMockRead(*resp, 1, ASYNC),
436 MockRead(ASYNC, 0, 2), // EOF
439 Initialize(reads, arraysize(reads), writes, arraysize(writes));
440 AddAuthToCache();
442 AssertConnectSucceeds();
444 AssertConnectionEstablished();
447 TEST_P(SpdyProxyClientSocketTest, ConnectRedirects) {
448 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
449 scoped_ptr<SpdyFrame> rst(
450 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
451 MockWrite writes[] = {
452 CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 2),
455 scoped_ptr<SpdyFrame> resp(ConstructConnectRedirectReplyFrame());
456 MockRead reads[] = {
457 CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3), // EOF
460 Initialize(reads, arraysize(reads), writes, arraysize(writes));
462 AssertConnectFails(ERR_HTTPS_PROXY_TUNNEL_RESPONSE);
464 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
465 ASSERT_TRUE(response != NULL);
467 const HttpResponseHeaders* headers = response->headers.get();
468 ASSERT_EQ(302, headers->response_code());
469 ASSERT_FALSE(headers->HasHeader("set-cookie"));
470 ASSERT_TRUE(headers->HasHeaderValue("content-length", "0"));
472 std::string location;
473 ASSERT_TRUE(headers->IsRedirect(&location));
474 ASSERT_EQ(location, kRedirectUrl);
476 // Let the RST_STREAM write while |rst| is in-scope.
477 base::MessageLoop::current()->RunUntilIdle();
480 TEST_P(SpdyProxyClientSocketTest, ConnectFails) {
481 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
482 MockWrite writes[] = {
483 CreateMockWrite(*conn, 0, SYNCHRONOUS),
486 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
487 MockRead reads[] = {
488 MockRead(ASYNC, 0, 1), // EOF
491 Initialize(reads, arraysize(reads), writes, arraysize(writes));
493 ASSERT_FALSE(sock_->IsConnected());
495 AssertConnectFails(ERR_CONNECTION_CLOSED);
497 ASSERT_FALSE(sock_->IsConnected());
500 // ----------- WasEverUsed
502 TEST_P(SpdyProxyClientSocketTest, WasEverUsedReturnsCorrectValues) {
503 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
504 scoped_ptr<SpdyFrame> rst(
505 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
506 MockWrite writes[] = {
507 CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 2),
510 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
511 MockRead reads[] = {
512 CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3), // EOF
515 Initialize(reads, arraysize(reads), writes, arraysize(writes));
517 EXPECT_FALSE(sock_->WasEverUsed());
518 AssertConnectSucceeds();
519 EXPECT_TRUE(sock_->WasEverUsed());
520 sock_->Disconnect();
521 EXPECT_TRUE(sock_->WasEverUsed());
523 // Let the RST_STREAM write while |rst| is in-scope.
524 base::MessageLoop::current()->RunUntilIdle();
527 // ----------- GetPeerAddress
529 TEST_P(SpdyProxyClientSocketTest, GetPeerAddressReturnsCorrectValues) {
530 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
531 MockWrite writes[] = {
532 CreateMockWrite(*conn, 0, SYNCHRONOUS),
535 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
536 MockRead reads[] = {
537 CreateMockRead(*resp, 1, ASYNC),
538 MockRead(ASYNC, 0, 2), // EOF
541 Initialize(reads, arraysize(reads), writes, arraysize(writes));
543 IPEndPoint addr;
544 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr));
546 AssertConnectSucceeds();
547 EXPECT_TRUE(sock_->IsConnected());
548 EXPECT_EQ(OK, sock_->GetPeerAddress(&addr));
550 Run(1);
552 EXPECT_FALSE(sock_->IsConnected());
553 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr));
555 sock_->Disconnect();
557 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr));
560 // ----------- Write
562 TEST_P(SpdyProxyClientSocketTest, WriteSendsDataInDataFrame) {
563 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
564 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
565 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
566 MockWrite writes[] = {
567 CreateMockWrite(*conn, 0, SYNCHRONOUS),
568 CreateMockWrite(*msg1, 2, SYNCHRONOUS),
569 CreateMockWrite(*msg2, 3, SYNCHRONOUS),
572 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
573 MockRead reads[] = {
574 CreateMockRead(*resp, 1, ASYNC),
575 MockRead(ASYNC, 0, 4), // EOF
578 Initialize(reads, arraysize(reads), writes, arraysize(writes));
580 AssertConnectSucceeds();
582 AssertAsyncWriteSucceeds(kMsg1, kLen1);
583 AssertAsyncWriteSucceeds(kMsg2, kLen2);
586 TEST_P(SpdyProxyClientSocketTest, WriteSplitsLargeDataIntoMultipleFrames) {
587 std::string chunk_data(kMaxSpdyFrameChunkSize, 'x');
588 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
589 scoped_ptr<SpdyFrame> chunk(ConstructBodyFrame(chunk_data.data(),
590 chunk_data.length()));
591 MockWrite writes[] = {
592 CreateMockWrite(*conn, 0, SYNCHRONOUS),
593 CreateMockWrite(*chunk, 2, SYNCHRONOUS),
594 CreateMockWrite(*chunk, 3, SYNCHRONOUS),
595 CreateMockWrite(*chunk, 4, SYNCHRONOUS)
598 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
599 MockRead reads[] = {
600 CreateMockRead(*resp, 1, ASYNC),
601 MockRead(ASYNC, 0, 5), // EOF
604 Initialize(reads, arraysize(reads), writes, arraysize(writes));
606 AssertConnectSucceeds();
608 std::string big_data(kMaxSpdyFrameChunkSize * 3, 'x');
609 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(big_data.data(),
610 big_data.length()));
612 EXPECT_EQ(ERR_IO_PENDING,
613 sock_->Write(buf.get(), buf->size(), write_callback_.callback()));
614 data_->RunFor(3);
616 EXPECT_EQ(buf->size(), write_callback_.WaitForResult());
619 // ----------- Read
621 TEST_P(SpdyProxyClientSocketTest, ReadReadsDataInDataFrame) {
622 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
623 MockWrite writes[] = {
624 CreateMockWrite(*conn, 0, SYNCHRONOUS),
627 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
628 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
629 MockRead reads[] = {
630 CreateMockRead(*resp, 1, ASYNC),
631 CreateMockRead(*msg1, 2, ASYNC),
632 MockRead(ASYNC, 0, 3), // EOF
635 Initialize(reads, arraysize(reads), writes, arraysize(writes));
637 AssertConnectSucceeds();
639 Run(1); // SpdySession consumes the next read and sends it to
640 // sock_ to be buffered.
641 AssertSyncReadEquals(kMsg1, kLen1);
644 TEST_P(SpdyProxyClientSocketTest, ReadDataFromBufferedFrames) {
645 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
646 MockWrite writes[] = {
647 CreateMockWrite(*conn, 0, SYNCHRONOUS),
650 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
651 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
652 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
653 MockRead reads[] = {
654 CreateMockRead(*resp, 1, ASYNC),
655 CreateMockRead(*msg1, 2, ASYNC),
656 CreateMockRead(*msg2, 3, ASYNC),
657 MockRead(ASYNC, 0, 4), // EOF
660 Initialize(reads, arraysize(reads), writes, arraysize(writes));
662 AssertConnectSucceeds();
664 Run(1); // SpdySession consumes the next read and sends it to
665 // sock_ to be buffered.
666 AssertSyncReadEquals(kMsg1, kLen1);
667 Run(1); // SpdySession consumes the next read and sends it to
668 // sock_ to be buffered.
669 AssertSyncReadEquals(kMsg2, kLen2);
672 TEST_P(SpdyProxyClientSocketTest, ReadDataMultipleBufferedFrames) {
673 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
674 MockWrite writes[] = {
675 CreateMockWrite(*conn, 0, SYNCHRONOUS),
678 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
679 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
680 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
681 MockRead reads[] = {
682 CreateMockRead(*resp, 1, ASYNC),
683 CreateMockRead(*msg1, 2, ASYNC),
684 CreateMockRead(*msg2, 3, ASYNC),
685 MockRead(ASYNC, 0, 4), // EOF
688 Initialize(reads, arraysize(reads), writes, arraysize(writes));
690 AssertConnectSucceeds();
692 Run(2); // SpdySession consumes the next two reads and sends then to
693 // sock_ to be buffered.
694 AssertSyncReadEquals(kMsg1, kLen1);
695 AssertSyncReadEquals(kMsg2, kLen2);
698 TEST_P(SpdyProxyClientSocketTest,
699 LargeReadWillMergeDataFromDifferentFrames) {
700 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
701 MockWrite writes[] = {
702 CreateMockWrite(*conn, 0, SYNCHRONOUS),
705 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
706 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
707 scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
708 MockRead reads[] = {
709 CreateMockRead(*resp, 1, ASYNC),
710 CreateMockRead(*msg3, 2, ASYNC),
711 CreateMockRead(*msg3, 3, ASYNC),
712 MockRead(ASYNC, 0, 4), // EOF
715 Initialize(reads, arraysize(reads), writes, arraysize(writes));
717 AssertConnectSucceeds();
719 Run(2); // SpdySession consumes the next two reads and sends then to
720 // sock_ to be buffered.
721 // The payload from two data frames, each with kMsg3 will be combined
722 // together into a single read().
723 AssertSyncReadEquals(kMsg33, kLen33);
726 TEST_P(SpdyProxyClientSocketTest, MultipleShortReadsThenMoreRead) {
727 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
728 MockWrite writes[] = {
729 CreateMockWrite(*conn, 0, SYNCHRONOUS),
732 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
733 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
734 scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
735 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
736 MockRead reads[] = {
737 CreateMockRead(*resp, 1, ASYNC),
738 CreateMockRead(*msg1, 2, ASYNC),
739 CreateMockRead(*msg3, 3, ASYNC),
740 CreateMockRead(*msg3, 4, ASYNC),
741 CreateMockRead(*msg2, 5, ASYNC),
742 MockRead(ASYNC, 0, 6), // EOF
745 Initialize(reads, arraysize(reads), writes, arraysize(writes));
747 AssertConnectSucceeds();
749 Run(4); // SpdySession consumes the next four reads and sends then to
750 // sock_ to be buffered.
751 AssertSyncReadEquals(kMsg1, kLen1);
752 // The payload from two data frames, each with kMsg3 will be combined
753 // together into a single read().
754 AssertSyncReadEquals(kMsg33, kLen33);
755 AssertSyncReadEquals(kMsg2, kLen2);
758 TEST_P(SpdyProxyClientSocketTest, ReadWillSplitDataFromLargeFrame) {
759 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
760 MockWrite writes[] = {
761 CreateMockWrite(*conn, 0, SYNCHRONOUS),
764 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
765 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
766 scoped_ptr<SpdyFrame> msg33(ConstructBodyFrame(kMsg33, kLen33));
767 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
768 MockRead reads[] = {
769 CreateMockRead(*resp, 1, ASYNC),
770 CreateMockRead(*msg1, 2, ASYNC),
771 CreateMockRead(*msg33, 3, ASYNC),
772 MockRead(ASYNC, 0, 4), // EOF
775 Initialize(reads, arraysize(reads), writes, arraysize(writes));
777 AssertConnectSucceeds();
779 Run(2); // SpdySession consumes the next two reads and sends then to
780 // sock_ to be buffered.
781 AssertSyncReadEquals(kMsg1, kLen1);
782 // The payload from the single large data frame will be read across
783 // two different reads.
784 AssertSyncReadEquals(kMsg3, kLen3);
785 AssertSyncReadEquals(kMsg3, kLen3);
788 TEST_P(SpdyProxyClientSocketTest, MultipleReadsFromSameLargeFrame) {
789 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
790 MockWrite writes[] = {
791 CreateMockWrite(*conn, 0, SYNCHRONOUS),
794 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
795 scoped_ptr<SpdyFrame> msg333(ConstructBodyFrame(kMsg333, kLen333));
796 MockRead reads[] = {
797 CreateMockRead(*resp, 1, ASYNC),
798 CreateMockRead(*msg333, 2, ASYNC),
799 MockRead(ASYNC, 0, 3), // EOF
802 Initialize(reads, arraysize(reads), writes, arraysize(writes));
804 AssertConnectSucceeds();
806 Run(1); // SpdySession consumes the next read and sends it to
807 // sock_ to be buffered.
808 // The payload from the single large data frame will be read across
809 // two different reads.
810 AssertSyncReadEquals(kMsg33, kLen33);
812 // Now attempt to do a read of more data than remains buffered
813 scoped_refptr<IOBuffer> buf(new IOBuffer(kLen33));
814 ASSERT_EQ(kLen3, sock_->Read(buf.get(), kLen33, read_callback_.callback()));
815 ASSERT_EQ(std::string(kMsg3, kLen3), std::string(buf->data(), kLen3));
816 ASSERT_TRUE(sock_->IsConnected());
819 TEST_P(SpdyProxyClientSocketTest, ReadAuthResponseBody) {
820 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
821 MockWrite writes[] = {
822 CreateMockWrite(*conn, 0, SYNCHRONOUS),
825 scoped_ptr<SpdyFrame> resp(ConstructConnectAuthReplyFrame());
826 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
827 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
828 MockRead reads[] = {
829 CreateMockRead(*resp, 1, ASYNC),
830 CreateMockRead(*msg1, 2, ASYNC),
831 CreateMockRead(*msg2, 3, ASYNC),
832 MockRead(ASYNC, 0, 4), // EOF
835 Initialize(reads, arraysize(reads), writes, arraysize(writes));
837 AssertConnectFails(ERR_PROXY_AUTH_REQUESTED);
839 Run(2); // SpdySession consumes the next two reads and sends then to
840 // sock_ to be buffered.
841 AssertSyncReadEquals(kMsg1, kLen1);
842 AssertSyncReadEquals(kMsg2, kLen2);
845 TEST_P(SpdyProxyClientSocketTest, ReadErrorResponseBody) {
846 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
847 MockWrite writes[] = {
848 CreateMockWrite(*conn, 0, SYNCHRONOUS),
851 scoped_ptr<SpdyFrame> resp(ConstructConnectErrorReplyFrame());
852 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
853 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
854 MockRead reads[] = {
855 CreateMockRead(*resp, 1, ASYNC),
856 CreateMockRead(*msg1, 2, ASYNC),
857 CreateMockRead(*msg2, 3, ASYNC),
858 MockRead(ASYNC, 0, 4), // EOF
861 Initialize(reads, arraysize(reads), writes, arraysize(writes));
863 AssertConnectFails(ERR_TUNNEL_CONNECTION_FAILED);
866 // ----------- Reads and Writes
868 TEST_P(SpdyProxyClientSocketTest, AsyncReadAroundWrite) {
869 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
870 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
871 MockWrite writes[] = {
872 CreateMockWrite(*conn, 0, SYNCHRONOUS),
873 CreateMockWrite(*msg2, 3, SYNCHRONOUS),
876 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
877 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
878 scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
879 MockRead reads[] = {
880 CreateMockRead(*resp, 1, ASYNC),
881 CreateMockRead(*msg1, 2, ASYNC), // sync read
882 CreateMockRead(*msg3, 4, ASYNC), // async read
883 MockRead(ASYNC, 0, 5), // EOF
886 Initialize(reads, arraysize(reads), writes, arraysize(writes));
888 AssertConnectSucceeds();
890 Run(1);
891 AssertSyncReadEquals(kMsg1, kLen1);
893 AssertReadStarts(kMsg3, kLen3);
894 // Read should block until after the write succeeds
896 AssertAsyncWriteSucceeds(kMsg2, kLen2); // Runs 1 step
898 ASSERT_FALSE(read_callback_.have_result());
899 Run(1);
900 // Now the read will return
901 AssertReadReturns(kMsg3, kLen3);
904 TEST_P(SpdyProxyClientSocketTest, AsyncWriteAroundReads) {
905 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
906 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
907 MockWrite writes[] = {
908 CreateMockWrite(*conn, 0, SYNCHRONOUS),
909 CreateMockWrite(*msg2, 4, ASYNC),
912 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
913 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
914 scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
915 MockRead reads[] = {
916 CreateMockRead(*resp, 1, ASYNC),
917 CreateMockRead(*msg1, 2, ASYNC),
918 CreateMockRead(*msg3, 3, ASYNC),
919 MockRead(ASYNC, 0, 5), // EOF
922 Initialize(reads, arraysize(reads), writes, arraysize(writes));
924 AssertConnectSucceeds();
926 Run(1);
927 AssertSyncReadEquals(kMsg1, kLen1);
928 // Write should block until the read completes
929 AssertWriteReturns(kMsg2, kLen2, ERR_IO_PENDING);
931 AssertAsyncReadEquals(kMsg3, kLen3);
933 ASSERT_FALSE(write_callback_.have_result());
935 // Now the write will complete
936 Run(1);
937 AssertWriteLength(kLen2);
940 // ----------- Reading/Writing on Closed socket
942 // Reading from an already closed socket should return 0
943 TEST_P(SpdyProxyClientSocketTest, ReadOnClosedSocketReturnsZero) {
944 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
945 MockWrite writes[] = {
946 CreateMockWrite(*conn, 0, SYNCHRONOUS),
949 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
950 MockRead reads[] = {
951 CreateMockRead(*resp, 1, ASYNC),
952 MockRead(ASYNC, 0, 2), // EOF
955 Initialize(reads, arraysize(reads), writes, arraysize(writes));
957 AssertConnectSucceeds();
959 Run(1);
961 ASSERT_FALSE(sock_->IsConnected());
962 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
963 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
964 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
965 ASSERT_FALSE(sock_->IsConnectedAndIdle());
968 // Read pending when socket is closed should return 0
969 TEST_P(SpdyProxyClientSocketTest, PendingReadOnCloseReturnsZero) {
970 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
971 MockWrite writes[] = {
972 CreateMockWrite(*conn, 0, SYNCHRONOUS),
975 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
976 MockRead reads[] = {
977 CreateMockRead(*resp, 1, ASYNC),
978 MockRead(ASYNC, 0, 2), // EOF
981 Initialize(reads, arraysize(reads), writes, arraysize(writes));
983 AssertConnectSucceeds();
985 AssertReadStarts(kMsg1, kLen1);
987 Run(1);
989 ASSERT_EQ(0, read_callback_.WaitForResult());
992 // Reading from a disconnected socket is an error
993 TEST_P(SpdyProxyClientSocketTest,
994 ReadOnDisconnectSocketReturnsNotConnected) {
995 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
996 scoped_ptr<SpdyFrame> rst(
997 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
998 MockWrite writes[] = {
999 CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 2),
1002 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1003 MockRead reads[] = {
1004 CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3), // EOF
1007 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1009 AssertConnectSucceeds();
1011 sock_->Disconnect();
1013 ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED,
1014 sock_->Read(NULL, 1, CompletionCallback()));
1016 // Let the RST_STREAM write while |rst| is in-scope.
1017 base::MessageLoop::current()->RunUntilIdle();
1020 // Reading buffered data from an already closed socket should return
1021 // buffered data, then 0.
1022 TEST_P(SpdyProxyClientSocketTest, ReadOnClosedSocketReturnsBufferedData) {
1023 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1024 MockWrite writes[] = {
1025 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1028 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1029 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
1030 MockRead reads[] = {
1031 CreateMockRead(*resp, 1, ASYNC),
1032 CreateMockRead(*msg1, 2, ASYNC),
1033 MockRead(ASYNC, 0, 3), // EOF
1036 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1038 AssertConnectSucceeds();
1040 Run(2);
1042 ASSERT_FALSE(sock_->IsConnected());
1043 scoped_refptr<IOBuffer> buf(new IOBuffer(kLen1));
1044 ASSERT_EQ(kLen1, sock_->Read(buf.get(), kLen1, CompletionCallback()));
1045 ASSERT_EQ(std::string(kMsg1, kLen1), std::string(buf->data(), kLen1));
1047 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
1048 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
1049 sock_->Disconnect();
1050 ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED,
1051 sock_->Read(NULL, 1, CompletionCallback()));
1054 // Calling Write() on a closed socket is an error
1055 TEST_P(SpdyProxyClientSocketTest, WriteOnClosedStream) {
1056 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1057 MockWrite writes[] = {
1058 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1061 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1062 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
1063 MockRead reads[] = {
1064 CreateMockRead(*resp, 1, ASYNC),
1065 MockRead(ASYNC, 0, 2), // EOF
1068 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1070 AssertConnectSucceeds();
1072 Run(1); // Read EOF which will close the stream
1073 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
1074 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED,
1075 sock_->Write(buf.get(), buf->size(), CompletionCallback()));
1078 // Calling Write() on a disconnected socket is an error
1079 TEST_P(SpdyProxyClientSocketTest, WriteOnDisconnectedSocket) {
1080 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1081 scoped_ptr<SpdyFrame> rst(
1082 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
1083 MockWrite writes[] = {
1084 CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 2),
1087 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1088 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
1089 MockRead reads[] = {
1090 CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3), // EOF
1093 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1095 AssertConnectSucceeds();
1097 sock_->Disconnect();
1099 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
1100 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED,
1101 sock_->Write(buf.get(), buf->size(), CompletionCallback()));
1103 // Let the RST_STREAM write while |rst| is in-scope.
1104 base::MessageLoop::current()->RunUntilIdle();
1107 // If the socket is closed with a pending Write(), the callback
1108 // should be called with ERR_CONNECTION_CLOSED.
1109 TEST_P(SpdyProxyClientSocketTest, WritePendingOnClose) {
1110 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1111 MockWrite writes[] = {
1112 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1113 MockWrite(ASYNC, ERR_ABORTED, 2),
1116 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1117 MockRead reads[] = {
1118 CreateMockRead(*resp, 1, ASYNC),
1119 MockRead(ASYNC, 0, 3), // EOF
1122 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1124 AssertConnectSucceeds();
1126 EXPECT_TRUE(sock_->IsConnected());
1128 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
1129 EXPECT_EQ(ERR_IO_PENDING,
1130 sock_->Write(buf.get(), buf->size(), write_callback_.callback()));
1132 CloseSpdySession(ERR_ABORTED, std::string());
1134 EXPECT_EQ(ERR_CONNECTION_CLOSED, write_callback_.WaitForResult());
1137 // If the socket is Disconnected with a pending Write(), the callback
1138 // should not be called.
1139 TEST_P(SpdyProxyClientSocketTest, DisconnectWithWritePending) {
1140 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1141 scoped_ptr<SpdyFrame> rst(
1142 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
1143 MockWrite writes[] = {
1144 CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 2),
1145 MockWrite(SYNCHRONOUS, 0, 3), // EOF
1148 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1149 MockRead reads[] = {
1150 CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 4), // EOF
1153 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1155 AssertConnectSucceeds();
1157 EXPECT_TRUE(sock_->IsConnected());
1159 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
1160 EXPECT_EQ(ERR_IO_PENDING,
1161 sock_->Write(buf.get(), buf->size(), write_callback_.callback()));
1163 sock_->Disconnect();
1165 EXPECT_FALSE(sock_->IsConnected());
1166 EXPECT_FALSE(write_callback_.have_result());
1168 // Let the RST_STREAM write while |rst| is in-scope.
1169 base::MessageLoop::current()->RunUntilIdle();
1172 // If the socket is Disconnected with a pending Read(), the callback
1173 // should not be called.
1174 TEST_P(SpdyProxyClientSocketTest, DisconnectWithReadPending) {
1175 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1176 scoped_ptr<SpdyFrame> rst(
1177 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
1178 MockWrite writes[] = {
1179 CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 2),
1182 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1183 MockRead reads[] = {
1184 CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3), // EOF
1187 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1189 AssertConnectSucceeds();
1191 EXPECT_TRUE(sock_->IsConnected());
1193 scoped_refptr<IOBuffer> buf(new IOBuffer(kLen1));
1194 ASSERT_EQ(ERR_IO_PENDING,
1195 sock_->Read(buf.get(), kLen1, read_callback_.callback()));
1197 sock_->Disconnect();
1199 EXPECT_FALSE(sock_->IsConnected());
1200 EXPECT_FALSE(read_callback_.have_result());
1202 // Let the RST_STREAM write while |rst| is in-scope.
1203 base::MessageLoop::current()->RunUntilIdle();
1206 // If the socket is Reset when both a read and write are pending,
1207 // both should be called back.
1208 TEST_P(SpdyProxyClientSocketTest, RstWithReadAndWritePending) {
1209 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1210 MockWrite writes[] = {
1211 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1212 MockWrite(ASYNC, ERR_ABORTED, 3),
1215 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1216 scoped_ptr<SpdyFrame> rst(
1217 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
1218 MockRead reads[] = {
1219 CreateMockRead(*resp, 1, ASYNC),
1220 CreateMockRead(*rst, 2, ASYNC),
1221 MockRead(ASYNC, 0, 4) // EOF
1224 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1226 AssertConnectSucceeds();
1228 EXPECT_TRUE(sock_->IsConnected());
1230 scoped_refptr<IOBuffer> read_buf(new IOBuffer(kLen1));
1231 ASSERT_EQ(ERR_IO_PENDING,
1232 sock_->Read(read_buf.get(), kLen1, read_callback_.callback()));
1234 scoped_refptr<IOBufferWithSize> write_buf(CreateBuffer(kMsg1, kLen1));
1235 EXPECT_EQ(
1236 ERR_IO_PENDING,
1237 sock_->Write(
1238 write_buf.get(), write_buf->size(), write_callback_.callback()));
1240 Run(2);
1242 EXPECT_TRUE(sock_.get());
1243 EXPECT_TRUE(read_callback_.have_result());
1244 EXPECT_TRUE(write_callback_.have_result());
1246 // Let the RST_STREAM write while |rst| is in-scope.
1247 base::MessageLoop::current()->RunUntilIdle();
1250 // Makes sure the proxy client socket's source gets the expected NetLog events
1251 // and only the expected NetLog events (No SpdySession events).
1252 TEST_P(SpdyProxyClientSocketTest, NetLog) {
1253 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1254 scoped_ptr<SpdyFrame> rst(
1255 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
1256 MockWrite writes[] = {
1257 CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 3),
1260 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1261 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
1262 MockRead reads[] = {
1263 CreateMockRead(*resp, 1, ASYNC), CreateMockRead(*msg1, 2, ASYNC),
1264 MockRead(ASYNC, 0, 4), // EOF
1267 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1269 AssertConnectSucceeds();
1271 Run(1); // SpdySession consumes the next read and sends it to
1272 // sock_ to be buffered.
1273 AssertSyncReadEquals(kMsg1, kLen1);
1275 NetLog::Source sock_source = sock_->NetLog().source();
1276 sock_.reset();
1278 TestNetLogEntry::List entry_list;
1279 net_log_.GetEntriesForSource(sock_source, &entry_list);
1281 ASSERT_EQ(entry_list.size(), 10u);
1282 EXPECT_TRUE(LogContainsBeginEvent(entry_list, 0, NetLog::TYPE_SOCKET_ALIVE));
1283 EXPECT_TRUE(LogContainsEvent(entry_list, 1,
1284 NetLog::TYPE_HTTP2_PROXY_CLIENT_SESSION,
1285 NetLog::PHASE_NONE));
1286 EXPECT_TRUE(LogContainsBeginEvent(entry_list, 2,
1287 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_SEND_REQUEST));
1288 EXPECT_TRUE(LogContainsEvent(entry_list, 3,
1289 NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
1290 NetLog::PHASE_NONE));
1291 EXPECT_TRUE(LogContainsEndEvent(entry_list, 4,
1292 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_SEND_REQUEST));
1293 EXPECT_TRUE(LogContainsBeginEvent(entry_list, 5,
1294 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_READ_HEADERS));
1295 EXPECT_TRUE(LogContainsEvent(entry_list, 6,
1296 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
1297 NetLog::PHASE_NONE));
1298 EXPECT_TRUE(LogContainsEndEvent(entry_list, 7,
1299 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_READ_HEADERS));
1300 EXPECT_TRUE(LogContainsEvent(entry_list, 8,
1301 NetLog::TYPE_SOCKET_BYTES_RECEIVED,
1302 NetLog::PHASE_NONE));
1303 EXPECT_TRUE(LogContainsEndEvent(entry_list, 9, NetLog::TYPE_SOCKET_ALIVE));
1305 // Let the RST_STREAM write while |rst| is in-scope.
1306 base::MessageLoop::current()->RunUntilIdle();
1309 // CompletionCallback that causes the SpdyProxyClientSocket to be
1310 // deleted when Run is invoked.
1311 class DeleteSockCallback : public TestCompletionCallbackBase {
1312 public:
1313 explicit DeleteSockCallback(scoped_ptr<SpdyProxyClientSocket>* sock)
1314 : sock_(sock),
1315 callback_(base::Bind(&DeleteSockCallback::OnComplete,
1316 base::Unretained(this))) {
1319 ~DeleteSockCallback() override {}
1321 const CompletionCallback& callback() const { return callback_; }
1323 private:
1324 void OnComplete(int result) {
1325 sock_->reset(NULL);
1326 SetResult(result);
1329 scoped_ptr<SpdyProxyClientSocket>* sock_;
1330 CompletionCallback callback_;
1332 DISALLOW_COPY_AND_ASSIGN(DeleteSockCallback);
1335 // If the socket is Reset when both a read and write are pending, and the
1336 // read callback causes the socket to be deleted, the write callback should
1337 // not be called.
1338 TEST_P(SpdyProxyClientSocketTest, RstWithReadAndWritePendingDelete) {
1339 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1340 MockWrite writes[] = {
1341 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1342 MockWrite(ASYNC, ERR_ABORTED, 3),
1345 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1346 scoped_ptr<SpdyFrame> rst(
1347 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
1348 MockRead reads[] = {
1349 CreateMockRead(*resp, 1, ASYNC),
1350 CreateMockRead(*rst, 2, ASYNC),
1351 MockRead(ASYNC, 0, 4), // EOF
1354 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1356 AssertConnectSucceeds();
1358 EXPECT_TRUE(sock_->IsConnected());
1360 DeleteSockCallback read_callback(&sock_);
1362 scoped_refptr<IOBuffer> read_buf(new IOBuffer(kLen1));
1363 ASSERT_EQ(ERR_IO_PENDING,
1364 sock_->Read(read_buf.get(), kLen1, read_callback.callback()));
1366 scoped_refptr<IOBufferWithSize> write_buf(CreateBuffer(kMsg1, kLen1));
1367 EXPECT_EQ(
1368 ERR_IO_PENDING,
1369 sock_->Write(
1370 write_buf.get(), write_buf->size(), write_callback_.callback()));
1372 Run(1);
1374 EXPECT_FALSE(sock_.get());
1375 EXPECT_TRUE(read_callback.have_result());
1376 EXPECT_FALSE(write_callback_.have_result());
1378 // Let the RST_STREAM write while |rst| is in-scope.
1379 base::MessageLoop::current()->RunUntilIdle();
1382 } // namespace net