Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / net / spdy / spdy_proxy_client_socket_unittest.cc
blob13e6624d29e0bae5eaa585ea2ab4d0c8ec3ca636
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/capturing_net_log.h"
12 #include "net/base/net_log.h"
13 #include "net/base/net_log_unittest.h"
14 #include "net/base/test_completion_callback.h"
15 #include "net/base/winsock_init.h"
16 #include "net/dns/mock_host_resolver.h"
17 #include "net/http/http_response_headers.h"
18 #include "net/http/http_response_info.h"
19 #include "net/socket/client_socket_factory.h"
20 #include "net/socket/next_proto.h"
21 #include "net/socket/socket_test_util.h"
22 #include "net/socket/tcp_client_socket.h"
23 #include "net/spdy/buffered_spdy_framer.h"
24 #include "net/spdy/spdy_http_utils.h"
25 #include "net/spdy/spdy_protocol.h"
26 #include "net/spdy/spdy_session_pool.h"
27 #include "net/spdy/spdy_test_util_common.h"
28 #include "testing/gtest/include/gtest/gtest.h"
29 #include "testing/platform_test.h"
31 //-----------------------------------------------------------------------------
33 namespace {
35 static const char kRequestUrl[] = "https://www.google.com/";
36 static const char kOriginHost[] = "www.google.com";
37 static const int kOriginPort = 443;
38 static const char kOriginHostPort[] = "www.google.com:443";
39 static const char kProxyUrl[] = "https://myproxy:6121/";
40 static const char kProxyHost[] = "myproxy";
41 static const int kProxyPort = 6121;
42 static const char kUserAgent[] = "Mozilla/1.0";
44 static const int kStreamId = 1;
46 static const char kMsg1[] = "\0hello!\xff";
47 static const int kLen1 = 8;
48 static const char kMsg2[] = "\0a2345678\0";
49 static const int kLen2 = 10;
50 static const char kMsg3[] = "bye!";
51 static const int kLen3 = 4;
52 static const char kMsg33[] = "bye!bye!";
53 static const int kLen33 = kLen3 + kLen3;
54 static const char kMsg333[] = "bye!bye!bye!";
55 static const int kLen333 = kLen3 + kLen3 + kLen3;
57 static const char kRedirectUrl[] = "https://example.com/";
59 } // anonymous namespace
61 namespace net {
63 class SpdyProxyClientSocketTest
64 : public PlatformTest,
65 public testing::WithParamInterface<NextProto> {
66 public:
67 SpdyProxyClientSocketTest();
69 virtual void TearDown();
71 protected:
72 void Initialize(MockRead* reads, size_t reads_count, MockWrite* writes,
73 size_t writes_count);
74 void PopulateConnectRequestIR(SpdyHeaderBlock* syn_ir);
75 void PopulateConnectReplyIR(SpdyHeaderBlock* block, const char* status);
76 SpdyFrame* ConstructConnectRequestFrame();
77 SpdyFrame* ConstructConnectAuthRequestFrame();
78 SpdyFrame* ConstructConnectReplyFrame();
79 SpdyFrame* ConstructConnectAuthReplyFrame();
80 SpdyFrame* ConstructConnectRedirectReplyFrame();
81 SpdyFrame* ConstructConnectErrorReplyFrame();
82 SpdyFrame* ConstructBodyFrame(const char* data, int length);
83 scoped_refptr<IOBufferWithSize> CreateBuffer(const char* data, int size);
84 void AssertConnectSucceeds();
85 void AssertConnectFails(int result);
86 void AssertConnectionEstablished();
87 void AssertSyncReadEquals(const char* data, int len);
88 void AssertAsyncReadEquals(const char* data, int len);
89 void AssertReadStarts(const char* data, int len);
90 void AssertReadReturns(const char* data, int len);
91 void AssertAsyncWriteSucceeds(const char* data, int len);
92 void AssertWriteReturns(const char* data, int len, int rv);
93 void AssertWriteLength(int len);
94 void AssertAsyncWriteWithReadsSucceeds(const char* data, int len,
95 int num_reads);
97 void AddAuthToCache() {
98 const base::string16 kFoo(base::ASCIIToUTF16("foo"));
99 const base::string16 kBar(base::ASCIIToUTF16("bar"));
100 session_->http_auth_cache()->Add(GURL(kProxyUrl),
101 "MyRealm1",
102 HttpAuth::AUTH_SCHEME_BASIC,
103 "Basic realm=MyRealm1",
104 AuthCredentials(kFoo, kBar),
105 "/");
108 void Run(int steps) {
109 data_->StopAfter(steps);
110 data_->Run();
113 void CloseSpdySession(net::Error error, const std::string& description) {
114 spdy_session_->CloseSessionOnError(error, description);
117 SpdyTestUtil spdy_util_;
118 scoped_ptr<SpdyProxyClientSocket> sock_;
119 TestCompletionCallback read_callback_;
120 TestCompletionCallback write_callback_;
121 scoped_ptr<DeterministicSocketData> data_;
122 CapturingBoundNetLog net_log_;
124 private:
125 scoped_refptr<HttpNetworkSession> session_;
126 scoped_refptr<IOBuffer> read_buf_;
127 SpdySessionDependencies session_deps_;
128 MockConnect connect_data_;
129 base::WeakPtr<SpdySession> spdy_session_;
130 BufferedSpdyFramer framer_;
132 std::string user_agent_;
133 GURL url_;
134 HostPortPair proxy_host_port_;
135 HostPortPair endpoint_host_port_pair_;
136 ProxyServer proxy_;
137 SpdySessionKey endpoint_spdy_session_key_;
139 DISALLOW_COPY_AND_ASSIGN(SpdyProxyClientSocketTest);
142 INSTANTIATE_TEST_CASE_P(
143 NextProto,
144 SpdyProxyClientSocketTest,
145 testing::Values(kProtoDeprecatedSPDY2,
146 kProtoSPDY3, kProtoSPDY31, kProtoSPDY4));
148 SpdyProxyClientSocketTest::SpdyProxyClientSocketTest()
149 : spdy_util_(GetParam()),
150 session_(NULL),
151 read_buf_(NULL),
152 session_deps_(GetParam()),
153 connect_data_(SYNCHRONOUS, OK),
154 framer_(spdy_util_.spdy_version(), false),
155 user_agent_(kUserAgent),
156 url_(kRequestUrl),
157 proxy_host_port_(kProxyHost, kProxyPort),
158 endpoint_host_port_pair_(kOriginHost, kOriginPort),
159 proxy_(ProxyServer::SCHEME_HTTPS, proxy_host_port_),
160 endpoint_spdy_session_key_(endpoint_host_port_pair_,
161 proxy_,
162 PRIVACY_MODE_DISABLED) {
163 session_deps_.net_log = net_log_.bound().net_log();
166 void SpdyProxyClientSocketTest::TearDown() {
167 if (session_.get() != NULL)
168 session_->spdy_session_pool()->CloseAllSessions();
170 // Empty the current queue.
171 base::MessageLoop::current()->RunUntilIdle();
172 PlatformTest::TearDown();
175 void SpdyProxyClientSocketTest::Initialize(MockRead* reads,
176 size_t reads_count,
177 MockWrite* writes,
178 size_t writes_count) {
179 data_.reset(new DeterministicSocketData(reads, reads_count,
180 writes, writes_count));
181 data_->set_connect_data(connect_data_);
182 data_->SetStop(2);
184 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
185 data_.get());
186 session_deps_.host_resolver->set_synchronous_mode(true);
188 session_ = SpdySessionDependencies::SpdyCreateSessionDeterministic(
189 &session_deps_);
191 // Creates the SPDY session and stream.
192 spdy_session_ =
193 CreateInsecureSpdySession(
194 session_, endpoint_spdy_session_key_, BoundNetLog());
195 base::WeakPtr<SpdyStream> spdy_stream(
196 CreateStreamSynchronously(
197 SPDY_BIDIRECTIONAL_STREAM, spdy_session_, url_, LOWEST,
198 net_log_.bound()));
199 ASSERT_TRUE(spdy_stream.get() != NULL);
201 // Create the SpdyProxyClientSocket.
202 sock_.reset(
203 new SpdyProxyClientSocket(spdy_stream, user_agent_,
204 endpoint_host_port_pair_, url_,
205 proxy_host_port_, net_log_.bound(),
206 session_->http_auth_cache(),
207 session_->http_auth_handler_factory()));
210 scoped_refptr<IOBufferWithSize> SpdyProxyClientSocketTest::CreateBuffer(
211 const char* data, int size) {
212 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(size));
213 memcpy(buf->data(), data, size);
214 return buf;
217 void SpdyProxyClientSocketTest::AssertConnectSucceeds() {
218 ASSERT_EQ(ERR_IO_PENDING, sock_->Connect(read_callback_.callback()));
219 data_->Run();
220 ASSERT_EQ(OK, read_callback_.WaitForResult());
223 void SpdyProxyClientSocketTest::AssertConnectFails(int result) {
224 ASSERT_EQ(ERR_IO_PENDING, sock_->Connect(read_callback_.callback()));
225 data_->Run();
226 ASSERT_EQ(result, read_callback_.WaitForResult());
229 void SpdyProxyClientSocketTest::AssertConnectionEstablished() {
230 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
231 ASSERT_TRUE(response != NULL);
232 ASSERT_EQ(200, response->headers->response_code());
235 void SpdyProxyClientSocketTest::AssertSyncReadEquals(const char* data,
236 int len) {
237 scoped_refptr<IOBuffer> buf(new IOBuffer(len));
238 ASSERT_EQ(len, sock_->Read(buf.get(), len, CompletionCallback()));
239 ASSERT_EQ(std::string(data, len), std::string(buf->data(), len));
240 ASSERT_TRUE(sock_->IsConnected());
243 void SpdyProxyClientSocketTest::AssertAsyncReadEquals(const char* data,
244 int len) {
245 data_->StopAfter(1);
246 // Issue the read, which will be completed asynchronously
247 scoped_refptr<IOBuffer> buf(new IOBuffer(len));
248 ASSERT_EQ(ERR_IO_PENDING,
249 sock_->Read(buf.get(), len, read_callback_.callback()));
250 EXPECT_TRUE(sock_->IsConnected());
251 data_->Run();
253 EXPECT_TRUE(sock_->IsConnected());
255 // Now the read will return
256 EXPECT_EQ(len, read_callback_.WaitForResult());
257 ASSERT_EQ(std::string(data, len), std::string(buf->data(), len));
260 void SpdyProxyClientSocketTest::AssertReadStarts(const char* data,
261 int len) {
262 data_->StopAfter(1);
263 // Issue the read, which will be completed asynchronously
264 read_buf_ = new IOBuffer(len);
265 ASSERT_EQ(ERR_IO_PENDING,
266 sock_->Read(read_buf_.get(), len, read_callback_.callback()));
267 EXPECT_TRUE(sock_->IsConnected());
270 void SpdyProxyClientSocketTest::AssertReadReturns(const char* data,
271 int len) {
272 EXPECT_TRUE(sock_->IsConnected());
274 // Now the read will return
275 EXPECT_EQ(len, read_callback_.WaitForResult());
276 ASSERT_EQ(std::string(data, len), std::string(read_buf_->data(), len));
279 void SpdyProxyClientSocketTest::AssertAsyncWriteSucceeds(const char* data,
280 int len) {
281 AssertWriteReturns(data, len, ERR_IO_PENDING);
282 data_->RunFor(1);
283 AssertWriteLength(len);
286 void SpdyProxyClientSocketTest::AssertWriteReturns(const char* data,
287 int len,
288 int rv) {
289 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(data, len));
290 EXPECT_EQ(rv,
291 sock_->Write(buf.get(), buf->size(), write_callback_.callback()));
294 void SpdyProxyClientSocketTest::AssertWriteLength(int len) {
295 EXPECT_EQ(len, write_callback_.WaitForResult());
298 void SpdyProxyClientSocketTest::AssertAsyncWriteWithReadsSucceeds(
299 const char* data, int len, int num_reads) {
300 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(data, len));
302 EXPECT_EQ(ERR_IO_PENDING,
303 sock_->Write(buf.get(), buf->size(), write_callback_.callback()));
305 for (int i = 0; i < num_reads; i++) {
306 Run(1);
307 AssertSyncReadEquals(kMsg2, kLen2);
310 write_callback_.WaitForResult();
313 void SpdyProxyClientSocketTest::PopulateConnectRequestIR(
314 SpdyHeaderBlock* block) {
315 (*block)[spdy_util_.GetMethodKey()] = "CONNECT";
316 (*block)[spdy_util_.GetPathKey()] = kOriginHostPort;
317 (*block)[spdy_util_.GetHostKey()] = kOriginHost;
318 (*block)["user-agent"] = kUserAgent;
319 spdy_util_.MaybeAddVersionHeader(block);
322 void SpdyProxyClientSocketTest::PopulateConnectReplyIR(SpdyHeaderBlock* block,
323 const char* status) {
324 (*block)[spdy_util_.GetStatusKey()] = status;
325 spdy_util_.MaybeAddVersionHeader(block);
328 // Constructs a standard SPDY SYN_STREAM frame for a CONNECT request.
329 SpdyFrame*
330 SpdyProxyClientSocketTest::ConstructConnectRequestFrame() {
331 SpdyHeaderBlock block;
332 PopulateConnectRequestIR(&block);
333 return spdy_util_.ConstructSpdySyn(kStreamId, block, LOWEST, false, false);
336 // Constructs a SPDY SYN_STREAM frame for a CONNECT request which includes
337 // Proxy-Authorization headers.
338 SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectAuthRequestFrame() {
339 SpdyHeaderBlock block;
340 PopulateConnectRequestIR(&block);
341 block["proxy-authorization"] = "Basic Zm9vOmJhcg==";
342 return spdy_util_.ConstructSpdySyn(kStreamId, block, LOWEST, false, false);
345 // Constructs a standard SPDY SYN_REPLY frame to match the SPDY CONNECT.
346 SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectReplyFrame() {
347 SpdyHeaderBlock block;
348 PopulateConnectReplyIR(&block, "200");
349 SpdySynReplyIR reply_ir(kStreamId);
350 return spdy_util_.ConstructSpdyReply(kStreamId, block);
353 // Constructs a standard SPDY SYN_REPLY frame to match the SPDY CONNECT,
354 // including Proxy-Authenticate headers.
355 SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectAuthReplyFrame() {
356 SpdyHeaderBlock block;
357 PopulateConnectReplyIR(&block, "407");
358 block["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
359 return spdy_util_.ConstructSpdyReply(kStreamId, block);
362 // Constructs a SPDY SYN_REPLY frame with an HTTP 302 redirect.
363 SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectRedirectReplyFrame() {
364 SpdyHeaderBlock block;
365 PopulateConnectReplyIR(&block, "302");
366 block["location"] = kRedirectUrl;
367 block["set-cookie"] = "foo=bar";
368 return spdy_util_.ConstructSpdyReply(kStreamId, block);
371 // Constructs a SPDY SYN_REPLY frame with an HTTP 500 error.
372 SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectErrorReplyFrame() {
373 SpdyHeaderBlock block;
374 PopulateConnectReplyIR(&block, "500");
375 return spdy_util_.ConstructSpdyReply(kStreamId, block);
378 SpdyFrame* SpdyProxyClientSocketTest::ConstructBodyFrame(
379 const char* data,
380 int length) {
381 return framer_.CreateDataFrame(kStreamId, data, length, DATA_FLAG_NONE);
384 // ----------- Connect
386 TEST_P(SpdyProxyClientSocketTest, ConnectSendsCorrectRequest) {
387 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
388 MockWrite writes[] = {
389 CreateMockWrite(*conn, 0, SYNCHRONOUS),
392 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
393 MockRead reads[] = {
394 CreateMockRead(*resp, 1, ASYNC),
395 MockRead(ASYNC, 0, 2), // EOF
398 Initialize(reads, arraysize(reads), writes, arraysize(writes));
400 ASSERT_FALSE(sock_->IsConnected());
402 AssertConnectSucceeds();
404 AssertConnectionEstablished();
407 TEST_P(SpdyProxyClientSocketTest, ConnectWithAuthRequested) {
408 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
409 MockWrite writes[] = {
410 CreateMockWrite(*conn, 0, SYNCHRONOUS),
413 scoped_ptr<SpdyFrame> resp(ConstructConnectAuthReplyFrame());
414 MockRead reads[] = {
415 CreateMockRead(*resp, 1, ASYNC),
416 MockRead(ASYNC, 0, 2), // EOF
419 Initialize(reads, arraysize(reads), writes, arraysize(writes));
421 AssertConnectFails(ERR_PROXY_AUTH_REQUESTED);
423 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
424 ASSERT_TRUE(response != NULL);
425 ASSERT_EQ(407, response->headers->response_code());
428 TEST_P(SpdyProxyClientSocketTest, ConnectWithAuthCredentials) {
429 scoped_ptr<SpdyFrame> conn(ConstructConnectAuthRequestFrame());
430 MockWrite writes[] = {
431 CreateMockWrite(*conn, 0, SYNCHRONOUS),
434 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
435 MockRead reads[] = {
436 CreateMockRead(*resp, 1, ASYNC),
437 MockRead(ASYNC, 0, 2), // EOF
440 Initialize(reads, arraysize(reads), writes, arraysize(writes));
441 AddAuthToCache();
443 AssertConnectSucceeds();
445 AssertConnectionEstablished();
448 TEST_P(SpdyProxyClientSocketTest, ConnectRedirects) {
449 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
450 scoped_ptr<SpdyFrame> rst(
451 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
452 MockWrite writes[] = {
453 CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 2),
456 scoped_ptr<SpdyFrame> resp(ConstructConnectRedirectReplyFrame());
457 MockRead reads[] = {
458 CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3), // EOF
461 Initialize(reads, arraysize(reads), writes, arraysize(writes));
463 AssertConnectFails(ERR_HTTPS_PROXY_TUNNEL_RESPONSE);
465 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
466 ASSERT_TRUE(response != NULL);
468 const HttpResponseHeaders* headers = response->headers.get();
469 ASSERT_EQ(302, headers->response_code());
470 ASSERT_FALSE(headers->HasHeader("set-cookie"));
471 ASSERT_TRUE(headers->HasHeaderValue("content-length", "0"));
473 std::string location;
474 ASSERT_TRUE(headers->IsRedirect(&location));
475 ASSERT_EQ(location, kRedirectUrl);
477 // Let the RST_STREAM write while |rst| is in-scope.
478 base::MessageLoop::current()->RunUntilIdle();
481 TEST_P(SpdyProxyClientSocketTest, ConnectFails) {
482 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
483 MockWrite writes[] = {
484 CreateMockWrite(*conn, 0, SYNCHRONOUS),
487 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
488 MockRead reads[] = {
489 MockRead(ASYNC, 0, 1), // EOF
492 Initialize(reads, arraysize(reads), writes, arraysize(writes));
494 ASSERT_FALSE(sock_->IsConnected());
496 AssertConnectFails(ERR_CONNECTION_CLOSED);
498 ASSERT_FALSE(sock_->IsConnected());
501 // ----------- WasEverUsed
503 TEST_P(SpdyProxyClientSocketTest, WasEverUsedReturnsCorrectValues) {
504 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
505 scoped_ptr<SpdyFrame> rst(
506 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
507 MockWrite writes[] = {
508 CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 2),
511 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
512 MockRead reads[] = {
513 CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3), // EOF
516 Initialize(reads, arraysize(reads), writes, arraysize(writes));
518 EXPECT_FALSE(sock_->WasEverUsed());
519 AssertConnectSucceeds();
520 EXPECT_TRUE(sock_->WasEverUsed());
521 sock_->Disconnect();
522 EXPECT_TRUE(sock_->WasEverUsed());
524 // Let the RST_STREAM write while |rst| is in-scope.
525 base::MessageLoop::current()->RunUntilIdle();
528 // ----------- GetPeerAddress
530 TEST_P(SpdyProxyClientSocketTest, GetPeerAddressReturnsCorrectValues) {
531 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
532 MockWrite writes[] = {
533 CreateMockWrite(*conn, 0, SYNCHRONOUS),
536 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
537 MockRead reads[] = {
538 CreateMockRead(*resp, 1, ASYNC),
539 MockRead(ASYNC, 0, 2), // EOF
542 Initialize(reads, arraysize(reads), writes, arraysize(writes));
544 net::IPEndPoint addr;
545 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr));
547 AssertConnectSucceeds();
548 EXPECT_TRUE(sock_->IsConnected());
549 EXPECT_EQ(OK, sock_->GetPeerAddress(&addr));
551 Run(1);
553 EXPECT_FALSE(sock_->IsConnected());
554 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr));
556 sock_->Disconnect();
558 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr));
561 // ----------- Write
563 TEST_P(SpdyProxyClientSocketTest, WriteSendsDataInDataFrame) {
564 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
565 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
566 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
567 MockWrite writes[] = {
568 CreateMockWrite(*conn, 0, SYNCHRONOUS),
569 CreateMockWrite(*msg1, 2, SYNCHRONOUS),
570 CreateMockWrite(*msg2, 3, SYNCHRONOUS),
573 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
574 MockRead reads[] = {
575 CreateMockRead(*resp, 1, ASYNC),
576 MockRead(ASYNC, 0, 4), // EOF
579 Initialize(reads, arraysize(reads), writes, arraysize(writes));
581 AssertConnectSucceeds();
583 AssertAsyncWriteSucceeds(kMsg1, kLen1);
584 AssertAsyncWriteSucceeds(kMsg2, kLen2);
587 TEST_P(SpdyProxyClientSocketTest, WriteSplitsLargeDataIntoMultipleFrames) {
588 std::string chunk_data(kMaxSpdyFrameChunkSize, 'x');
589 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
590 scoped_ptr<SpdyFrame> chunk(ConstructBodyFrame(chunk_data.data(),
591 chunk_data.length()));
592 MockWrite writes[] = {
593 CreateMockWrite(*conn, 0, SYNCHRONOUS),
594 CreateMockWrite(*chunk, 2, SYNCHRONOUS),
595 CreateMockWrite(*chunk, 3, SYNCHRONOUS),
596 CreateMockWrite(*chunk, 4, SYNCHRONOUS)
599 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
600 MockRead reads[] = {
601 CreateMockRead(*resp, 1, ASYNC),
602 MockRead(ASYNC, 0, 5), // EOF
605 Initialize(reads, arraysize(reads), writes, arraysize(writes));
607 AssertConnectSucceeds();
609 std::string big_data(kMaxSpdyFrameChunkSize * 3, 'x');
610 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(big_data.data(),
611 big_data.length()));
613 EXPECT_EQ(ERR_IO_PENDING,
614 sock_->Write(buf.get(), buf->size(), write_callback_.callback()));
615 data_->RunFor(3);
617 EXPECT_EQ(buf->size(), write_callback_.WaitForResult());
620 // ----------- Read
622 TEST_P(SpdyProxyClientSocketTest, ReadReadsDataInDataFrame) {
623 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
624 MockWrite writes[] = {
625 CreateMockWrite(*conn, 0, SYNCHRONOUS),
628 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
629 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
630 MockRead reads[] = {
631 CreateMockRead(*resp, 1, ASYNC),
632 CreateMockRead(*msg1, 2, ASYNC),
633 MockRead(ASYNC, 0, 3), // EOF
636 Initialize(reads, arraysize(reads), writes, arraysize(writes));
638 AssertConnectSucceeds();
640 Run(1); // SpdySession consumes the next read and sends it to
641 // sock_ to be buffered.
642 AssertSyncReadEquals(kMsg1, kLen1);
645 TEST_P(SpdyProxyClientSocketTest, ReadDataFromBufferedFrames) {
646 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
647 MockWrite writes[] = {
648 CreateMockWrite(*conn, 0, SYNCHRONOUS),
651 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
652 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
653 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
654 MockRead reads[] = {
655 CreateMockRead(*resp, 1, ASYNC),
656 CreateMockRead(*msg1, 2, ASYNC),
657 CreateMockRead(*msg2, 3, ASYNC),
658 MockRead(ASYNC, 0, 4), // EOF
661 Initialize(reads, arraysize(reads), writes, arraysize(writes));
663 AssertConnectSucceeds();
665 Run(1); // SpdySession consumes the next read and sends it to
666 // sock_ to be buffered.
667 AssertSyncReadEquals(kMsg1, kLen1);
668 Run(1); // SpdySession consumes the next read and sends it to
669 // sock_ to be buffered.
670 AssertSyncReadEquals(kMsg2, kLen2);
673 TEST_P(SpdyProxyClientSocketTest, ReadDataMultipleBufferedFrames) {
674 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
675 MockWrite writes[] = {
676 CreateMockWrite(*conn, 0, SYNCHRONOUS),
679 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
680 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
681 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
682 MockRead reads[] = {
683 CreateMockRead(*resp, 1, ASYNC),
684 CreateMockRead(*msg1, 2, ASYNC),
685 CreateMockRead(*msg2, 3, ASYNC),
686 MockRead(ASYNC, 0, 4), // EOF
689 Initialize(reads, arraysize(reads), writes, arraysize(writes));
691 AssertConnectSucceeds();
693 Run(2); // SpdySession consumes the next two reads and sends then to
694 // sock_ to be buffered.
695 AssertSyncReadEquals(kMsg1, kLen1);
696 AssertSyncReadEquals(kMsg2, kLen2);
699 TEST_P(SpdyProxyClientSocketTest,
700 LargeReadWillMergeDataFromDifferentFrames) {
701 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
702 MockWrite writes[] = {
703 CreateMockWrite(*conn, 0, SYNCHRONOUS),
706 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
707 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
708 scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
709 MockRead reads[] = {
710 CreateMockRead(*resp, 1, ASYNC),
711 CreateMockRead(*msg3, 2, ASYNC),
712 CreateMockRead(*msg3, 3, ASYNC),
713 MockRead(ASYNC, 0, 4), // EOF
716 Initialize(reads, arraysize(reads), writes, arraysize(writes));
718 AssertConnectSucceeds();
720 Run(2); // SpdySession consumes the next two reads and sends then to
721 // sock_ to be buffered.
722 // The payload from two data frames, each with kMsg3 will be combined
723 // together into a single read().
724 AssertSyncReadEquals(kMsg33, kLen33);
727 TEST_P(SpdyProxyClientSocketTest, MultipleShortReadsThenMoreRead) {
728 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
729 MockWrite writes[] = {
730 CreateMockWrite(*conn, 0, SYNCHRONOUS),
733 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
734 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
735 scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
736 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
737 MockRead reads[] = {
738 CreateMockRead(*resp, 1, ASYNC),
739 CreateMockRead(*msg1, 2, ASYNC),
740 CreateMockRead(*msg3, 3, ASYNC),
741 CreateMockRead(*msg3, 4, ASYNC),
742 CreateMockRead(*msg2, 5, ASYNC),
743 MockRead(ASYNC, 0, 6), // EOF
746 Initialize(reads, arraysize(reads), writes, arraysize(writes));
748 AssertConnectSucceeds();
750 Run(4); // SpdySession consumes the next four reads and sends then to
751 // sock_ to be buffered.
752 AssertSyncReadEquals(kMsg1, kLen1);
753 // The payload from two data frames, each with kMsg3 will be combined
754 // together into a single read().
755 AssertSyncReadEquals(kMsg33, kLen33);
756 AssertSyncReadEquals(kMsg2, kLen2);
759 TEST_P(SpdyProxyClientSocketTest, ReadWillSplitDataFromLargeFrame) {
760 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
761 MockWrite writes[] = {
762 CreateMockWrite(*conn, 0, SYNCHRONOUS),
765 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
766 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
767 scoped_ptr<SpdyFrame> msg33(ConstructBodyFrame(kMsg33, kLen33));
768 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
769 MockRead reads[] = {
770 CreateMockRead(*resp, 1, ASYNC),
771 CreateMockRead(*msg1, 2, ASYNC),
772 CreateMockRead(*msg33, 3, ASYNC),
773 MockRead(ASYNC, 0, 4), // EOF
776 Initialize(reads, arraysize(reads), writes, arraysize(writes));
778 AssertConnectSucceeds();
780 Run(2); // SpdySession consumes the next two reads and sends then to
781 // sock_ to be buffered.
782 AssertSyncReadEquals(kMsg1, kLen1);
783 // The payload from the single large data frame will be read across
784 // two different reads.
785 AssertSyncReadEquals(kMsg3, kLen3);
786 AssertSyncReadEquals(kMsg3, kLen3);
789 TEST_P(SpdyProxyClientSocketTest, MultipleReadsFromSameLargeFrame) {
790 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
791 MockWrite writes[] = {
792 CreateMockWrite(*conn, 0, SYNCHRONOUS),
795 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
796 scoped_ptr<SpdyFrame> msg333(ConstructBodyFrame(kMsg333, kLen333));
797 MockRead reads[] = {
798 CreateMockRead(*resp, 1, ASYNC),
799 CreateMockRead(*msg333, 2, ASYNC),
800 MockRead(ASYNC, 0, 3), // EOF
803 Initialize(reads, arraysize(reads), writes, arraysize(writes));
805 AssertConnectSucceeds();
807 Run(1); // SpdySession consumes the next read and sends it to
808 // sock_ to be buffered.
809 // The payload from the single large data frame will be read across
810 // two different reads.
811 AssertSyncReadEquals(kMsg33, kLen33);
813 // Now attempt to do a read of more data than remains buffered
814 scoped_refptr<IOBuffer> buf(new IOBuffer(kLen33));
815 ASSERT_EQ(kLen3, sock_->Read(buf.get(), kLen33, read_callback_.callback()));
816 ASSERT_EQ(std::string(kMsg3, kLen3), std::string(buf->data(), kLen3));
817 ASSERT_TRUE(sock_->IsConnected());
820 TEST_P(SpdyProxyClientSocketTest, ReadAuthResponseBody) {
821 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
822 MockWrite writes[] = {
823 CreateMockWrite(*conn, 0, SYNCHRONOUS),
826 scoped_ptr<SpdyFrame> resp(ConstructConnectAuthReplyFrame());
827 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
828 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
829 MockRead reads[] = {
830 CreateMockRead(*resp, 1, ASYNC),
831 CreateMockRead(*msg1, 2, ASYNC),
832 CreateMockRead(*msg2, 3, ASYNC),
833 MockRead(ASYNC, 0, 4), // EOF
836 Initialize(reads, arraysize(reads), writes, arraysize(writes));
838 AssertConnectFails(ERR_PROXY_AUTH_REQUESTED);
840 Run(2); // SpdySession consumes the next two reads and sends then to
841 // sock_ to be buffered.
842 AssertSyncReadEquals(kMsg1, kLen1);
843 AssertSyncReadEquals(kMsg2, kLen2);
846 TEST_P(SpdyProxyClientSocketTest, ReadErrorResponseBody) {
847 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
848 MockWrite writes[] = {
849 CreateMockWrite(*conn, 0, SYNCHRONOUS),
852 scoped_ptr<SpdyFrame> resp(ConstructConnectErrorReplyFrame());
853 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
854 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
855 MockRead reads[] = {
856 CreateMockRead(*resp, 1, ASYNC),
857 CreateMockRead(*msg1, 2, ASYNC),
858 CreateMockRead(*msg2, 3, ASYNC),
859 MockRead(ASYNC, 0, 4), // EOF
862 Initialize(reads, arraysize(reads), writes, arraysize(writes));
864 AssertConnectFails(ERR_TUNNEL_CONNECTION_FAILED);
867 // ----------- Reads and Writes
869 TEST_P(SpdyProxyClientSocketTest, AsyncReadAroundWrite) {
870 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
871 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
872 MockWrite writes[] = {
873 CreateMockWrite(*conn, 0, SYNCHRONOUS),
874 CreateMockWrite(*msg2, 3, SYNCHRONOUS),
877 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
878 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
879 scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
880 MockRead reads[] = {
881 CreateMockRead(*resp, 1, ASYNC),
882 CreateMockRead(*msg1, 2, ASYNC), // sync read
883 CreateMockRead(*msg3, 4, ASYNC), // async read
884 MockRead(ASYNC, 0, 5), // EOF
887 Initialize(reads, arraysize(reads), writes, arraysize(writes));
889 AssertConnectSucceeds();
891 Run(1);
892 AssertSyncReadEquals(kMsg1, kLen1);
894 AssertReadStarts(kMsg3, kLen3);
895 // Read should block until after the write succeeds
897 AssertAsyncWriteSucceeds(kMsg2, kLen2); // Runs 1 step
899 ASSERT_FALSE(read_callback_.have_result());
900 Run(1);
901 // Now the read will return
902 AssertReadReturns(kMsg3, kLen3);
905 TEST_P(SpdyProxyClientSocketTest, AsyncWriteAroundReads) {
906 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
907 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
908 MockWrite writes[] = {
909 CreateMockWrite(*conn, 0, SYNCHRONOUS),
910 CreateMockWrite(*msg2, 4, ASYNC),
913 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
914 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
915 scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
916 MockRead reads[] = {
917 CreateMockRead(*resp, 1, ASYNC),
918 CreateMockRead(*msg1, 2, ASYNC),
919 CreateMockRead(*msg3, 3, ASYNC),
920 MockRead(ASYNC, 0, 5), // EOF
923 Initialize(reads, arraysize(reads), writes, arraysize(writes));
925 AssertConnectSucceeds();
927 Run(1);
928 AssertSyncReadEquals(kMsg1, kLen1);
929 // Write should block until the read completes
930 AssertWriteReturns(kMsg2, kLen2, ERR_IO_PENDING);
932 AssertAsyncReadEquals(kMsg3, kLen3);
934 ASSERT_FALSE(write_callback_.have_result());
936 // Now the write will complete
937 Run(1);
938 AssertWriteLength(kLen2);
941 // ----------- Reading/Writing on Closed socket
943 // Reading from an already closed socket should return 0
944 TEST_P(SpdyProxyClientSocketTest, ReadOnClosedSocketReturnsZero) {
945 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
946 MockWrite writes[] = {
947 CreateMockWrite(*conn, 0, SYNCHRONOUS),
950 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
951 MockRead reads[] = {
952 CreateMockRead(*resp, 1, ASYNC),
953 MockRead(ASYNC, 0, 2), // EOF
956 Initialize(reads, arraysize(reads), writes, arraysize(writes));
958 AssertConnectSucceeds();
960 Run(1);
962 ASSERT_FALSE(sock_->IsConnected());
963 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
964 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
965 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
966 ASSERT_FALSE(sock_->IsConnectedAndIdle());
969 // Read pending when socket is closed should return 0
970 TEST_P(SpdyProxyClientSocketTest, PendingReadOnCloseReturnsZero) {
971 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
972 MockWrite writes[] = {
973 CreateMockWrite(*conn, 0, SYNCHRONOUS),
976 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
977 MockRead reads[] = {
978 CreateMockRead(*resp, 1, ASYNC),
979 MockRead(ASYNC, 0, 2), // EOF
982 Initialize(reads, arraysize(reads), writes, arraysize(writes));
984 AssertConnectSucceeds();
986 AssertReadStarts(kMsg1, kLen1);
988 Run(1);
990 ASSERT_EQ(0, read_callback_.WaitForResult());
993 // Reading from a disconnected socket is an error
994 TEST_P(SpdyProxyClientSocketTest,
995 ReadOnDisconnectSocketReturnsNotConnected) {
996 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
997 scoped_ptr<SpdyFrame> rst(
998 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
999 MockWrite writes[] = {
1000 CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 2),
1003 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1004 MockRead reads[] = {
1005 CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3), // EOF
1008 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1010 AssertConnectSucceeds();
1012 sock_->Disconnect();
1014 ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED,
1015 sock_->Read(NULL, 1, CompletionCallback()));
1017 // Let the RST_STREAM write while |rst| is in-scope.
1018 base::MessageLoop::current()->RunUntilIdle();
1021 // Reading buffered data from an already closed socket should return
1022 // buffered data, then 0.
1023 TEST_P(SpdyProxyClientSocketTest, ReadOnClosedSocketReturnsBufferedData) {
1024 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1025 MockWrite writes[] = {
1026 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1029 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1030 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
1031 MockRead reads[] = {
1032 CreateMockRead(*resp, 1, ASYNC),
1033 CreateMockRead(*msg1, 2, ASYNC),
1034 MockRead(ASYNC, 0, 3), // EOF
1037 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1039 AssertConnectSucceeds();
1041 Run(2);
1043 ASSERT_FALSE(sock_->IsConnected());
1044 scoped_refptr<IOBuffer> buf(new IOBuffer(kLen1));
1045 ASSERT_EQ(kLen1, sock_->Read(buf.get(), kLen1, CompletionCallback()));
1046 ASSERT_EQ(std::string(kMsg1, kLen1), std::string(buf->data(), kLen1));
1048 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
1049 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
1050 sock_->Disconnect();
1051 ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED,
1052 sock_->Read(NULL, 1, CompletionCallback()));
1055 // Calling Write() on a closed socket is an error
1056 TEST_P(SpdyProxyClientSocketTest, WriteOnClosedStream) {
1057 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1058 MockWrite writes[] = {
1059 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1062 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1063 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
1064 MockRead reads[] = {
1065 CreateMockRead(*resp, 1, ASYNC),
1066 MockRead(ASYNC, 0, 2), // EOF
1069 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1071 AssertConnectSucceeds();
1073 Run(1); // Read EOF which will close the stream
1074 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
1075 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED,
1076 sock_->Write(buf.get(), buf->size(), CompletionCallback()));
1079 // Calling Write() on a disconnected socket is an error
1080 TEST_P(SpdyProxyClientSocketTest, WriteOnDisconnectedSocket) {
1081 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1082 scoped_ptr<SpdyFrame> rst(
1083 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
1084 MockWrite writes[] = {
1085 CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 2),
1088 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1089 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
1090 MockRead reads[] = {
1091 CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3), // EOF
1094 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1096 AssertConnectSucceeds();
1098 sock_->Disconnect();
1100 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
1101 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED,
1102 sock_->Write(buf.get(), buf->size(), CompletionCallback()));
1104 // Let the RST_STREAM write while |rst| is in-scope.
1105 base::MessageLoop::current()->RunUntilIdle();
1108 // If the socket is closed with a pending Write(), the callback
1109 // should be called with ERR_CONNECTION_CLOSED.
1110 TEST_P(SpdyProxyClientSocketTest, WritePendingOnClose) {
1111 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1112 MockWrite writes[] = {
1113 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1114 MockWrite(ASYNC, ERR_ABORTED, 2),
1117 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1118 MockRead reads[] = {
1119 CreateMockRead(*resp, 1, ASYNC),
1120 MockRead(ASYNC, 0, 3), // EOF
1123 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1125 AssertConnectSucceeds();
1127 EXPECT_TRUE(sock_->IsConnected());
1129 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
1130 EXPECT_EQ(ERR_IO_PENDING,
1131 sock_->Write(buf.get(), buf->size(), write_callback_.callback()));
1133 CloseSpdySession(ERR_ABORTED, std::string());
1135 EXPECT_EQ(ERR_CONNECTION_CLOSED, write_callback_.WaitForResult());
1138 // If the socket is Disconnected with a pending Write(), the callback
1139 // should not be called.
1140 TEST_P(SpdyProxyClientSocketTest, DisconnectWithWritePending) {
1141 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1142 scoped_ptr<SpdyFrame> rst(
1143 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
1144 MockWrite writes[] = {
1145 CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 2),
1146 MockWrite(SYNCHRONOUS, 0, 3), // EOF
1149 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1150 MockRead reads[] = {
1151 CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 4), // EOF
1154 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1156 AssertConnectSucceeds();
1158 EXPECT_TRUE(sock_->IsConnected());
1160 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
1161 EXPECT_EQ(ERR_IO_PENDING,
1162 sock_->Write(buf.get(), buf->size(), write_callback_.callback()));
1164 sock_->Disconnect();
1166 EXPECT_FALSE(sock_->IsConnected());
1167 EXPECT_FALSE(write_callback_.have_result());
1169 // Let the RST_STREAM write while |rst| is in-scope.
1170 base::MessageLoop::current()->RunUntilIdle();
1173 // If the socket is Disconnected with a pending Read(), the callback
1174 // should not be called.
1175 TEST_P(SpdyProxyClientSocketTest, DisconnectWithReadPending) {
1176 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1177 scoped_ptr<SpdyFrame> rst(
1178 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
1179 MockWrite writes[] = {
1180 CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 2),
1183 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1184 MockRead reads[] = {
1185 CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3), // EOF
1188 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1190 AssertConnectSucceeds();
1192 EXPECT_TRUE(sock_->IsConnected());
1194 scoped_refptr<IOBuffer> buf(new IOBuffer(kLen1));
1195 ASSERT_EQ(ERR_IO_PENDING,
1196 sock_->Read(buf.get(), kLen1, read_callback_.callback()));
1198 sock_->Disconnect();
1200 EXPECT_FALSE(sock_->IsConnected());
1201 EXPECT_FALSE(read_callback_.have_result());
1203 // Let the RST_STREAM write while |rst| is in-scope.
1204 base::MessageLoop::current()->RunUntilIdle();
1207 // If the socket is Reset when both a read and write are pending,
1208 // both should be called back.
1209 TEST_P(SpdyProxyClientSocketTest, RstWithReadAndWritePending) {
1210 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1211 MockWrite writes[] = {
1212 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1213 MockWrite(ASYNC, ERR_ABORTED, 3),
1216 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1217 scoped_ptr<SpdyFrame> rst(
1218 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
1219 MockRead reads[] = {
1220 CreateMockRead(*resp, 1, ASYNC),
1221 CreateMockRead(*rst, 2, ASYNC),
1222 MockRead(ASYNC, 0, 4) // EOF
1225 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1227 AssertConnectSucceeds();
1229 EXPECT_TRUE(sock_->IsConnected());
1231 scoped_refptr<IOBuffer> read_buf(new IOBuffer(kLen1));
1232 ASSERT_EQ(ERR_IO_PENDING,
1233 sock_->Read(read_buf.get(), kLen1, read_callback_.callback()));
1235 scoped_refptr<IOBufferWithSize> write_buf(CreateBuffer(kMsg1, kLen1));
1236 EXPECT_EQ(
1237 ERR_IO_PENDING,
1238 sock_->Write(
1239 write_buf.get(), write_buf->size(), write_callback_.callback()));
1241 Run(2);
1243 EXPECT_TRUE(sock_.get());
1244 EXPECT_TRUE(read_callback_.have_result());
1245 EXPECT_TRUE(write_callback_.have_result());
1247 // Let the RST_STREAM write while |rst| is in-scope.
1248 base::MessageLoop::current()->RunUntilIdle();
1251 // Makes sure the proxy client socket's source gets the expected NetLog events
1252 // and only the expected NetLog events (No SpdySession events).
1253 TEST_P(SpdyProxyClientSocketTest, NetLog) {
1254 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1255 scoped_ptr<SpdyFrame> rst(
1256 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
1257 MockWrite writes[] = {
1258 CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 3),
1261 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1262 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
1263 MockRead reads[] = {
1264 CreateMockRead(*resp, 1, ASYNC), CreateMockRead(*msg1, 2, ASYNC),
1265 MockRead(ASYNC, 0, 4), // EOF
1268 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1270 AssertConnectSucceeds();
1272 Run(1); // SpdySession consumes the next read and sends it to
1273 // sock_ to be buffered.
1274 AssertSyncReadEquals(kMsg1, kLen1);
1276 NetLog::Source sock_source = sock_->NetLog().source();
1277 sock_.reset();
1279 CapturingNetLog::CapturedEntryList entry_list;
1280 net_log_.GetEntriesForSource(sock_source, &entry_list);
1282 ASSERT_EQ(entry_list.size(), 10u);
1283 EXPECT_TRUE(LogContainsBeginEvent(entry_list, 0, NetLog::TYPE_SOCKET_ALIVE));
1284 EXPECT_TRUE(LogContainsEvent(entry_list, 1,
1285 NetLog::TYPE_SPDY_PROXY_CLIENT_SESSION,
1286 NetLog::PHASE_NONE));
1287 EXPECT_TRUE(LogContainsBeginEvent(entry_list, 2,
1288 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_SEND_REQUEST));
1289 EXPECT_TRUE(LogContainsEvent(entry_list, 3,
1290 NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
1291 NetLog::PHASE_NONE));
1292 EXPECT_TRUE(LogContainsEndEvent(entry_list, 4,
1293 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_SEND_REQUEST));
1294 EXPECT_TRUE(LogContainsBeginEvent(entry_list, 5,
1295 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_READ_HEADERS));
1296 EXPECT_TRUE(LogContainsEvent(entry_list, 6,
1297 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
1298 NetLog::PHASE_NONE));
1299 EXPECT_TRUE(LogContainsEndEvent(entry_list, 7,
1300 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_READ_HEADERS));
1301 EXPECT_TRUE(LogContainsEvent(entry_list, 8,
1302 NetLog::TYPE_SOCKET_BYTES_RECEIVED,
1303 NetLog::PHASE_NONE));
1304 EXPECT_TRUE(LogContainsEndEvent(entry_list, 9, NetLog::TYPE_SOCKET_ALIVE));
1306 // Let the RST_STREAM write while |rst| is in-scope.
1307 base::MessageLoop::current()->RunUntilIdle();
1310 // CompletionCallback that causes the SpdyProxyClientSocket to be
1311 // deleted when Run is invoked.
1312 class DeleteSockCallback : public TestCompletionCallbackBase {
1313 public:
1314 explicit DeleteSockCallback(scoped_ptr<SpdyProxyClientSocket>* sock)
1315 : sock_(sock),
1316 callback_(base::Bind(&DeleteSockCallback::OnComplete,
1317 base::Unretained(this))) {
1320 virtual ~DeleteSockCallback() {
1323 const CompletionCallback& callback() const { return callback_; }
1325 private:
1326 void OnComplete(int result) {
1327 sock_->reset(NULL);
1328 SetResult(result);
1331 scoped_ptr<SpdyProxyClientSocket>* sock_;
1332 CompletionCallback callback_;
1334 DISALLOW_COPY_AND_ASSIGN(DeleteSockCallback);
1337 // If the socket is Reset when both a read and write are pending, and the
1338 // read callback causes the socket to be deleted, the write callback should
1339 // not be called.
1340 TEST_P(SpdyProxyClientSocketTest, RstWithReadAndWritePendingDelete) {
1341 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1342 MockWrite writes[] = {
1343 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1344 MockWrite(ASYNC, ERR_ABORTED, 3),
1347 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1348 scoped_ptr<SpdyFrame> rst(
1349 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
1350 MockRead reads[] = {
1351 CreateMockRead(*resp, 1, ASYNC),
1352 CreateMockRead(*rst, 2, ASYNC),
1353 MockRead(ASYNC, 0, 4), // EOF
1356 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1358 AssertConnectSucceeds();
1360 EXPECT_TRUE(sock_->IsConnected());
1362 DeleteSockCallback read_callback(&sock_);
1364 scoped_refptr<IOBuffer> read_buf(new IOBuffer(kLen1));
1365 ASSERT_EQ(ERR_IO_PENDING,
1366 sock_->Read(read_buf.get(), kLen1, read_callback.callback()));
1368 scoped_refptr<IOBufferWithSize> write_buf(CreateBuffer(kMsg1, kLen1));
1369 EXPECT_EQ(
1370 ERR_IO_PENDING,
1371 sock_->Write(
1372 write_buf.get(), write_buf->size(), write_callback_.callback()));
1374 Run(1);
1376 EXPECT_FALSE(sock_.get());
1377 EXPECT_TRUE(read_callback.have_result());
1378 EXPECT_FALSE(write_callback_.have_result());
1380 // Let the RST_STREAM write while |rst| is in-scope.
1381 base::MessageLoop::current()->RunUntilIdle();
1384 } // namespace net