Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / net / spdy / spdy_proxy_client_socket_unittest.cc
blob9d3e03e412745b94bf8e368aad87a0c8a20c76bc
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));
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 if (spdy_util_.spdy_version() == HTTP2) {
315 (*block)[spdy_util_.GetHostKey()] = kOriginHostPort;
316 } else {
317 (*block)[spdy_util_.GetPathKey()] = kOriginHostPort;
318 (*block)[spdy_util_.GetHostKey()] = kOriginHost;
320 (*block)["user-agent"] = kUserAgent;
321 spdy_util_.MaybeAddVersionHeader(block);
324 void SpdyProxyClientSocketTest::PopulateConnectReplyIR(SpdyHeaderBlock* block,
325 const char* status) {
326 (*block)[spdy_util_.GetStatusKey()] = status;
327 spdy_util_.MaybeAddVersionHeader(block);
330 // Constructs a standard SPDY SYN_STREAM frame for a CONNECT request.
331 SpdyFrame*
332 SpdyProxyClientSocketTest::ConstructConnectRequestFrame() {
333 SpdyHeaderBlock block;
334 PopulateConnectRequestIR(&block);
335 return spdy_util_.ConstructSpdySyn(kStreamId, block, LOWEST, false, false);
338 // Constructs a SPDY SYN_STREAM frame for a CONNECT request which includes
339 // Proxy-Authorization headers.
340 SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectAuthRequestFrame() {
341 SpdyHeaderBlock block;
342 PopulateConnectRequestIR(&block);
343 block["proxy-authorization"] = "Basic Zm9vOmJhcg==";
344 return spdy_util_.ConstructSpdySyn(kStreamId, block, LOWEST, false, false);
347 // Constructs a standard SPDY SYN_REPLY frame to match the SPDY CONNECT.
348 SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectReplyFrame() {
349 SpdyHeaderBlock block;
350 PopulateConnectReplyIR(&block, "200");
351 SpdySynReplyIR reply_ir(kStreamId);
352 return spdy_util_.ConstructSpdyReply(kStreamId, block);
355 // Constructs a standard SPDY SYN_REPLY frame to match the SPDY CONNECT,
356 // including Proxy-Authenticate headers.
357 SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectAuthReplyFrame() {
358 SpdyHeaderBlock block;
359 PopulateConnectReplyIR(&block, "407");
360 block["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
361 return spdy_util_.ConstructSpdyReply(kStreamId, block);
364 // Constructs a SPDY SYN_REPLY frame with an HTTP 302 redirect.
365 SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectRedirectReplyFrame() {
366 SpdyHeaderBlock block;
367 PopulateConnectReplyIR(&block, "302");
368 block["location"] = kRedirectUrl;
369 block["set-cookie"] = "foo=bar";
370 return spdy_util_.ConstructSpdyReply(kStreamId, block);
373 // Constructs a SPDY SYN_REPLY frame with an HTTP 500 error.
374 SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectErrorReplyFrame() {
375 SpdyHeaderBlock block;
376 PopulateConnectReplyIR(&block, "500");
377 return spdy_util_.ConstructSpdyReply(kStreamId, block);
380 SpdyFrame* SpdyProxyClientSocketTest::ConstructBodyFrame(
381 const char* data,
382 int length) {
383 return framer_.CreateDataFrame(kStreamId, data, length, DATA_FLAG_NONE);
386 // ----------- Connect
388 TEST_P(SpdyProxyClientSocketTest, ConnectSendsCorrectRequest) {
389 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
390 MockWrite writes[] = {
391 CreateMockWrite(*conn, 0, SYNCHRONOUS),
394 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
395 MockRead reads[] = {
396 CreateMockRead(*resp, 1, ASYNC),
397 MockRead(ASYNC, 0, 2), // EOF
400 Initialize(reads, arraysize(reads), writes, arraysize(writes));
402 ASSERT_FALSE(sock_->IsConnected());
404 AssertConnectSucceeds();
406 AssertConnectionEstablished();
409 TEST_P(SpdyProxyClientSocketTest, ConnectWithAuthRequested) {
410 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
411 MockWrite writes[] = {
412 CreateMockWrite(*conn, 0, SYNCHRONOUS),
415 scoped_ptr<SpdyFrame> resp(ConstructConnectAuthReplyFrame());
416 MockRead reads[] = {
417 CreateMockRead(*resp, 1, ASYNC),
418 MockRead(ASYNC, 0, 2), // EOF
421 Initialize(reads, arraysize(reads), writes, arraysize(writes));
423 AssertConnectFails(ERR_PROXY_AUTH_REQUESTED);
425 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
426 ASSERT_TRUE(response != NULL);
427 ASSERT_EQ(407, response->headers->response_code());
430 TEST_P(SpdyProxyClientSocketTest, ConnectWithAuthCredentials) {
431 scoped_ptr<SpdyFrame> conn(ConstructConnectAuthRequestFrame());
432 MockWrite writes[] = {
433 CreateMockWrite(*conn, 0, SYNCHRONOUS),
436 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
437 MockRead reads[] = {
438 CreateMockRead(*resp, 1, ASYNC),
439 MockRead(ASYNC, 0, 2), // EOF
442 Initialize(reads, arraysize(reads), writes, arraysize(writes));
443 AddAuthToCache();
445 AssertConnectSucceeds();
447 AssertConnectionEstablished();
450 TEST_P(SpdyProxyClientSocketTest, ConnectRedirects) {
451 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
452 scoped_ptr<SpdyFrame> rst(
453 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
454 MockWrite writes[] = {
455 CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 2),
458 scoped_ptr<SpdyFrame> resp(ConstructConnectRedirectReplyFrame());
459 MockRead reads[] = {
460 CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3), // EOF
463 Initialize(reads, arraysize(reads), writes, arraysize(writes));
465 AssertConnectFails(ERR_HTTPS_PROXY_TUNNEL_RESPONSE);
467 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
468 ASSERT_TRUE(response != NULL);
470 const HttpResponseHeaders* headers = response->headers.get();
471 ASSERT_EQ(302, headers->response_code());
472 ASSERT_FALSE(headers->HasHeader("set-cookie"));
473 ASSERT_TRUE(headers->HasHeaderValue("content-length", "0"));
475 std::string location;
476 ASSERT_TRUE(headers->IsRedirect(&location));
477 ASSERT_EQ(location, kRedirectUrl);
479 // Let the RST_STREAM write while |rst| is in-scope.
480 base::MessageLoop::current()->RunUntilIdle();
483 TEST_P(SpdyProxyClientSocketTest, ConnectFails) {
484 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
485 MockWrite writes[] = {
486 CreateMockWrite(*conn, 0, SYNCHRONOUS),
489 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
490 MockRead reads[] = {
491 MockRead(ASYNC, 0, 1), // EOF
494 Initialize(reads, arraysize(reads), writes, arraysize(writes));
496 ASSERT_FALSE(sock_->IsConnected());
498 AssertConnectFails(ERR_CONNECTION_CLOSED);
500 ASSERT_FALSE(sock_->IsConnected());
503 // ----------- WasEverUsed
505 TEST_P(SpdyProxyClientSocketTest, WasEverUsedReturnsCorrectValues) {
506 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
507 scoped_ptr<SpdyFrame> rst(
508 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
509 MockWrite writes[] = {
510 CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 2),
513 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
514 MockRead reads[] = {
515 CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3), // EOF
518 Initialize(reads, arraysize(reads), writes, arraysize(writes));
520 EXPECT_FALSE(sock_->WasEverUsed());
521 AssertConnectSucceeds();
522 EXPECT_TRUE(sock_->WasEverUsed());
523 sock_->Disconnect();
524 EXPECT_TRUE(sock_->WasEverUsed());
526 // Let the RST_STREAM write while |rst| is in-scope.
527 base::MessageLoop::current()->RunUntilIdle();
530 // ----------- GetPeerAddress
532 TEST_P(SpdyProxyClientSocketTest, GetPeerAddressReturnsCorrectValues) {
533 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
534 MockWrite writes[] = {
535 CreateMockWrite(*conn, 0, SYNCHRONOUS),
538 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
539 MockRead reads[] = {
540 CreateMockRead(*resp, 1, ASYNC),
541 MockRead(ASYNC, 0, 2), // EOF
544 Initialize(reads, arraysize(reads), writes, arraysize(writes));
546 IPEndPoint addr;
547 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr));
549 AssertConnectSucceeds();
550 EXPECT_TRUE(sock_->IsConnected());
551 EXPECT_EQ(OK, sock_->GetPeerAddress(&addr));
553 Run(1);
555 EXPECT_FALSE(sock_->IsConnected());
556 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr));
558 sock_->Disconnect();
560 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr));
563 // ----------- Write
565 TEST_P(SpdyProxyClientSocketTest, WriteSendsDataInDataFrame) {
566 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
567 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
568 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
569 MockWrite writes[] = {
570 CreateMockWrite(*conn, 0, SYNCHRONOUS),
571 CreateMockWrite(*msg1, 2, SYNCHRONOUS),
572 CreateMockWrite(*msg2, 3, SYNCHRONOUS),
575 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
576 MockRead reads[] = {
577 CreateMockRead(*resp, 1, ASYNC),
578 MockRead(ASYNC, 0, 4), // EOF
581 Initialize(reads, arraysize(reads), writes, arraysize(writes));
583 AssertConnectSucceeds();
585 AssertAsyncWriteSucceeds(kMsg1, kLen1);
586 AssertAsyncWriteSucceeds(kMsg2, kLen2);
589 TEST_P(SpdyProxyClientSocketTest, WriteSplitsLargeDataIntoMultipleFrames) {
590 std::string chunk_data(kMaxSpdyFrameChunkSize, 'x');
591 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
592 scoped_ptr<SpdyFrame> chunk(ConstructBodyFrame(chunk_data.data(),
593 chunk_data.length()));
594 MockWrite writes[] = {
595 CreateMockWrite(*conn, 0, SYNCHRONOUS),
596 CreateMockWrite(*chunk, 2, SYNCHRONOUS),
597 CreateMockWrite(*chunk, 3, SYNCHRONOUS),
598 CreateMockWrite(*chunk, 4, SYNCHRONOUS)
601 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
602 MockRead reads[] = {
603 CreateMockRead(*resp, 1, ASYNC),
604 MockRead(ASYNC, 0, 5), // EOF
607 Initialize(reads, arraysize(reads), writes, arraysize(writes));
609 AssertConnectSucceeds();
611 std::string big_data(kMaxSpdyFrameChunkSize * 3, 'x');
612 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(big_data.data(),
613 big_data.length()));
615 EXPECT_EQ(ERR_IO_PENDING,
616 sock_->Write(buf.get(), buf->size(), write_callback_.callback()));
617 data_->RunFor(3);
619 EXPECT_EQ(buf->size(), write_callback_.WaitForResult());
622 // ----------- Read
624 TEST_P(SpdyProxyClientSocketTest, ReadReadsDataInDataFrame) {
625 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
626 MockWrite writes[] = {
627 CreateMockWrite(*conn, 0, SYNCHRONOUS),
630 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
631 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
632 MockRead reads[] = {
633 CreateMockRead(*resp, 1, ASYNC),
634 CreateMockRead(*msg1, 2, ASYNC),
635 MockRead(ASYNC, 0, 3), // EOF
638 Initialize(reads, arraysize(reads), writes, arraysize(writes));
640 AssertConnectSucceeds();
642 Run(1); // SpdySession consumes the next read and sends it to
643 // sock_ to be buffered.
644 AssertSyncReadEquals(kMsg1, kLen1);
647 TEST_P(SpdyProxyClientSocketTest, ReadDataFromBufferedFrames) {
648 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
649 MockWrite writes[] = {
650 CreateMockWrite(*conn, 0, SYNCHRONOUS),
653 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
654 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
655 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
656 MockRead reads[] = {
657 CreateMockRead(*resp, 1, ASYNC),
658 CreateMockRead(*msg1, 2, ASYNC),
659 CreateMockRead(*msg2, 3, ASYNC),
660 MockRead(ASYNC, 0, 4), // EOF
663 Initialize(reads, arraysize(reads), writes, arraysize(writes));
665 AssertConnectSucceeds();
667 Run(1); // SpdySession consumes the next read and sends it to
668 // sock_ to be buffered.
669 AssertSyncReadEquals(kMsg1, kLen1);
670 Run(1); // SpdySession consumes the next read and sends it to
671 // sock_ to be buffered.
672 AssertSyncReadEquals(kMsg2, kLen2);
675 TEST_P(SpdyProxyClientSocketTest, ReadDataMultipleBufferedFrames) {
676 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
677 MockWrite writes[] = {
678 CreateMockWrite(*conn, 0, SYNCHRONOUS),
681 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
682 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
683 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
684 MockRead reads[] = {
685 CreateMockRead(*resp, 1, ASYNC),
686 CreateMockRead(*msg1, 2, ASYNC),
687 CreateMockRead(*msg2, 3, ASYNC),
688 MockRead(ASYNC, 0, 4), // EOF
691 Initialize(reads, arraysize(reads), writes, arraysize(writes));
693 AssertConnectSucceeds();
695 Run(2); // SpdySession consumes the next two reads and sends then to
696 // sock_ to be buffered.
697 AssertSyncReadEquals(kMsg1, kLen1);
698 AssertSyncReadEquals(kMsg2, kLen2);
701 TEST_P(SpdyProxyClientSocketTest,
702 LargeReadWillMergeDataFromDifferentFrames) {
703 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
704 MockWrite writes[] = {
705 CreateMockWrite(*conn, 0, SYNCHRONOUS),
708 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
709 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
710 scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
711 MockRead reads[] = {
712 CreateMockRead(*resp, 1, ASYNC),
713 CreateMockRead(*msg3, 2, ASYNC),
714 CreateMockRead(*msg3, 3, ASYNC),
715 MockRead(ASYNC, 0, 4), // EOF
718 Initialize(reads, arraysize(reads), writes, arraysize(writes));
720 AssertConnectSucceeds();
722 Run(2); // SpdySession consumes the next two reads and sends then to
723 // sock_ to be buffered.
724 // The payload from two data frames, each with kMsg3 will be combined
725 // together into a single read().
726 AssertSyncReadEquals(kMsg33, kLen33);
729 TEST_P(SpdyProxyClientSocketTest, MultipleShortReadsThenMoreRead) {
730 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
731 MockWrite writes[] = {
732 CreateMockWrite(*conn, 0, SYNCHRONOUS),
735 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
736 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
737 scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
738 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
739 MockRead reads[] = {
740 CreateMockRead(*resp, 1, ASYNC),
741 CreateMockRead(*msg1, 2, ASYNC),
742 CreateMockRead(*msg3, 3, ASYNC),
743 CreateMockRead(*msg3, 4, ASYNC),
744 CreateMockRead(*msg2, 5, ASYNC),
745 MockRead(ASYNC, 0, 6), // EOF
748 Initialize(reads, arraysize(reads), writes, arraysize(writes));
750 AssertConnectSucceeds();
752 Run(4); // SpdySession consumes the next four reads and sends then to
753 // sock_ to be buffered.
754 AssertSyncReadEquals(kMsg1, kLen1);
755 // The payload from two data frames, each with kMsg3 will be combined
756 // together into a single read().
757 AssertSyncReadEquals(kMsg33, kLen33);
758 AssertSyncReadEquals(kMsg2, kLen2);
761 TEST_P(SpdyProxyClientSocketTest, ReadWillSplitDataFromLargeFrame) {
762 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
763 MockWrite writes[] = {
764 CreateMockWrite(*conn, 0, SYNCHRONOUS),
767 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
768 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
769 scoped_ptr<SpdyFrame> msg33(ConstructBodyFrame(kMsg33, kLen33));
770 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
771 MockRead reads[] = {
772 CreateMockRead(*resp, 1, ASYNC),
773 CreateMockRead(*msg1, 2, ASYNC),
774 CreateMockRead(*msg33, 3, ASYNC),
775 MockRead(ASYNC, 0, 4), // EOF
778 Initialize(reads, arraysize(reads), writes, arraysize(writes));
780 AssertConnectSucceeds();
782 Run(2); // SpdySession consumes the next two reads and sends then to
783 // sock_ to be buffered.
784 AssertSyncReadEquals(kMsg1, kLen1);
785 // The payload from the single large data frame will be read across
786 // two different reads.
787 AssertSyncReadEquals(kMsg3, kLen3);
788 AssertSyncReadEquals(kMsg3, kLen3);
791 TEST_P(SpdyProxyClientSocketTest, MultipleReadsFromSameLargeFrame) {
792 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
793 MockWrite writes[] = {
794 CreateMockWrite(*conn, 0, SYNCHRONOUS),
797 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
798 scoped_ptr<SpdyFrame> msg333(ConstructBodyFrame(kMsg333, kLen333));
799 MockRead reads[] = {
800 CreateMockRead(*resp, 1, ASYNC),
801 CreateMockRead(*msg333, 2, ASYNC),
802 MockRead(ASYNC, 0, 3), // EOF
805 Initialize(reads, arraysize(reads), writes, arraysize(writes));
807 AssertConnectSucceeds();
809 Run(1); // SpdySession consumes the next read and sends it to
810 // sock_ to be buffered.
811 // The payload from the single large data frame will be read across
812 // two different reads.
813 AssertSyncReadEquals(kMsg33, kLen33);
815 // Now attempt to do a read of more data than remains buffered
816 scoped_refptr<IOBuffer> buf(new IOBuffer(kLen33));
817 ASSERT_EQ(kLen3, sock_->Read(buf.get(), kLen33, read_callback_.callback()));
818 ASSERT_EQ(std::string(kMsg3, kLen3), std::string(buf->data(), kLen3));
819 ASSERT_TRUE(sock_->IsConnected());
822 TEST_P(SpdyProxyClientSocketTest, ReadAuthResponseBody) {
823 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
824 MockWrite writes[] = {
825 CreateMockWrite(*conn, 0, SYNCHRONOUS),
828 scoped_ptr<SpdyFrame> resp(ConstructConnectAuthReplyFrame());
829 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
830 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
831 MockRead reads[] = {
832 CreateMockRead(*resp, 1, ASYNC),
833 CreateMockRead(*msg1, 2, ASYNC),
834 CreateMockRead(*msg2, 3, ASYNC),
835 MockRead(ASYNC, 0, 4), // EOF
838 Initialize(reads, arraysize(reads), writes, arraysize(writes));
840 AssertConnectFails(ERR_PROXY_AUTH_REQUESTED);
842 Run(2); // SpdySession consumes the next two reads and sends then to
843 // sock_ to be buffered.
844 AssertSyncReadEquals(kMsg1, kLen1);
845 AssertSyncReadEquals(kMsg2, kLen2);
848 TEST_P(SpdyProxyClientSocketTest, ReadErrorResponseBody) {
849 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
850 MockWrite writes[] = {
851 CreateMockWrite(*conn, 0, SYNCHRONOUS),
854 scoped_ptr<SpdyFrame> resp(ConstructConnectErrorReplyFrame());
855 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
856 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
857 MockRead reads[] = {
858 CreateMockRead(*resp, 1, ASYNC),
859 CreateMockRead(*msg1, 2, ASYNC),
860 CreateMockRead(*msg2, 3, ASYNC),
861 MockRead(ASYNC, 0, 4), // EOF
864 Initialize(reads, arraysize(reads), writes, arraysize(writes));
866 AssertConnectFails(ERR_TUNNEL_CONNECTION_FAILED);
869 // ----------- Reads and Writes
871 TEST_P(SpdyProxyClientSocketTest, AsyncReadAroundWrite) {
872 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
873 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
874 MockWrite writes[] = {
875 CreateMockWrite(*conn, 0, SYNCHRONOUS),
876 CreateMockWrite(*msg2, 3, SYNCHRONOUS),
879 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
880 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
881 scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
882 MockRead reads[] = {
883 CreateMockRead(*resp, 1, ASYNC),
884 CreateMockRead(*msg1, 2, ASYNC), // sync read
885 CreateMockRead(*msg3, 4, ASYNC), // async read
886 MockRead(ASYNC, 0, 5), // EOF
889 Initialize(reads, arraysize(reads), writes, arraysize(writes));
891 AssertConnectSucceeds();
893 Run(1);
894 AssertSyncReadEquals(kMsg1, kLen1);
896 AssertReadStarts(kMsg3, kLen3);
897 // Read should block until after the write succeeds
899 AssertAsyncWriteSucceeds(kMsg2, kLen2); // Runs 1 step
901 ASSERT_FALSE(read_callback_.have_result());
902 Run(1);
903 // Now the read will return
904 AssertReadReturns(kMsg3, kLen3);
907 TEST_P(SpdyProxyClientSocketTest, AsyncWriteAroundReads) {
908 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
909 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
910 MockWrite writes[] = {
911 CreateMockWrite(*conn, 0, SYNCHRONOUS),
912 CreateMockWrite(*msg2, 4, ASYNC),
915 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
916 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
917 scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
918 MockRead reads[] = {
919 CreateMockRead(*resp, 1, ASYNC),
920 CreateMockRead(*msg1, 2, ASYNC),
921 CreateMockRead(*msg3, 3, ASYNC),
922 MockRead(ASYNC, 0, 5), // EOF
925 Initialize(reads, arraysize(reads), writes, arraysize(writes));
927 AssertConnectSucceeds();
929 Run(1);
930 AssertSyncReadEquals(kMsg1, kLen1);
931 // Write should block until the read completes
932 AssertWriteReturns(kMsg2, kLen2, ERR_IO_PENDING);
934 AssertAsyncReadEquals(kMsg3, kLen3);
936 ASSERT_FALSE(write_callback_.have_result());
938 // Now the write will complete
939 Run(1);
940 AssertWriteLength(kLen2);
943 // ----------- Reading/Writing on Closed socket
945 // Reading from an already closed socket should return 0
946 TEST_P(SpdyProxyClientSocketTest, ReadOnClosedSocketReturnsZero) {
947 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
948 MockWrite writes[] = {
949 CreateMockWrite(*conn, 0, SYNCHRONOUS),
952 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
953 MockRead reads[] = {
954 CreateMockRead(*resp, 1, ASYNC),
955 MockRead(ASYNC, 0, 2), // EOF
958 Initialize(reads, arraysize(reads), writes, arraysize(writes));
960 AssertConnectSucceeds();
962 Run(1);
964 ASSERT_FALSE(sock_->IsConnected());
965 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
966 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
967 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
968 ASSERT_FALSE(sock_->IsConnectedAndIdle());
971 // Read pending when socket is closed should return 0
972 TEST_P(SpdyProxyClientSocketTest, PendingReadOnCloseReturnsZero) {
973 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
974 MockWrite writes[] = {
975 CreateMockWrite(*conn, 0, SYNCHRONOUS),
978 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
979 MockRead reads[] = {
980 CreateMockRead(*resp, 1, ASYNC),
981 MockRead(ASYNC, 0, 2), // EOF
984 Initialize(reads, arraysize(reads), writes, arraysize(writes));
986 AssertConnectSucceeds();
988 AssertReadStarts(kMsg1, kLen1);
990 Run(1);
992 ASSERT_EQ(0, read_callback_.WaitForResult());
995 // Reading from a disconnected socket is an error
996 TEST_P(SpdyProxyClientSocketTest,
997 ReadOnDisconnectSocketReturnsNotConnected) {
998 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
999 scoped_ptr<SpdyFrame> rst(
1000 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
1001 MockWrite writes[] = {
1002 CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 2),
1005 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1006 MockRead reads[] = {
1007 CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3), // EOF
1010 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1012 AssertConnectSucceeds();
1014 sock_->Disconnect();
1016 ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED,
1017 sock_->Read(NULL, 1, CompletionCallback()));
1019 // Let the RST_STREAM write while |rst| is in-scope.
1020 base::MessageLoop::current()->RunUntilIdle();
1023 // Reading buffered data from an already closed socket should return
1024 // buffered data, then 0.
1025 TEST_P(SpdyProxyClientSocketTest, ReadOnClosedSocketReturnsBufferedData) {
1026 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1027 MockWrite writes[] = {
1028 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1031 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1032 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
1033 MockRead reads[] = {
1034 CreateMockRead(*resp, 1, ASYNC),
1035 CreateMockRead(*msg1, 2, ASYNC),
1036 MockRead(ASYNC, 0, 3), // EOF
1039 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1041 AssertConnectSucceeds();
1043 Run(2);
1045 ASSERT_FALSE(sock_->IsConnected());
1046 scoped_refptr<IOBuffer> buf(new IOBuffer(kLen1));
1047 ASSERT_EQ(kLen1, sock_->Read(buf.get(), kLen1, CompletionCallback()));
1048 ASSERT_EQ(std::string(kMsg1, kLen1), std::string(buf->data(), kLen1));
1050 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
1051 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
1052 sock_->Disconnect();
1053 ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED,
1054 sock_->Read(NULL, 1, CompletionCallback()));
1057 // Calling Write() on a closed socket is an error
1058 TEST_P(SpdyProxyClientSocketTest, WriteOnClosedStream) {
1059 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1060 MockWrite writes[] = {
1061 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1064 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1065 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
1066 MockRead reads[] = {
1067 CreateMockRead(*resp, 1, ASYNC),
1068 MockRead(ASYNC, 0, 2), // EOF
1071 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1073 AssertConnectSucceeds();
1075 Run(1); // Read EOF which will close the stream
1076 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
1077 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED,
1078 sock_->Write(buf.get(), buf->size(), CompletionCallback()));
1081 // Calling Write() on a disconnected socket is an error
1082 TEST_P(SpdyProxyClientSocketTest, WriteOnDisconnectedSocket) {
1083 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1084 scoped_ptr<SpdyFrame> rst(
1085 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
1086 MockWrite writes[] = {
1087 CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 2),
1090 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1091 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
1092 MockRead reads[] = {
1093 CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3), // EOF
1096 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1098 AssertConnectSucceeds();
1100 sock_->Disconnect();
1102 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
1103 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED,
1104 sock_->Write(buf.get(), buf->size(), CompletionCallback()));
1106 // Let the RST_STREAM write while |rst| is in-scope.
1107 base::MessageLoop::current()->RunUntilIdle();
1110 // If the socket is closed with a pending Write(), the callback
1111 // should be called with ERR_CONNECTION_CLOSED.
1112 TEST_P(SpdyProxyClientSocketTest, WritePendingOnClose) {
1113 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1114 MockWrite writes[] = {
1115 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1116 MockWrite(ASYNC, ERR_ABORTED, 2),
1119 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1120 MockRead reads[] = {
1121 CreateMockRead(*resp, 1, ASYNC),
1122 MockRead(ASYNC, 0, 3), // EOF
1125 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1127 AssertConnectSucceeds();
1129 EXPECT_TRUE(sock_->IsConnected());
1131 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
1132 EXPECT_EQ(ERR_IO_PENDING,
1133 sock_->Write(buf.get(), buf->size(), write_callback_.callback()));
1135 CloseSpdySession(ERR_ABORTED, std::string());
1137 EXPECT_EQ(ERR_CONNECTION_CLOSED, write_callback_.WaitForResult());
1140 // If the socket is Disconnected with a pending Write(), the callback
1141 // should not be called.
1142 TEST_P(SpdyProxyClientSocketTest, DisconnectWithWritePending) {
1143 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1144 scoped_ptr<SpdyFrame> rst(
1145 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
1146 MockWrite writes[] = {
1147 CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 2),
1148 MockWrite(SYNCHRONOUS, 0, 3), // EOF
1151 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1152 MockRead reads[] = {
1153 CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 4), // EOF
1156 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1158 AssertConnectSucceeds();
1160 EXPECT_TRUE(sock_->IsConnected());
1162 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
1163 EXPECT_EQ(ERR_IO_PENDING,
1164 sock_->Write(buf.get(), buf->size(), write_callback_.callback()));
1166 sock_->Disconnect();
1168 EXPECT_FALSE(sock_->IsConnected());
1169 EXPECT_FALSE(write_callback_.have_result());
1171 // Let the RST_STREAM write while |rst| is in-scope.
1172 base::MessageLoop::current()->RunUntilIdle();
1175 // If the socket is Disconnected with a pending Read(), the callback
1176 // should not be called.
1177 TEST_P(SpdyProxyClientSocketTest, DisconnectWithReadPending) {
1178 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1179 scoped_ptr<SpdyFrame> rst(
1180 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
1181 MockWrite writes[] = {
1182 CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 2),
1185 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1186 MockRead reads[] = {
1187 CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3), // EOF
1190 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1192 AssertConnectSucceeds();
1194 EXPECT_TRUE(sock_->IsConnected());
1196 scoped_refptr<IOBuffer> buf(new IOBuffer(kLen1));
1197 ASSERT_EQ(ERR_IO_PENDING,
1198 sock_->Read(buf.get(), kLen1, read_callback_.callback()));
1200 sock_->Disconnect();
1202 EXPECT_FALSE(sock_->IsConnected());
1203 EXPECT_FALSE(read_callback_.have_result());
1205 // Let the RST_STREAM write while |rst| is in-scope.
1206 base::MessageLoop::current()->RunUntilIdle();
1209 // If the socket is Reset when both a read and write are pending,
1210 // both should be called back.
1211 TEST_P(SpdyProxyClientSocketTest, RstWithReadAndWritePending) {
1212 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1213 MockWrite writes[] = {
1214 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1215 MockWrite(ASYNC, ERR_ABORTED, 3),
1218 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1219 scoped_ptr<SpdyFrame> rst(
1220 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
1221 MockRead reads[] = {
1222 CreateMockRead(*resp, 1, ASYNC),
1223 CreateMockRead(*rst, 2, ASYNC),
1224 MockRead(ASYNC, 0, 4) // EOF
1227 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1229 AssertConnectSucceeds();
1231 EXPECT_TRUE(sock_->IsConnected());
1233 scoped_refptr<IOBuffer> read_buf(new IOBuffer(kLen1));
1234 ASSERT_EQ(ERR_IO_PENDING,
1235 sock_->Read(read_buf.get(), kLen1, read_callback_.callback()));
1237 scoped_refptr<IOBufferWithSize> write_buf(CreateBuffer(kMsg1, kLen1));
1238 EXPECT_EQ(
1239 ERR_IO_PENDING,
1240 sock_->Write(
1241 write_buf.get(), write_buf->size(), write_callback_.callback()));
1243 Run(2);
1245 EXPECT_TRUE(sock_.get());
1246 EXPECT_TRUE(read_callback_.have_result());
1247 EXPECT_TRUE(write_callback_.have_result());
1249 // Let the RST_STREAM write while |rst| is in-scope.
1250 base::MessageLoop::current()->RunUntilIdle();
1253 // Makes sure the proxy client socket's source gets the expected NetLog events
1254 // and only the expected NetLog events (No SpdySession events).
1255 TEST_P(SpdyProxyClientSocketTest, NetLog) {
1256 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1257 scoped_ptr<SpdyFrame> rst(
1258 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
1259 MockWrite writes[] = {
1260 CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 3),
1263 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1264 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
1265 MockRead reads[] = {
1266 CreateMockRead(*resp, 1, ASYNC), CreateMockRead(*msg1, 2, ASYNC),
1267 MockRead(ASYNC, 0, 4), // EOF
1270 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1272 AssertConnectSucceeds();
1274 Run(1); // SpdySession consumes the next read and sends it to
1275 // sock_ to be buffered.
1276 AssertSyncReadEquals(kMsg1, kLen1);
1278 NetLog::Source sock_source = sock_->NetLog().source();
1279 sock_.reset();
1281 TestNetLogEntry::List entry_list;
1282 net_log_.GetEntriesForSource(sock_source, &entry_list);
1284 ASSERT_EQ(entry_list.size(), 10u);
1285 EXPECT_TRUE(LogContainsBeginEvent(entry_list, 0, NetLog::TYPE_SOCKET_ALIVE));
1286 EXPECT_TRUE(LogContainsEvent(entry_list, 1,
1287 NetLog::TYPE_HTTP2_PROXY_CLIENT_SESSION,
1288 NetLog::PHASE_NONE));
1289 EXPECT_TRUE(LogContainsBeginEvent(entry_list, 2,
1290 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_SEND_REQUEST));
1291 EXPECT_TRUE(LogContainsEvent(entry_list, 3,
1292 NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
1293 NetLog::PHASE_NONE));
1294 EXPECT_TRUE(LogContainsEndEvent(entry_list, 4,
1295 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_SEND_REQUEST));
1296 EXPECT_TRUE(LogContainsBeginEvent(entry_list, 5,
1297 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_READ_HEADERS));
1298 EXPECT_TRUE(LogContainsEvent(entry_list, 6,
1299 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
1300 NetLog::PHASE_NONE));
1301 EXPECT_TRUE(LogContainsEndEvent(entry_list, 7,
1302 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_READ_HEADERS));
1303 EXPECT_TRUE(LogContainsEvent(entry_list, 8,
1304 NetLog::TYPE_SOCKET_BYTES_RECEIVED,
1305 NetLog::PHASE_NONE));
1306 EXPECT_TRUE(LogContainsEndEvent(entry_list, 9, NetLog::TYPE_SOCKET_ALIVE));
1308 // Let the RST_STREAM write while |rst| is in-scope.
1309 base::MessageLoop::current()->RunUntilIdle();
1312 // CompletionCallback that causes the SpdyProxyClientSocket to be
1313 // deleted when Run is invoked.
1314 class DeleteSockCallback : public TestCompletionCallbackBase {
1315 public:
1316 explicit DeleteSockCallback(scoped_ptr<SpdyProxyClientSocket>* sock)
1317 : sock_(sock),
1318 callback_(base::Bind(&DeleteSockCallback::OnComplete,
1319 base::Unretained(this))) {
1322 ~DeleteSockCallback() override {}
1324 const CompletionCallback& callback() const { return callback_; }
1326 private:
1327 void OnComplete(int result) {
1328 sock_->reset(NULL);
1329 SetResult(result);
1332 scoped_ptr<SpdyProxyClientSocket>* sock_;
1333 CompletionCallback callback_;
1335 DISALLOW_COPY_AND_ASSIGN(DeleteSockCallback);
1338 // If the socket is Reset when both a read and write are pending, and the
1339 // read callback causes the socket to be deleted, the write callback should
1340 // not be called.
1341 TEST_P(SpdyProxyClientSocketTest, RstWithReadAndWritePendingDelete) {
1342 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1343 MockWrite writes[] = {
1344 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1345 MockWrite(ASYNC, ERR_ABORTED, 3),
1348 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1349 scoped_ptr<SpdyFrame> rst(
1350 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
1351 MockRead reads[] = {
1352 CreateMockRead(*resp, 1, ASYNC),
1353 CreateMockRead(*rst, 2, ASYNC),
1354 MockRead(ASYNC, 0, 4), // EOF
1357 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1359 AssertConnectSucceeds();
1361 EXPECT_TRUE(sock_->IsConnected());
1363 DeleteSockCallback read_callback(&sock_);
1365 scoped_refptr<IOBuffer> read_buf(new IOBuffer(kLen1));
1366 ASSERT_EQ(ERR_IO_PENDING,
1367 sock_->Read(read_buf.get(), kLen1, read_callback.callback()));
1369 scoped_refptr<IOBufferWithSize> write_buf(CreateBuffer(kMsg1, kLen1));
1370 EXPECT_EQ(
1371 ERR_IO_PENDING,
1372 sock_->Write(
1373 write_buf.get(), write_buf->size(), write_callback_.callback()));
1375 Run(1);
1377 EXPECT_FALSE(sock_.get());
1378 EXPECT_TRUE(read_callback.have_result());
1379 EXPECT_FALSE(write_callback_.have_result());
1381 // Let the RST_STREAM write while |rst| is in-scope.
1382 base::MessageLoop::current()->RunUntilIdle();
1385 } // namespace net