Revert of Update WV test license server config to use portable sdk server. (https...
[chromium-blink-merge.git] / net / spdy / spdy_proxy_client_socket_unittest.cc
blob18fef797df63a7740c6fefeee706d223cb89060a
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[] = "\00012345678\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 SpdyFrame* ConstructConnectRequestFrame();
75 SpdyFrame* ConstructConnectAuthRequestFrame();
76 SpdyFrame* ConstructConnectReplyFrame();
77 SpdyFrame* ConstructConnectAuthReplyFrame();
78 SpdyFrame* ConstructConnectRedirectReplyFrame();
79 SpdyFrame* ConstructConnectErrorReplyFrame();
80 SpdyFrame* ConstructBodyFrame(const char* data, int length);
81 scoped_refptr<IOBufferWithSize> CreateBuffer(const char* data, int size);
82 void AssertConnectSucceeds();
83 void AssertConnectFails(int result);
84 void AssertConnectionEstablished();
85 void AssertSyncReadEquals(const char* data, int len);
86 void AssertAsyncReadEquals(const char* data, int len);
87 void AssertReadStarts(const char* data, int len);
88 void AssertReadReturns(const char* data, int len);
89 void AssertAsyncWriteSucceeds(const char* data, int len);
90 void AssertWriteReturns(const char* data, int len, int rv);
91 void AssertWriteLength(int len);
92 void AssertAsyncWriteWithReadsSucceeds(const char* data, int len,
93 int num_reads);
95 void AddAuthToCache() {
96 const base::string16 kFoo(base::ASCIIToUTF16("foo"));
97 const base::string16 kBar(base::ASCIIToUTF16("bar"));
98 session_->http_auth_cache()->Add(GURL(kProxyUrl),
99 "MyRealm1",
100 HttpAuth::AUTH_SCHEME_BASIC,
101 "Basic realm=MyRealm1",
102 AuthCredentials(kFoo, kBar),
103 "/");
106 void Run(int steps) {
107 data_->StopAfter(steps);
108 data_->Run();
111 void CloseSpdySession(net::Error error, const std::string& description) {
112 spdy_session_->CloseSessionOnError(error, description);
115 SpdyTestUtil spdy_util_;
116 scoped_ptr<SpdyProxyClientSocket> sock_;
117 TestCompletionCallback read_callback_;
118 TestCompletionCallback write_callback_;
119 scoped_ptr<DeterministicSocketData> data_;
120 CapturingBoundNetLog net_log_;
122 private:
123 scoped_refptr<HttpNetworkSession> session_;
124 scoped_refptr<IOBuffer> read_buf_;
125 SpdySessionDependencies session_deps_;
126 MockConnect connect_data_;
127 base::WeakPtr<SpdySession> spdy_session_;
128 BufferedSpdyFramer framer_;
130 std::string user_agent_;
131 GURL url_;
132 HostPortPair proxy_host_port_;
133 HostPortPair endpoint_host_port_pair_;
134 ProxyServer proxy_;
135 SpdySessionKey endpoint_spdy_session_key_;
137 DISALLOW_COPY_AND_ASSIGN(SpdyProxyClientSocketTest);
140 INSTANTIATE_TEST_CASE_P(
141 NextProto,
142 SpdyProxyClientSocketTest,
143 testing::Values(kProtoDeprecatedSPDY2,
144 kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2,
145 kProtoHTTP2Draft04));
147 SpdyProxyClientSocketTest::SpdyProxyClientSocketTest()
148 : spdy_util_(GetParam()),
149 session_(NULL),
150 read_buf_(NULL),
151 session_deps_(GetParam()),
152 connect_data_(SYNCHRONOUS, OK),
153 framer_(spdy_util_.spdy_version(), false),
154 user_agent_(kUserAgent),
155 url_(kRequestUrl),
156 proxy_host_port_(kProxyHost, kProxyPort),
157 endpoint_host_port_pair_(kOriginHost, kOriginPort),
158 proxy_(ProxyServer::SCHEME_HTTPS, proxy_host_port_),
159 endpoint_spdy_session_key_(endpoint_host_port_pair_,
160 proxy_,
161 kPrivacyModeDisabled) {
162 session_deps_.net_log = net_log_.bound().net_log();
165 void SpdyProxyClientSocketTest::TearDown() {
166 sock_.reset(NULL);
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());
233 ASSERT_EQ("Connection Established", response->headers->GetStatusText());
236 void SpdyProxyClientSocketTest::AssertSyncReadEquals(const char* data,
237 int len) {
238 scoped_refptr<IOBuffer> buf(new IOBuffer(len));
239 ASSERT_EQ(len, sock_->Read(buf.get(), len, CompletionCallback()));
240 ASSERT_EQ(std::string(data, len), std::string(buf->data(), len));
241 ASSERT_TRUE(sock_->IsConnected());
244 void SpdyProxyClientSocketTest::AssertAsyncReadEquals(const char* data,
245 int len) {
246 data_->StopAfter(1);
247 // Issue the read, which will be completed asynchronously
248 scoped_refptr<IOBuffer> buf(new IOBuffer(len));
249 ASSERT_EQ(ERR_IO_PENDING,
250 sock_->Read(buf.get(), len, read_callback_.callback()));
251 EXPECT_TRUE(sock_->IsConnected());
252 data_->Run();
254 EXPECT_TRUE(sock_->IsConnected());
256 // Now the read will return
257 EXPECT_EQ(len, read_callback_.WaitForResult());
258 ASSERT_EQ(std::string(data, len), std::string(buf->data(), len));
261 void SpdyProxyClientSocketTest::AssertReadStarts(const char* data,
262 int len) {
263 data_->StopAfter(1);
264 // Issue the read, which will be completed asynchronously
265 read_buf_ = new IOBuffer(len);
266 ASSERT_EQ(ERR_IO_PENDING,
267 sock_->Read(read_buf_.get(), len, read_callback_.callback()));
268 EXPECT_TRUE(sock_->IsConnected());
271 void SpdyProxyClientSocketTest::AssertReadReturns(const char* data,
272 int len) {
273 EXPECT_TRUE(sock_->IsConnected());
275 // Now the read will return
276 EXPECT_EQ(len, read_callback_.WaitForResult());
277 ASSERT_EQ(std::string(data, len), std::string(read_buf_->data(), len));
280 void SpdyProxyClientSocketTest::AssertAsyncWriteSucceeds(const char* data,
281 int len) {
282 AssertWriteReturns(data, len, ERR_IO_PENDING);
283 data_->RunFor(1);
284 AssertWriteLength(len);
287 void SpdyProxyClientSocketTest::AssertWriteReturns(const char* data,
288 int len,
289 int rv) {
290 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(data, len));
291 EXPECT_EQ(rv,
292 sock_->Write(buf.get(), buf->size(), write_callback_.callback()));
295 void SpdyProxyClientSocketTest::AssertWriteLength(int len) {
296 EXPECT_EQ(len, write_callback_.WaitForResult());
299 void SpdyProxyClientSocketTest::AssertAsyncWriteWithReadsSucceeds(
300 const char* data, int len, int num_reads) {
301 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(data, len));
303 EXPECT_EQ(ERR_IO_PENDING,
304 sock_->Write(buf.get(), buf->size(), write_callback_.callback()));
306 for (int i = 0; i < num_reads; i++) {
307 Run(1);
308 AssertSyncReadEquals(kMsg2, kLen2);
311 write_callback_.WaitForResult();
314 // Constructs a standard SPDY SYN_STREAM frame for a CONNECT request.
315 SpdyFrame*
316 SpdyProxyClientSocketTest::ConstructConnectRequestFrame() {
317 const SpdyHeaderInfo kSynStartHeader = {
318 SYN_STREAM,
319 kStreamId,
321 net::ConvertRequestPriorityToSpdyPriority(
322 LOWEST, spdy_util_.spdy_version()),
324 CONTROL_FLAG_NONE,
325 false,
326 RST_STREAM_INVALID,
327 NULL,
329 DATA_FLAG_NONE
331 bool spdy2 = spdy_util_.is_spdy2();
332 const char* const kConnectHeaders[] = {
333 spdy2 ? "method" : ":method", "CONNECT",
334 spdy2 ? "url" : ":path", kOriginHostPort,
335 spdy2 ? "host" : ":host", kOriginHost,
336 "user-agent", kUserAgent,
337 spdy2 ? "version" : ":version", "HTTP/1.1",
339 return spdy_util_.ConstructSpdyFrame(
340 kSynStartHeader, NULL, 0, kConnectHeaders, arraysize(kConnectHeaders)/2);
343 // Constructs a SPDY SYN_STREAM frame for a CONNECT request which includes
344 // Proxy-Authorization headers.
345 SpdyFrame*
346 SpdyProxyClientSocketTest::ConstructConnectAuthRequestFrame() {
347 const SpdyHeaderInfo kSynStartHeader = {
348 SYN_STREAM,
349 kStreamId,
351 net::ConvertRequestPriorityToSpdyPriority(
352 LOWEST, spdy_util_.spdy_version()),
354 CONTROL_FLAG_NONE,
355 false,
356 RST_STREAM_INVALID,
357 NULL,
359 DATA_FLAG_NONE
361 bool spdy2 = spdy_util_.is_spdy2();
362 const char* const kConnectHeaders[] = {
363 spdy2 ? "method" : ":method", "CONNECT",
364 spdy2 ? "url" : ":path", kOriginHostPort,
365 spdy2 ? "host" : ":host", kOriginHost,
366 "user-agent", kUserAgent,
367 spdy2 ? "version" : ":version", "HTTP/1.1",
368 "proxy-authorization", "Basic Zm9vOmJhcg==",
370 return spdy_util_.ConstructSpdyFrame(
371 kSynStartHeader, NULL, 0, kConnectHeaders, arraysize(kConnectHeaders)/2);
374 // Constructs a standard SPDY SYN_REPLY frame to match the SPDY CONNECT.
375 SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectReplyFrame() {
376 bool spdy2 = spdy_util_.is_spdy2();
377 const char* const kStandardReplyHeaders[] = {
378 spdy2 ? "status" : ":status", "200 Connection Established",
379 spdy2 ? "version" : ":version", "HTTP/1.1"
381 return spdy_util_.ConstructSpdyControlFrame(NULL,
383 false,
384 kStreamId,
385 LOWEST,
386 SYN_REPLY,
387 CONTROL_FLAG_NONE,
388 kStandardReplyHeaders,
389 arraysize(kStandardReplyHeaders),
393 // Constructs a standard SPDY SYN_REPLY frame to match the SPDY CONNECT.
394 SpdyFrame*
395 SpdyProxyClientSocketTest::ConstructConnectAuthReplyFrame() {
396 bool spdy2 = spdy_util_.is_spdy2();
398 const char* const kStandardReplyHeaders[] = {
399 spdy2 ? "status" : ":status", "407 Proxy Authentication Required",
400 spdy2 ? "version" : ":version", "HTTP/1.1",
401 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
404 return spdy_util_.ConstructSpdyControlFrame(NULL,
406 false,
407 kStreamId,
408 LOWEST,
409 SYN_REPLY,
410 CONTROL_FLAG_NONE,
411 kStandardReplyHeaders,
412 arraysize(kStandardReplyHeaders),
416 // Constructs a SPDY SYN_REPLY frame with an HTTP 302 redirect.
417 SpdyFrame*
418 SpdyProxyClientSocketTest::ConstructConnectRedirectReplyFrame() {
419 bool spdy2 = spdy_util_.is_spdy2();
421 const char* const kStandardReplyHeaders[] = {
422 spdy2 ? "status" : ":status", "302 Found",
423 spdy2 ? "version" : ":version", "HTTP/1.1",
424 "location", kRedirectUrl,
425 "set-cookie", "foo=bar"
428 return spdy_util_.ConstructSpdyControlFrame(NULL,
430 false,
431 kStreamId,
432 LOWEST,
433 SYN_REPLY,
434 CONTROL_FLAG_NONE,
435 kStandardReplyHeaders,
436 arraysize(kStandardReplyHeaders),
440 // Constructs a SPDY SYN_REPLY frame with an HTTP 500 error.
441 SpdyFrame*
442 SpdyProxyClientSocketTest::ConstructConnectErrorReplyFrame() {
443 bool spdy2 = spdy_util_.is_spdy2();
445 const char* const kStandardReplyHeaders[] = {
446 spdy2 ? "status" : ":status", "500 Internal Server Error",
447 spdy2 ? "version" : ":version", "HTTP/1.1",
450 return spdy_util_.ConstructSpdyControlFrame(NULL,
452 false,
453 kStreamId,
454 LOWEST,
455 SYN_REPLY,
456 CONTROL_FLAG_NONE,
457 kStandardReplyHeaders,
458 arraysize(kStandardReplyHeaders),
462 SpdyFrame* SpdyProxyClientSocketTest::ConstructBodyFrame(
463 const char* data,
464 int length) {
465 return framer_.CreateDataFrame(kStreamId, data, length, DATA_FLAG_NONE);
468 // ----------- Connect
470 TEST_P(SpdyProxyClientSocketTest, ConnectSendsCorrectRequest) {
471 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
472 MockWrite writes[] = {
473 CreateMockWrite(*conn, 0, SYNCHRONOUS),
476 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
477 MockRead reads[] = {
478 CreateMockRead(*resp, 1, ASYNC),
479 MockRead(ASYNC, 0, 2), // EOF
482 Initialize(reads, arraysize(reads), writes, arraysize(writes));
484 ASSERT_FALSE(sock_->IsConnected());
486 AssertConnectSucceeds();
488 AssertConnectionEstablished();
491 TEST_P(SpdyProxyClientSocketTest, ConnectWithAuthRequested) {
492 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
493 MockWrite writes[] = {
494 CreateMockWrite(*conn, 0, SYNCHRONOUS),
497 scoped_ptr<SpdyFrame> resp(ConstructConnectAuthReplyFrame());
498 MockRead reads[] = {
499 CreateMockRead(*resp, 1, ASYNC),
500 MockRead(ASYNC, 0, 2), // EOF
503 Initialize(reads, arraysize(reads), writes, arraysize(writes));
505 AssertConnectFails(ERR_PROXY_AUTH_REQUESTED);
507 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
508 ASSERT_TRUE(response != NULL);
509 ASSERT_EQ(407, response->headers->response_code());
510 ASSERT_EQ("Proxy Authentication Required",
511 response->headers->GetStatusText());
514 TEST_P(SpdyProxyClientSocketTest, ConnectWithAuthCredentials) {
515 scoped_ptr<SpdyFrame> conn(ConstructConnectAuthRequestFrame());
516 MockWrite writes[] = {
517 CreateMockWrite(*conn, 0, SYNCHRONOUS),
520 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
521 MockRead reads[] = {
522 CreateMockRead(*resp, 1, ASYNC),
523 MockRead(ASYNC, 0, 2), // EOF
526 Initialize(reads, arraysize(reads), writes, arraysize(writes));
527 AddAuthToCache();
529 AssertConnectSucceeds();
531 AssertConnectionEstablished();
534 TEST_P(SpdyProxyClientSocketTest, ConnectRedirects) {
535 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
536 MockWrite writes[] = {
537 CreateMockWrite(*conn, 0, SYNCHRONOUS),
540 scoped_ptr<SpdyFrame> resp(ConstructConnectRedirectReplyFrame());
541 MockRead reads[] = {
542 CreateMockRead(*resp, 1, ASYNC),
543 MockRead(ASYNC, 0, 2), // EOF
546 Initialize(reads, arraysize(reads), writes, arraysize(writes));
548 AssertConnectFails(ERR_HTTPS_PROXY_TUNNEL_RESPONSE);
550 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
551 ASSERT_TRUE(response != NULL);
553 const HttpResponseHeaders* headers = response->headers.get();
554 ASSERT_EQ(302, headers->response_code());
555 ASSERT_FALSE(headers->HasHeader("set-cookie"));
556 ASSERT_TRUE(headers->HasHeaderValue("content-length", "0"));
558 std::string location;
559 ASSERT_TRUE(headers->IsRedirect(&location));
560 ASSERT_EQ(location, kRedirectUrl);
563 TEST_P(SpdyProxyClientSocketTest, ConnectFails) {
564 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
565 MockWrite writes[] = {
566 CreateMockWrite(*conn, 0, SYNCHRONOUS),
569 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
570 MockRead reads[] = {
571 MockRead(ASYNC, 0, 1), // EOF
574 Initialize(reads, arraysize(reads), writes, arraysize(writes));
576 ASSERT_FALSE(sock_->IsConnected());
578 AssertConnectFails(ERR_CONNECTION_CLOSED);
580 ASSERT_FALSE(sock_->IsConnected());
583 // ----------- WasEverUsed
585 TEST_P(SpdyProxyClientSocketTest, WasEverUsedReturnsCorrectValues) {
586 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
587 MockWrite writes[] = {
588 CreateMockWrite(*conn, 0, SYNCHRONOUS),
591 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
592 MockRead reads[] = {
593 CreateMockRead(*resp, 1, ASYNC),
594 MockRead(ASYNC, 0, 2), // EOF
597 Initialize(reads, arraysize(reads), writes, arraysize(writes));
599 EXPECT_FALSE(sock_->WasEverUsed());
600 AssertConnectSucceeds();
601 EXPECT_TRUE(sock_->WasEverUsed());
602 sock_->Disconnect();
603 EXPECT_TRUE(sock_->WasEverUsed());
606 // ----------- GetPeerAddress
608 TEST_P(SpdyProxyClientSocketTest, GetPeerAddressReturnsCorrectValues) {
609 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
610 MockWrite writes[] = {
611 CreateMockWrite(*conn, 0, SYNCHRONOUS),
614 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
615 MockRead reads[] = {
616 CreateMockRead(*resp, 1, ASYNC),
617 MockRead(ASYNC, 0, 2), // EOF
620 Initialize(reads, arraysize(reads), writes, arraysize(writes));
622 net::IPEndPoint addr;
623 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr));
625 AssertConnectSucceeds();
626 EXPECT_TRUE(sock_->IsConnected());
627 EXPECT_EQ(OK, sock_->GetPeerAddress(&addr));
629 Run(1);
631 EXPECT_FALSE(sock_->IsConnected());
632 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr));
634 sock_->Disconnect();
636 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr));
639 // ----------- Write
641 TEST_P(SpdyProxyClientSocketTest, WriteSendsDataInDataFrame) {
642 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
643 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
644 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
645 MockWrite writes[] = {
646 CreateMockWrite(*conn, 0, SYNCHRONOUS),
647 CreateMockWrite(*msg1, 2, SYNCHRONOUS),
648 CreateMockWrite(*msg2, 3, SYNCHRONOUS),
651 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
652 MockRead reads[] = {
653 CreateMockRead(*resp, 1, ASYNC),
654 MockRead(ASYNC, 0, 4), // EOF
657 Initialize(reads, arraysize(reads), writes, arraysize(writes));
659 AssertConnectSucceeds();
661 AssertAsyncWriteSucceeds(kMsg1, kLen1);
662 AssertAsyncWriteSucceeds(kMsg2, kLen2);
665 TEST_P(SpdyProxyClientSocketTest, WriteSplitsLargeDataIntoMultipleFrames) {
666 std::string chunk_data(kMaxSpdyFrameChunkSize, 'x');
667 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
668 scoped_ptr<SpdyFrame> chunk(ConstructBodyFrame(chunk_data.data(),
669 chunk_data.length()));
670 MockWrite writes[] = {
671 CreateMockWrite(*conn, 0, SYNCHRONOUS),
672 CreateMockWrite(*chunk, 2, SYNCHRONOUS),
673 CreateMockWrite(*chunk, 3, SYNCHRONOUS),
674 CreateMockWrite(*chunk, 4, SYNCHRONOUS)
677 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
678 MockRead reads[] = {
679 CreateMockRead(*resp, 1, ASYNC),
680 MockRead(ASYNC, 0, 5), // EOF
683 Initialize(reads, arraysize(reads), writes, arraysize(writes));
685 AssertConnectSucceeds();
687 std::string big_data(kMaxSpdyFrameChunkSize * 3, 'x');
688 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(big_data.data(),
689 big_data.length()));
691 EXPECT_EQ(ERR_IO_PENDING,
692 sock_->Write(buf.get(), buf->size(), write_callback_.callback()));
693 data_->RunFor(3);
695 EXPECT_EQ(buf->size(), write_callback_.WaitForResult());
698 // ----------- Read
700 TEST_P(SpdyProxyClientSocketTest, ReadReadsDataInDataFrame) {
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 MockRead reads[] = {
709 CreateMockRead(*resp, 1, ASYNC),
710 CreateMockRead(*msg1, 2, ASYNC),
711 MockRead(ASYNC, 0, 3), // EOF
714 Initialize(reads, arraysize(reads), writes, arraysize(writes));
716 AssertConnectSucceeds();
718 Run(1); // SpdySession consumes the next read and sends it to
719 // sock_ to be buffered.
720 AssertSyncReadEquals(kMsg1, kLen1);
723 TEST_P(SpdyProxyClientSocketTest, ReadDataFromBufferedFrames) {
724 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
725 MockWrite writes[] = {
726 CreateMockWrite(*conn, 0, SYNCHRONOUS),
729 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
730 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
731 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
732 MockRead reads[] = {
733 CreateMockRead(*resp, 1, ASYNC),
734 CreateMockRead(*msg1, 2, ASYNC),
735 CreateMockRead(*msg2, 3, ASYNC),
736 MockRead(ASYNC, 0, 4), // EOF
739 Initialize(reads, arraysize(reads), writes, arraysize(writes));
741 AssertConnectSucceeds();
743 Run(1); // SpdySession consumes the next read and sends it to
744 // sock_ to be buffered.
745 AssertSyncReadEquals(kMsg1, kLen1);
746 Run(1); // SpdySession consumes the next read and sends it to
747 // sock_ to be buffered.
748 AssertSyncReadEquals(kMsg2, kLen2);
751 TEST_P(SpdyProxyClientSocketTest, ReadDataMultipleBufferedFrames) {
752 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
753 MockWrite writes[] = {
754 CreateMockWrite(*conn, 0, SYNCHRONOUS),
757 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
758 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
759 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
760 MockRead reads[] = {
761 CreateMockRead(*resp, 1, ASYNC),
762 CreateMockRead(*msg1, 2, ASYNC),
763 CreateMockRead(*msg2, 3, ASYNC),
764 MockRead(ASYNC, 0, 4), // EOF
767 Initialize(reads, arraysize(reads), writes, arraysize(writes));
769 AssertConnectSucceeds();
771 Run(2); // SpdySession consumes the next two reads and sends then to
772 // sock_ to be buffered.
773 AssertSyncReadEquals(kMsg1, kLen1);
774 AssertSyncReadEquals(kMsg2, kLen2);
777 TEST_P(SpdyProxyClientSocketTest,
778 LargeReadWillMergeDataFromDifferentFrames) {
779 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
780 MockWrite writes[] = {
781 CreateMockWrite(*conn, 0, SYNCHRONOUS),
784 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
785 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
786 scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
787 MockRead reads[] = {
788 CreateMockRead(*resp, 1, ASYNC),
789 CreateMockRead(*msg3, 2, ASYNC),
790 CreateMockRead(*msg3, 3, ASYNC),
791 MockRead(ASYNC, 0, 4), // EOF
794 Initialize(reads, arraysize(reads), writes, arraysize(writes));
796 AssertConnectSucceeds();
798 Run(2); // SpdySession consumes the next two reads and sends then to
799 // sock_ to be buffered.
800 // The payload from two data frames, each with kMsg3 will be combined
801 // together into a single read().
802 AssertSyncReadEquals(kMsg33, kLen33);
805 TEST_P(SpdyProxyClientSocketTest, MultipleShortReadsThenMoreRead) {
806 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
807 MockWrite writes[] = {
808 CreateMockWrite(*conn, 0, SYNCHRONOUS),
811 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
812 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
813 scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
814 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
815 MockRead reads[] = {
816 CreateMockRead(*resp, 1, ASYNC),
817 CreateMockRead(*msg1, 2, ASYNC),
818 CreateMockRead(*msg3, 3, ASYNC),
819 CreateMockRead(*msg3, 4, ASYNC),
820 CreateMockRead(*msg2, 5, ASYNC),
821 MockRead(ASYNC, 0, 6), // EOF
824 Initialize(reads, arraysize(reads), writes, arraysize(writes));
826 AssertConnectSucceeds();
828 Run(4); // SpdySession consumes the next four reads and sends then to
829 // sock_ to be buffered.
830 AssertSyncReadEquals(kMsg1, kLen1);
831 // The payload from two data frames, each with kMsg3 will be combined
832 // together into a single read().
833 AssertSyncReadEquals(kMsg33, kLen33);
834 AssertSyncReadEquals(kMsg2, kLen2);
837 TEST_P(SpdyProxyClientSocketTest, ReadWillSplitDataFromLargeFrame) {
838 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
839 MockWrite writes[] = {
840 CreateMockWrite(*conn, 0, SYNCHRONOUS),
843 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
844 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
845 scoped_ptr<SpdyFrame> msg33(ConstructBodyFrame(kMsg33, kLen33));
846 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
847 MockRead reads[] = {
848 CreateMockRead(*resp, 1, ASYNC),
849 CreateMockRead(*msg1, 2, ASYNC),
850 CreateMockRead(*msg33, 3, ASYNC),
851 MockRead(ASYNC, 0, 4), // EOF
854 Initialize(reads, arraysize(reads), writes, arraysize(writes));
856 AssertConnectSucceeds();
858 Run(2); // SpdySession consumes the next two reads and sends then to
859 // sock_ to be buffered.
860 AssertSyncReadEquals(kMsg1, kLen1);
861 // The payload from the single large data frame will be read across
862 // two different reads.
863 AssertSyncReadEquals(kMsg3, kLen3);
864 AssertSyncReadEquals(kMsg3, kLen3);
867 TEST_P(SpdyProxyClientSocketTest, MultipleReadsFromSameLargeFrame) {
868 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
869 MockWrite writes[] = {
870 CreateMockWrite(*conn, 0, SYNCHRONOUS),
873 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
874 scoped_ptr<SpdyFrame> msg333(ConstructBodyFrame(kMsg333, kLen333));
875 MockRead reads[] = {
876 CreateMockRead(*resp, 1, ASYNC),
877 CreateMockRead(*msg333, 2, ASYNC),
878 MockRead(ASYNC, 0, 3), // EOF
881 Initialize(reads, arraysize(reads), writes, arraysize(writes));
883 AssertConnectSucceeds();
885 Run(1); // SpdySession consumes the next read and sends it to
886 // sock_ to be buffered.
887 // The payload from the single large data frame will be read across
888 // two different reads.
889 AssertSyncReadEquals(kMsg33, kLen33);
891 // Now attempt to do a read of more data than remains buffered
892 scoped_refptr<IOBuffer> buf(new IOBuffer(kLen33));
893 ASSERT_EQ(kLen3, sock_->Read(buf.get(), kLen33, read_callback_.callback()));
894 ASSERT_EQ(std::string(kMsg3, kLen3), std::string(buf->data(), kLen3));
895 ASSERT_TRUE(sock_->IsConnected());
898 TEST_P(SpdyProxyClientSocketTest, ReadAuthResponseBody) {
899 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
900 MockWrite writes[] = {
901 CreateMockWrite(*conn, 0, SYNCHRONOUS),
904 scoped_ptr<SpdyFrame> resp(ConstructConnectAuthReplyFrame());
905 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
906 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
907 MockRead reads[] = {
908 CreateMockRead(*resp, 1, ASYNC),
909 CreateMockRead(*msg1, 2, ASYNC),
910 CreateMockRead(*msg2, 3, ASYNC),
911 MockRead(ASYNC, 0, 4), // EOF
914 Initialize(reads, arraysize(reads), writes, arraysize(writes));
916 AssertConnectFails(ERR_PROXY_AUTH_REQUESTED);
918 Run(2); // SpdySession consumes the next two reads and sends then to
919 // sock_ to be buffered.
920 AssertSyncReadEquals(kMsg1, kLen1);
921 AssertSyncReadEquals(kMsg2, kLen2);
924 TEST_P(SpdyProxyClientSocketTest, ReadErrorResponseBody) {
925 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
926 MockWrite writes[] = {
927 CreateMockWrite(*conn, 0, SYNCHRONOUS),
930 scoped_ptr<SpdyFrame> resp(ConstructConnectErrorReplyFrame());
931 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
932 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
933 MockRead reads[] = {
934 CreateMockRead(*resp, 1, ASYNC),
935 CreateMockRead(*msg1, 2, ASYNC),
936 CreateMockRead(*msg2, 3, ASYNC),
937 MockRead(ASYNC, 0, 4), // EOF
940 Initialize(reads, arraysize(reads), writes, arraysize(writes));
942 AssertConnectFails(ERR_TUNNEL_CONNECTION_FAILED);
945 // ----------- Reads and Writes
947 TEST_P(SpdyProxyClientSocketTest, AsyncReadAroundWrite) {
948 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
949 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
950 MockWrite writes[] = {
951 CreateMockWrite(*conn, 0, SYNCHRONOUS),
952 CreateMockWrite(*msg2, 3, SYNCHRONOUS),
955 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
956 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
957 scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
958 MockRead reads[] = {
959 CreateMockRead(*resp, 1, ASYNC),
960 CreateMockRead(*msg1, 2, ASYNC), // sync read
961 CreateMockRead(*msg3, 4, ASYNC), // async read
962 MockRead(ASYNC, 0, 5), // EOF
965 Initialize(reads, arraysize(reads), writes, arraysize(writes));
967 AssertConnectSucceeds();
969 Run(1);
970 AssertSyncReadEquals(kMsg1, kLen1);
972 AssertReadStarts(kMsg3, kLen3);
973 // Read should block until after the write succeeds
975 AssertAsyncWriteSucceeds(kMsg2, kLen2); // Runs 1 step
977 ASSERT_FALSE(read_callback_.have_result());
978 Run(1);
979 // Now the read will return
980 AssertReadReturns(kMsg3, kLen3);
983 TEST_P(SpdyProxyClientSocketTest, AsyncWriteAroundReads) {
984 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
985 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
986 MockWrite writes[] = {
987 CreateMockWrite(*conn, 0, SYNCHRONOUS),
988 CreateMockWrite(*msg2, 4, ASYNC),
991 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
992 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
993 scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
994 MockRead reads[] = {
995 CreateMockRead(*resp, 1, ASYNC),
996 CreateMockRead(*msg1, 2, ASYNC),
997 CreateMockRead(*msg3, 3, ASYNC),
998 MockRead(ASYNC, 0, 5), // EOF
1001 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1003 AssertConnectSucceeds();
1005 Run(1);
1006 AssertSyncReadEquals(kMsg1, kLen1);
1007 // Write should block until the read completes
1008 AssertWriteReturns(kMsg2, kLen2, ERR_IO_PENDING);
1010 AssertAsyncReadEquals(kMsg3, kLen3);
1012 ASSERT_FALSE(write_callback_.have_result());
1014 // Now the write will complete
1015 Run(1);
1016 AssertWriteLength(kLen2);
1019 // ----------- Reading/Writing on Closed socket
1021 // Reading from an already closed socket should return 0
1022 TEST_P(SpdyProxyClientSocketTest, ReadOnClosedSocketReturnsZero) {
1023 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1024 MockWrite writes[] = {
1025 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1028 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1029 MockRead reads[] = {
1030 CreateMockRead(*resp, 1, ASYNC),
1031 MockRead(ASYNC, 0, 2), // EOF
1034 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1036 AssertConnectSucceeds();
1038 Run(1);
1040 ASSERT_FALSE(sock_->IsConnected());
1041 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
1042 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
1043 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
1044 ASSERT_FALSE(sock_->IsConnectedAndIdle());
1047 // Read pending when socket is closed should return 0
1048 TEST_P(SpdyProxyClientSocketTest, PendingReadOnCloseReturnsZero) {
1049 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1050 MockWrite writes[] = {
1051 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1054 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1055 MockRead reads[] = {
1056 CreateMockRead(*resp, 1, ASYNC),
1057 MockRead(ASYNC, 0, 2), // EOF
1060 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1062 AssertConnectSucceeds();
1064 AssertReadStarts(kMsg1, kLen1);
1066 Run(1);
1068 ASSERT_EQ(0, read_callback_.WaitForResult());
1071 // Reading from a disconnected socket is an error
1072 TEST_P(SpdyProxyClientSocketTest,
1073 ReadOnDisconnectSocketReturnsNotConnected) {
1074 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1075 MockWrite writes[] = {
1076 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1079 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1080 MockRead reads[] = {
1081 CreateMockRead(*resp, 1, ASYNC),
1082 MockRead(ASYNC, 0, 2), // EOF
1085 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1087 AssertConnectSucceeds();
1089 sock_->Disconnect();
1091 ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED,
1092 sock_->Read(NULL, 1, CompletionCallback()));
1095 // Reading buffered data from an already closed socket should return
1096 // buffered data, then 0.
1097 TEST_P(SpdyProxyClientSocketTest, ReadOnClosedSocketReturnsBufferedData) {
1098 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1099 MockWrite writes[] = {
1100 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1103 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1104 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
1105 MockRead reads[] = {
1106 CreateMockRead(*resp, 1, ASYNC),
1107 CreateMockRead(*msg1, 2, ASYNC),
1108 MockRead(ASYNC, 0, 3), // EOF
1111 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1113 AssertConnectSucceeds();
1115 Run(2);
1117 ASSERT_FALSE(sock_->IsConnected());
1118 scoped_refptr<IOBuffer> buf(new IOBuffer(kLen1));
1119 ASSERT_EQ(kLen1, sock_->Read(buf.get(), kLen1, CompletionCallback()));
1120 ASSERT_EQ(std::string(kMsg1, kLen1), std::string(buf->data(), kLen1));
1122 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
1123 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
1124 sock_->Disconnect();
1125 ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED,
1126 sock_->Read(NULL, 1, CompletionCallback()));
1129 // Calling Write() on a closed socket is an error
1130 TEST_P(SpdyProxyClientSocketTest, WriteOnClosedStream) {
1131 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1132 MockWrite writes[] = {
1133 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1136 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1137 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
1138 MockRead reads[] = {
1139 CreateMockRead(*resp, 1, ASYNC),
1140 MockRead(ASYNC, 0, 2), // EOF
1143 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1145 AssertConnectSucceeds();
1147 Run(1); // Read EOF which will close the stream
1148 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
1149 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED,
1150 sock_->Write(buf.get(), buf->size(), CompletionCallback()));
1153 // Calling Write() on a disconnected socket is an error
1154 TEST_P(SpdyProxyClientSocketTest, WriteOnDisconnectedSocket) {
1155 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1156 MockWrite writes[] = {
1157 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1160 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1161 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
1162 MockRead reads[] = {
1163 CreateMockRead(*resp, 1, ASYNC),
1164 MockRead(ASYNC, 0, 2), // EOF
1167 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1169 AssertConnectSucceeds();
1171 sock_->Disconnect();
1173 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
1174 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED,
1175 sock_->Write(buf.get(), buf->size(), CompletionCallback()));
1178 // If the socket is closed with a pending Write(), the callback
1179 // should be called with ERR_CONNECTION_CLOSED.
1180 TEST_P(SpdyProxyClientSocketTest, WritePendingOnClose) {
1181 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1182 MockWrite writes[] = {
1183 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1184 MockWrite(ASYNC, ERR_ABORTED, 2),
1187 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1188 MockRead reads[] = {
1189 CreateMockRead(*resp, 1, ASYNC),
1190 MockRead(ASYNC, 0, 3), // EOF
1193 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1195 AssertConnectSucceeds();
1197 EXPECT_TRUE(sock_->IsConnected());
1199 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
1200 EXPECT_EQ(ERR_IO_PENDING,
1201 sock_->Write(buf.get(), buf->size(), write_callback_.callback()));
1203 CloseSpdySession(ERR_ABORTED, std::string());
1205 EXPECT_EQ(ERR_CONNECTION_CLOSED, write_callback_.WaitForResult());
1208 // If the socket is Disconnected with a pending Write(), the callback
1209 // should not be called.
1210 TEST_P(SpdyProxyClientSocketTest, DisconnectWithWritePending) {
1211 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1212 MockWrite writes[] = {
1213 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1214 MockWrite(SYNCHRONOUS, 0, 2), // EOF
1217 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1218 MockRead reads[] = {
1219 CreateMockRead(*resp, 1, ASYNC),
1220 MockRead(ASYNC, 0, 3), // EOF
1223 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1225 AssertConnectSucceeds();
1227 EXPECT_TRUE(sock_->IsConnected());
1229 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
1230 EXPECT_EQ(ERR_IO_PENDING,
1231 sock_->Write(buf.get(), buf->size(), write_callback_.callback()));
1233 sock_->Disconnect();
1235 EXPECT_FALSE(sock_->IsConnected());
1236 EXPECT_FALSE(write_callback_.have_result());
1239 // If the socket is Disconnected with a pending Read(), the callback
1240 // should not be called.
1241 TEST_P(SpdyProxyClientSocketTest, DisconnectWithReadPending) {
1242 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1243 MockWrite writes[] = {
1244 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1247 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1248 MockRead reads[] = {
1249 CreateMockRead(*resp, 1, ASYNC),
1250 MockRead(ASYNC, 0, 2), // EOF
1253 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1255 AssertConnectSucceeds();
1257 EXPECT_TRUE(sock_->IsConnected());
1259 scoped_refptr<IOBuffer> buf(new IOBuffer(kLen1));
1260 ASSERT_EQ(ERR_IO_PENDING,
1261 sock_->Read(buf.get(), kLen1, read_callback_.callback()));
1263 sock_->Disconnect();
1265 EXPECT_FALSE(sock_->IsConnected());
1266 EXPECT_FALSE(read_callback_.have_result());
1269 // If the socket is Reset when both a read and write are pending,
1270 // both should be called back.
1271 TEST_P(SpdyProxyClientSocketTest, RstWithReadAndWritePending) {
1272 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1273 MockWrite writes[] = {
1274 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1275 MockWrite(ASYNC, ERR_ABORTED, 3),
1278 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1279 scoped_ptr<SpdyFrame> rst(
1280 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
1281 MockRead reads[] = {
1282 CreateMockRead(*resp, 1, ASYNC),
1283 CreateMockRead(*rst, 2, ASYNC),
1284 MockRead(ASYNC, 0, 4) // EOF
1287 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1289 AssertConnectSucceeds();
1291 EXPECT_TRUE(sock_->IsConnected());
1293 scoped_refptr<IOBuffer> read_buf(new IOBuffer(kLen1));
1294 ASSERT_EQ(ERR_IO_PENDING,
1295 sock_->Read(read_buf.get(), kLen1, read_callback_.callback()));
1297 scoped_refptr<IOBufferWithSize> write_buf(CreateBuffer(kMsg1, kLen1));
1298 EXPECT_EQ(
1299 ERR_IO_PENDING,
1300 sock_->Write(
1301 write_buf.get(), write_buf->size(), write_callback_.callback()));
1303 Run(2);
1305 EXPECT_TRUE(sock_.get());
1306 EXPECT_TRUE(read_callback_.have_result());
1307 EXPECT_TRUE(write_callback_.have_result());
1310 // Makes sure the proxy client socket's source gets the expected NetLog events
1311 // and only the expected NetLog events (No SpdySession events).
1312 TEST_P(SpdyProxyClientSocketTest, NetLog) {
1313 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1314 MockWrite writes[] = {
1315 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1318 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1319 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
1320 MockRead reads[] = {
1321 CreateMockRead(*resp, 1, ASYNC),
1322 CreateMockRead(*msg1, 2, ASYNC),
1323 MockRead(ASYNC, 0, 3), // EOF
1326 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1328 AssertConnectSucceeds();
1330 Run(1); // SpdySession consumes the next read and sends it to
1331 // sock_ to be buffered.
1332 AssertSyncReadEquals(kMsg1, kLen1);
1334 NetLog::Source sock_source = sock_->NetLog().source();
1335 sock_.reset();
1337 CapturingNetLog::CapturedEntryList entry_list;
1338 net_log_.GetEntriesForSource(sock_source, &entry_list);
1340 ASSERT_EQ(entry_list.size(), 10u);
1341 EXPECT_TRUE(LogContainsBeginEvent(entry_list, 0, NetLog::TYPE_SOCKET_ALIVE));
1342 EXPECT_TRUE(LogContainsEvent(entry_list, 1,
1343 NetLog::TYPE_SPDY_PROXY_CLIENT_SESSION,
1344 NetLog::PHASE_NONE));
1345 EXPECT_TRUE(LogContainsBeginEvent(entry_list, 2,
1346 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_SEND_REQUEST));
1347 EXPECT_TRUE(LogContainsEvent(entry_list, 3,
1348 NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
1349 NetLog::PHASE_NONE));
1350 EXPECT_TRUE(LogContainsEndEvent(entry_list, 4,
1351 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_SEND_REQUEST));
1352 EXPECT_TRUE(LogContainsBeginEvent(entry_list, 5,
1353 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_READ_HEADERS));
1354 EXPECT_TRUE(LogContainsEvent(entry_list, 6,
1355 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
1356 NetLog::PHASE_NONE));
1357 EXPECT_TRUE(LogContainsEndEvent(entry_list, 7,
1358 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_READ_HEADERS));
1359 EXPECT_TRUE(LogContainsEvent(entry_list, 8,
1360 NetLog::TYPE_SOCKET_BYTES_RECEIVED,
1361 NetLog::PHASE_NONE));
1362 EXPECT_TRUE(LogContainsEndEvent(entry_list, 9, NetLog::TYPE_SOCKET_ALIVE));
1365 // CompletionCallback that causes the SpdyProxyClientSocket to be
1366 // deleted when Run is invoked.
1367 class DeleteSockCallback : public TestCompletionCallbackBase {
1368 public:
1369 explicit DeleteSockCallback(scoped_ptr<SpdyProxyClientSocket>* sock)
1370 : sock_(sock),
1371 callback_(base::Bind(&DeleteSockCallback::OnComplete,
1372 base::Unretained(this))) {
1375 virtual ~DeleteSockCallback() {
1378 const CompletionCallback& callback() const { return callback_; }
1380 private:
1381 void OnComplete(int result) {
1382 sock_->reset(NULL);
1383 SetResult(result);
1386 scoped_ptr<SpdyProxyClientSocket>* sock_;
1387 CompletionCallback callback_;
1389 DISALLOW_COPY_AND_ASSIGN(DeleteSockCallback);
1392 // If the socket is Reset when both a read and write are pending, and the
1393 // read callback causes the socket to be deleted, the write callback should
1394 // not be called.
1395 TEST_P(SpdyProxyClientSocketTest, RstWithReadAndWritePendingDelete) {
1396 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1397 MockWrite writes[] = {
1398 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1399 MockWrite(ASYNC, ERR_ABORTED, 3),
1402 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1403 scoped_ptr<SpdyFrame> rst(
1404 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
1405 MockRead reads[] = {
1406 CreateMockRead(*resp, 1, ASYNC),
1407 CreateMockRead(*rst, 2, ASYNC),
1408 MockRead(ASYNC, 0, 4), // EOF
1411 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1413 AssertConnectSucceeds();
1415 EXPECT_TRUE(sock_->IsConnected());
1417 DeleteSockCallback read_callback(&sock_);
1419 scoped_refptr<IOBuffer> read_buf(new IOBuffer(kLen1));
1420 ASSERT_EQ(ERR_IO_PENDING,
1421 sock_->Read(read_buf.get(), kLen1, read_callback.callback()));
1423 scoped_refptr<IOBufferWithSize> write_buf(CreateBuffer(kMsg1, kLen1));
1424 EXPECT_EQ(
1425 ERR_IO_PENDING,
1426 sock_->Write(
1427 write_buf.get(), write_buf->size(), write_callback_.callback()));
1429 Run(1);
1431 EXPECT_FALSE(sock_.get());
1432 EXPECT_TRUE(read_callback.have_result());
1433 EXPECT_FALSE(write_callback_.have_result());
1436 } // namespace net