Make certificate viewer a tab-modal dialog.
[chromium-blink-merge.git] / net / spdy / spdy_proxy_client_socket_spdy3_unittest.cc
blob84a45814d5916162e6b63f386dd5a7f43c66f0fe
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/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/socket_test_util.h"
21 #include "net/socket/tcp_client_socket.h"
22 #include "net/spdy/buffered_spdy_framer.h"
23 #include "net/spdy/spdy_http_utils.h"
24 #include "net/spdy/spdy_protocol.h"
25 #include "net/spdy/spdy_session_pool.h"
26 #include "net/spdy/spdy_test_util_common.h"
27 #include "net/spdy/spdy_test_util_spdy3.h"
28 #include "testing/gtest/include/gtest/gtest.h"
29 #include "testing/platform_test.h"
31 using namespace net::test_spdy3;
33 //-----------------------------------------------------------------------------
35 namespace {
37 static const char kRequestUrl[] = "https://www.google.com/";
38 static const char kOriginHost[] = "www.google.com";
39 static const int kOriginPort = 443;
40 static const char kOriginHostPort[] = "www.google.com:443";
41 static const char kProxyUrl[] = "https://myproxy:6121/";
42 static const char kProxyHost[] = "myproxy";
43 static const int kProxyPort = 6121;
44 static const char kUserAgent[] = "Mozilla/1.0";
46 static const int kStreamId = 1;
48 static const char kMsg1[] = "\0hello!\xff";
49 static const int kLen1 = 8;
50 static const char kMsg2[] = "\00012345678\0";
51 static const int kLen2 = 10;
52 static const char kMsg3[] = "bye!";
53 static const int kLen3 = 4;
54 static const char kMsg33[] = "bye!bye!";
55 static const int kLen33 = kLen3 + kLen3;
56 static const char kMsg333[] = "bye!bye!bye!";
57 static const int kLen333 = kLen3 + kLen3 + kLen3;
59 static const char kRedirectUrl[] = "https://example.com/";
61 } // anonymous namespace
63 namespace net {
65 class SpdyProxyClientSocketSpdy3Test : public PlatformTest {
66 public:
67 SpdyProxyClientSocketSpdy3Test();
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(ASCIIToUTF16("foo"));
97 const base::string16 kBar(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 scoped_ptr<SpdyProxyClientSocket> sock_;
112 TestCompletionCallback read_callback_;
113 TestCompletionCallback write_callback_;
114 scoped_ptr<DeterministicSocketData> data_;
115 CapturingBoundNetLog net_log_;
117 private:
118 scoped_refptr<HttpNetworkSession> session_;
119 scoped_refptr<IOBuffer> read_buf_;
120 SpdySessionDependencies session_deps_;
121 MockConnect connect_data_;
122 scoped_refptr<SpdySession> spdy_session_;
123 scoped_refptr<SpdyStream> spdy_stream_;
124 BufferedSpdyFramer framer_;
126 std::string user_agent_;
127 GURL url_;
128 HostPortPair proxy_host_port_;
129 HostPortPair endpoint_host_port_pair_;
130 ProxyServer proxy_;
131 HostPortProxyPair endpoint_host_port_proxy_pair_;
132 scoped_refptr<TransportSocketParams> transport_params_;
134 DISALLOW_COPY_AND_ASSIGN(SpdyProxyClientSocketSpdy3Test);
137 SpdyProxyClientSocketSpdy3Test::SpdyProxyClientSocketSpdy3Test()
138 : sock_(NULL),
139 data_(NULL),
140 session_(NULL),
141 read_buf_(NULL),
142 session_deps_(),
143 connect_data_(SYNCHRONOUS, OK),
144 spdy_session_(NULL),
145 spdy_stream_(NULL),
146 framer_(3, false),
147 user_agent_(kUserAgent),
148 url_(kRequestUrl),
149 proxy_host_port_(kProxyHost, kProxyPort),
150 endpoint_host_port_pair_(kOriginHost, kOriginPort),
151 proxy_(ProxyServer::SCHEME_HTTPS, proxy_host_port_),
152 endpoint_host_port_proxy_pair_(endpoint_host_port_pair_, proxy_),
153 transport_params_(new TransportSocketParams(proxy_host_port_,
154 LOWEST,
155 false,
156 false,
157 OnHostResolutionCallback())) {
158 session_deps_.net_log = net_log_.bound().net_log();
161 void SpdyProxyClientSocketSpdy3Test::TearDown() {
162 sock_.reset(NULL);
163 if (session_ != NULL)
164 session_->spdy_session_pool()->CloseAllSessions();
166 // Empty the current queue.
167 MessageLoop::current()->RunUntilIdle();
168 PlatformTest::TearDown();
171 void SpdyProxyClientSocketSpdy3Test::Initialize(MockRead* reads,
172 size_t reads_count,
173 MockWrite* writes,
174 size_t writes_count) {
175 data_.reset(new DeterministicSocketData(reads, reads_count,
176 writes, writes_count));
177 data_->set_connect_data(connect_data_);
178 data_->SetStop(2);
180 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
181 data_.get());
182 session_deps_.host_resolver->set_synchronous_mode(true);
184 session_ = SpdySessionDependencies::SpdyCreateSessionDeterministic(
185 &session_deps_);
187 // Creates a new spdy session.
188 spdy_session_ =
189 session_->spdy_session_pool()->Get(endpoint_host_port_proxy_pair_,
190 net_log_.bound());
192 // Perform the TCP connect.
193 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
194 EXPECT_EQ(OK,
195 connection->Init(endpoint_host_port_pair_.ToString(),
196 transport_params_, LOWEST, CompletionCallback(),
197 session_->GetTransportSocketPool(
198 HttpNetworkSession::NORMAL_SOCKET_POOL),
199 net_log_.bound()));
200 spdy_session_->InitializeWithSocket(connection.release(), false, OK);
202 // Create the SPDY Stream.
203 spdy_stream_ =
204 CreateStreamSynchronously(spdy_session_, url_, LOWEST, net_log_.bound());
205 ASSERT_TRUE(spdy_stream_.get() != NULL);
207 // Create the SpdyProxyClientSocket.
208 sock_.reset(
209 new SpdyProxyClientSocket(spdy_stream_, user_agent_,
210 endpoint_host_port_pair_, url_,
211 proxy_host_port_, net_log_.bound(),
212 session_->http_auth_cache(),
213 session_->http_auth_handler_factory()));
216 scoped_refptr<IOBufferWithSize> SpdyProxyClientSocketSpdy3Test::CreateBuffer(
217 const char* data, int size) {
218 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(size));
219 memcpy(buf->data(), data, size);
220 return buf;
223 void SpdyProxyClientSocketSpdy3Test::AssertConnectSucceeds() {
224 ASSERT_EQ(ERR_IO_PENDING, sock_->Connect(read_callback_.callback()));
225 data_->Run();
226 ASSERT_EQ(OK, read_callback_.WaitForResult());
229 void SpdyProxyClientSocketSpdy3Test::AssertConnectFails(int result) {
230 ASSERT_EQ(ERR_IO_PENDING, sock_->Connect(read_callback_.callback()));
231 data_->Run();
232 ASSERT_EQ(result, read_callback_.WaitForResult());
235 void SpdyProxyClientSocketSpdy3Test::AssertConnectionEstablished() {
236 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
237 ASSERT_TRUE(response != NULL);
238 ASSERT_EQ(200, response->headers->response_code());
239 ASSERT_EQ("Connection Established", response->headers->GetStatusText());
242 void SpdyProxyClientSocketSpdy3Test::AssertSyncReadEquals(const char* data,
243 int len) {
244 scoped_refptr<IOBuffer> buf(new IOBuffer(len));
245 ASSERT_EQ(len, sock_->Read(buf, len, CompletionCallback()));
246 ASSERT_EQ(std::string(data, len), std::string(buf->data(), len));
247 ASSERT_TRUE(sock_->IsConnected());
250 void SpdyProxyClientSocketSpdy3Test::AssertAsyncReadEquals(const char* data,
251 int len) {
252 data_->StopAfter(1);
253 // Issue the read, which will be completed asynchronously
254 scoped_refptr<IOBuffer> buf(new IOBuffer(len));
255 ASSERT_EQ(ERR_IO_PENDING, sock_->Read(buf, len, read_callback_.callback()));
256 EXPECT_TRUE(sock_->IsConnected());
257 data_->Run();
259 EXPECT_TRUE(sock_->IsConnected());
261 // Now the read will return
262 EXPECT_EQ(len, read_callback_.WaitForResult());
263 ASSERT_EQ(std::string(data, len), std::string(buf->data(), len));
266 void SpdyProxyClientSocketSpdy3Test::AssertReadStarts(const char* data,
267 int len) {
268 data_->StopAfter(1);
269 // Issue the read, which will be completed asynchronously
270 read_buf_ = new IOBuffer(len);
271 ASSERT_EQ(ERR_IO_PENDING,
272 sock_->Read(read_buf_, len, read_callback_.callback()));
273 EXPECT_TRUE(sock_->IsConnected());
276 void SpdyProxyClientSocketSpdy3Test::AssertReadReturns(const char* data,
277 int len) {
278 EXPECT_TRUE(sock_->IsConnected());
280 // Now the read will return
281 EXPECT_EQ(len, read_callback_.WaitForResult());
282 ASSERT_EQ(std::string(data, len), std::string(read_buf_->data(), len));
285 void SpdyProxyClientSocketSpdy3Test::AssertAsyncWriteSucceeds(const char* data,
286 int len) {
287 AssertWriteReturns(data, len, ERR_IO_PENDING);
288 data_->RunFor(1);
289 AssertWriteLength(len);
292 void SpdyProxyClientSocketSpdy3Test::AssertWriteReturns(const char* data,
293 int len,
294 int rv) {
295 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(data, len));
296 EXPECT_EQ(rv, sock_->Write(buf, buf->size(), write_callback_.callback()));
299 void SpdyProxyClientSocketSpdy3Test::AssertWriteLength(int len) {
300 EXPECT_EQ(len, write_callback_.WaitForResult());
303 void SpdyProxyClientSocketSpdy3Test::AssertAsyncWriteWithReadsSucceeds(
304 const char* data, int len, int num_reads) {
305 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(data, len));
307 EXPECT_EQ(ERR_IO_PENDING, sock_->Write(buf, buf->size(),
308 write_callback_.callback()));
310 for (int i = 0; i < num_reads; i++) {
311 Run(1);
312 AssertSyncReadEquals(kMsg2, kLen2);
315 write_callback_.WaitForResult();
318 // Constructs a standard SPDY SYN_STREAM frame for a CONNECT request.
319 SpdyFrame*
320 SpdyProxyClientSocketSpdy3Test::ConstructConnectRequestFrame() {
321 const SpdyHeaderInfo kSynStartHeader = {
322 SYN_STREAM,
323 kStreamId,
325 net::ConvertRequestPriorityToSpdyPriority(LOWEST, 3),
327 CONTROL_FLAG_NONE,
328 false,
329 RST_STREAM_INVALID,
330 NULL,
332 DATA_FLAG_NONE
334 const char* const kConnectHeaders[] = {
335 ":method", "CONNECT",
336 ":path", kOriginHostPort,
337 ":host", kOriginHost,
338 "user-agent", kUserAgent,
339 ":version", "HTTP/1.1",
341 return ConstructSpdyFrame(
342 kSynStartHeader, NULL, 0, kConnectHeaders, arraysize(kConnectHeaders)/2);
345 // Constructs a SPDY SYN_STREAM frame for a CONNECT request which includes
346 // Proxy-Authorization headers.
347 SpdyFrame*
348 SpdyProxyClientSocketSpdy3Test::ConstructConnectAuthRequestFrame() {
349 const SpdyHeaderInfo kSynStartHeader = {
350 SYN_STREAM,
351 kStreamId,
353 net::ConvertRequestPriorityToSpdyPriority(LOWEST, 3),
355 CONTROL_FLAG_NONE,
356 false,
357 RST_STREAM_INVALID,
358 NULL,
360 DATA_FLAG_NONE
362 const char* const kConnectHeaders[] = {
363 ":method", "CONNECT",
364 ":path", kOriginHostPort,
365 ":host", kOriginHost,
366 "user-agent", kUserAgent,
367 ":version", "HTTP/1.1",
368 "proxy-authorization", "Basic Zm9vOmJhcg==",
370 return ConstructSpdyFrame(
371 kSynStartHeader, NULL, 0, kConnectHeaders, arraysize(kConnectHeaders)/2);
374 // Constructs a standard SPDY SYN_REPLY frame to match the SPDY CONNECT.
375 SpdyFrame* SpdyProxyClientSocketSpdy3Test::ConstructConnectReplyFrame() {
376 const char* const kStandardReplyHeaders[] = {
377 ":status", "200 Connection Established",
378 ":version", "HTTP/1.1"
380 return ConstructSpdyControlFrame(NULL,
382 false,
383 kStreamId,
384 LOWEST,
385 SYN_REPLY,
386 CONTROL_FLAG_NONE,
387 kStandardReplyHeaders,
388 arraysize(kStandardReplyHeaders));
391 // Constructs a standard SPDY SYN_REPLY frame to match the SPDY CONNECT.
392 SpdyFrame*
393 SpdyProxyClientSocketSpdy3Test::ConstructConnectAuthReplyFrame() {
394 const char* const kStandardReplyHeaders[] = {
395 ":status", "407 Proxy Authentication Required",
396 ":version", "HTTP/1.1",
397 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
400 return ConstructSpdyControlFrame(NULL,
402 false,
403 kStreamId,
404 LOWEST,
405 SYN_REPLY,
406 CONTROL_FLAG_NONE,
407 kStandardReplyHeaders,
408 arraysize(kStandardReplyHeaders));
411 // Constructs a SPDY SYN_REPLY frame with an HTTP 302 redirect.
412 SpdyFrame*
413 SpdyProxyClientSocketSpdy3Test::ConstructConnectRedirectReplyFrame() {
414 const char* const kStandardReplyHeaders[] = {
415 ":status", "302 Found",
416 ":version", "HTTP/1.1",
417 "location", kRedirectUrl,
418 "set-cookie", "foo=bar"
421 return ConstructSpdyControlFrame(NULL,
423 false,
424 kStreamId,
425 LOWEST,
426 SYN_REPLY,
427 CONTROL_FLAG_NONE,
428 kStandardReplyHeaders,
429 arraysize(kStandardReplyHeaders));
432 // Constructs a SPDY SYN_REPLY frame with an HTTP 500 error.
433 SpdyFrame*
434 SpdyProxyClientSocketSpdy3Test::ConstructConnectErrorReplyFrame() {
435 const char* const kStandardReplyHeaders[] = {
436 ":status", "500 Internal Server Error",
437 ":version", "HTTP/1.1",
440 return ConstructSpdyControlFrame(NULL,
442 false,
443 kStreamId,
444 LOWEST,
445 SYN_REPLY,
446 CONTROL_FLAG_NONE,
447 kStandardReplyHeaders,
448 arraysize(kStandardReplyHeaders));
451 SpdyFrame* SpdyProxyClientSocketSpdy3Test::ConstructBodyFrame(
452 const char* data,
453 int length) {
454 return framer_.CreateDataFrame(kStreamId, data, length, DATA_FLAG_NONE);
457 // ----------- Connect
459 TEST_F(SpdyProxyClientSocketSpdy3Test, ConnectSendsCorrectRequest) {
460 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
461 MockWrite writes[] = {
462 CreateMockWrite(*conn, 0, SYNCHRONOUS),
465 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
466 MockRead reads[] = {
467 CreateMockRead(*resp, 1, ASYNC),
468 MockRead(ASYNC, 0, 2), // EOF
471 Initialize(reads, arraysize(reads), writes, arraysize(writes));
473 ASSERT_FALSE(sock_->IsConnected());
475 AssertConnectSucceeds();
477 AssertConnectionEstablished();
480 TEST_F(SpdyProxyClientSocketSpdy3Test, ConnectWithAuthRequested) {
481 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
482 MockWrite writes[] = {
483 CreateMockWrite(*conn, 0, SYNCHRONOUS),
486 scoped_ptr<SpdyFrame> resp(ConstructConnectAuthReplyFrame());
487 MockRead reads[] = {
488 CreateMockRead(*resp, 1, ASYNC),
489 MockRead(ASYNC, 0, 2), // EOF
492 Initialize(reads, arraysize(reads), writes, arraysize(writes));
494 AssertConnectFails(ERR_PROXY_AUTH_REQUESTED);
496 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
497 ASSERT_TRUE(response != NULL);
498 ASSERT_EQ(407, response->headers->response_code());
499 ASSERT_EQ("Proxy Authentication Required",
500 response->headers->GetStatusText());
503 TEST_F(SpdyProxyClientSocketSpdy3Test, ConnectWithAuthCredentials) {
504 scoped_ptr<SpdyFrame> conn(ConstructConnectAuthRequestFrame());
505 MockWrite writes[] = {
506 CreateMockWrite(*conn, 0, SYNCHRONOUS),
509 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
510 MockRead reads[] = {
511 CreateMockRead(*resp, 1, ASYNC),
512 MockRead(ASYNC, 0, 2), // EOF
515 Initialize(reads, arraysize(reads), writes, arraysize(writes));
516 AddAuthToCache();
518 AssertConnectSucceeds();
520 AssertConnectionEstablished();
523 TEST_F(SpdyProxyClientSocketSpdy3Test, ConnectRedirects) {
524 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
525 MockWrite writes[] = {
526 CreateMockWrite(*conn, 0, SYNCHRONOUS),
529 scoped_ptr<SpdyFrame> resp(ConstructConnectRedirectReplyFrame());
530 MockRead reads[] = {
531 CreateMockRead(*resp, 1, ASYNC),
532 MockRead(ASYNC, 0, 2), // EOF
535 Initialize(reads, arraysize(reads), writes, arraysize(writes));
537 AssertConnectFails(ERR_HTTPS_PROXY_TUNNEL_RESPONSE);
539 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
540 ASSERT_TRUE(response != NULL);
542 const HttpResponseHeaders* headers = response->headers;
543 ASSERT_EQ(302, headers->response_code());
544 ASSERT_FALSE(headers->HasHeader("set-cookie"));
545 ASSERT_TRUE(headers->HasHeaderValue("content-length", "0"));
547 std::string location;
548 ASSERT_TRUE(headers->IsRedirect(&location));
549 ASSERT_EQ(location, kRedirectUrl);
552 TEST_F(SpdyProxyClientSocketSpdy3Test, ConnectFails) {
553 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
554 MockWrite writes[] = {
555 CreateMockWrite(*conn, 0, SYNCHRONOUS),
558 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
559 MockRead reads[] = {
560 MockRead(ASYNC, 0, 1), // EOF
563 Initialize(reads, arraysize(reads), writes, arraysize(writes));
565 ASSERT_FALSE(sock_->IsConnected());
567 AssertConnectFails(ERR_CONNECTION_CLOSED);
569 ASSERT_FALSE(sock_->IsConnected());
572 // ----------- WasEverUsed
574 TEST_F(SpdyProxyClientSocketSpdy3Test, WasEverUsedReturnsCorrectValues) {
575 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
576 MockWrite writes[] = {
577 CreateMockWrite(*conn, 0, SYNCHRONOUS),
580 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
581 MockRead reads[] = {
582 CreateMockRead(*resp, 1, ASYNC),
583 MockRead(ASYNC, 0, 2), // EOF
586 Initialize(reads, arraysize(reads), writes, arraysize(writes));
588 EXPECT_FALSE(sock_->WasEverUsed());
589 AssertConnectSucceeds();
590 EXPECT_TRUE(sock_->WasEverUsed());
591 sock_->Disconnect();
592 EXPECT_TRUE(sock_->WasEverUsed());
595 // ----------- GetPeerAddress
597 TEST_F(SpdyProxyClientSocketSpdy3Test, GetPeerAddressReturnsCorrectValues) {
598 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
599 MockWrite writes[] = {
600 CreateMockWrite(*conn, 0, SYNCHRONOUS),
603 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
604 MockRead reads[] = {
605 CreateMockRead(*resp, 1, ASYNC),
606 MockRead(ASYNC, 0, 2), // EOF
609 Initialize(reads, arraysize(reads), writes, arraysize(writes));
611 net::IPEndPoint addr;
612 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr));
614 AssertConnectSucceeds();
615 EXPECT_TRUE(sock_->IsConnected());
616 EXPECT_EQ(OK, sock_->GetPeerAddress(&addr));
618 Run(1);
620 EXPECT_FALSE(sock_->IsConnected());
621 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr));
623 sock_->Disconnect();
625 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr));
628 // ----------- Write
630 TEST_F(SpdyProxyClientSocketSpdy3Test, WriteSendsDataInDataFrame) {
631 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
632 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
633 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
634 MockWrite writes[] = {
635 CreateMockWrite(*conn, 0, SYNCHRONOUS),
636 CreateMockWrite(*msg1, 2, SYNCHRONOUS),
637 CreateMockWrite(*msg2, 3, SYNCHRONOUS),
640 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
641 MockRead reads[] = {
642 CreateMockRead(*resp, 1, ASYNC),
643 MockRead(ASYNC, 0, 4), // EOF
646 Initialize(reads, arraysize(reads), writes, arraysize(writes));
648 AssertConnectSucceeds();
650 AssertAsyncWriteSucceeds(kMsg1, kLen1);
651 AssertAsyncWriteSucceeds(kMsg2, kLen2);
654 TEST_F(SpdyProxyClientSocketSpdy3Test, WriteSplitsLargeDataIntoMultipleFrames) {
655 std::string chunk_data(kMaxSpdyFrameChunkSize, 'x');
656 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
657 scoped_ptr<SpdyFrame> chunk(ConstructBodyFrame(chunk_data.data(),
658 chunk_data.length()));
659 MockWrite writes[] = {
660 CreateMockWrite(*conn, 0, SYNCHRONOUS),
661 CreateMockWrite(*chunk, 2, SYNCHRONOUS),
662 CreateMockWrite(*chunk, 3, SYNCHRONOUS),
663 CreateMockWrite(*chunk, 4, SYNCHRONOUS)
666 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
667 MockRead reads[] = {
668 CreateMockRead(*resp, 1, ASYNC),
669 MockRead(ASYNC, 0, 5), // EOF
672 Initialize(reads, arraysize(reads), writes, arraysize(writes));
674 AssertConnectSucceeds();
676 std::string big_data(kMaxSpdyFrameChunkSize * 3, 'x');
677 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(big_data.data(),
678 big_data.length()));
680 EXPECT_EQ(ERR_IO_PENDING, sock_->Write(buf, buf->size(),
681 write_callback_.callback()));
682 data_->RunFor(3);
684 EXPECT_EQ(buf->size(), write_callback_.WaitForResult());
687 // ----------- Read
689 TEST_F(SpdyProxyClientSocketSpdy3Test, ReadReadsDataInDataFrame) {
690 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
691 MockWrite writes[] = {
692 CreateMockWrite(*conn, 0, SYNCHRONOUS),
695 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
696 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
697 MockRead reads[] = {
698 CreateMockRead(*resp, 1, ASYNC),
699 CreateMockRead(*msg1, 2, ASYNC),
700 MockRead(ASYNC, 0, 3), // EOF
703 Initialize(reads, arraysize(reads), writes, arraysize(writes));
705 AssertConnectSucceeds();
707 Run(1); // SpdySession consumes the next read and sends it to
708 // sock_ to be buffered.
709 AssertSyncReadEquals(kMsg1, kLen1);
712 TEST_F(SpdyProxyClientSocketSpdy3Test, ReadDataFromBufferedFrames) {
713 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
714 MockWrite writes[] = {
715 CreateMockWrite(*conn, 0, SYNCHRONOUS),
718 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
719 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
720 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
721 MockRead reads[] = {
722 CreateMockRead(*resp, 1, ASYNC),
723 CreateMockRead(*msg1, 2, ASYNC),
724 CreateMockRead(*msg2, 3, ASYNC),
725 MockRead(ASYNC, 0, 4), // EOF
728 Initialize(reads, arraysize(reads), writes, arraysize(writes));
730 AssertConnectSucceeds();
732 Run(1); // SpdySession consumes the next read and sends it to
733 // sock_ to be buffered.
734 AssertSyncReadEquals(kMsg1, kLen1);
735 Run(1); // SpdySession consumes the next read and sends it to
736 // sock_ to be buffered.
737 AssertSyncReadEquals(kMsg2, kLen2);
740 TEST_F(SpdyProxyClientSocketSpdy3Test, ReadDataMultipleBufferedFrames) {
741 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
742 MockWrite writes[] = {
743 CreateMockWrite(*conn, 0, SYNCHRONOUS),
746 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
747 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
748 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
749 MockRead reads[] = {
750 CreateMockRead(*resp, 1, ASYNC),
751 CreateMockRead(*msg1, 2, ASYNC),
752 CreateMockRead(*msg2, 3, ASYNC),
753 MockRead(ASYNC, 0, 4), // EOF
756 Initialize(reads, arraysize(reads), writes, arraysize(writes));
758 AssertConnectSucceeds();
760 Run(2); // SpdySession consumes the next two reads and sends then to
761 // sock_ to be buffered.
762 AssertSyncReadEquals(kMsg1, kLen1);
763 AssertSyncReadEquals(kMsg2, kLen2);
766 TEST_F(SpdyProxyClientSocketSpdy3Test,
767 LargeReadWillMergeDataFromDifferentFrames) {
768 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
769 MockWrite writes[] = {
770 CreateMockWrite(*conn, 0, SYNCHRONOUS),
773 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
774 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
775 scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
776 MockRead reads[] = {
777 CreateMockRead(*resp, 1, ASYNC),
778 CreateMockRead(*msg3, 2, ASYNC),
779 CreateMockRead(*msg3, 3, ASYNC),
780 MockRead(ASYNC, 0, 4), // EOF
783 Initialize(reads, arraysize(reads), writes, arraysize(writes));
785 AssertConnectSucceeds();
787 Run(2); // SpdySession consumes the next two reads and sends then to
788 // sock_ to be buffered.
789 // The payload from two data frames, each with kMsg3 will be combined
790 // together into a single read().
791 AssertSyncReadEquals(kMsg33, kLen33);
794 TEST_F(SpdyProxyClientSocketSpdy3Test, MultipleShortReadsThenMoreRead) {
795 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
796 MockWrite writes[] = {
797 CreateMockWrite(*conn, 0, SYNCHRONOUS),
800 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
801 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
802 scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
803 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
804 MockRead reads[] = {
805 CreateMockRead(*resp, 1, ASYNC),
806 CreateMockRead(*msg1, 2, ASYNC),
807 CreateMockRead(*msg3, 3, ASYNC),
808 CreateMockRead(*msg3, 4, ASYNC),
809 CreateMockRead(*msg2, 5, ASYNC),
810 MockRead(ASYNC, 0, 6), // EOF
813 Initialize(reads, arraysize(reads), writes, arraysize(writes));
815 AssertConnectSucceeds();
817 Run(4); // SpdySession consumes the next four reads and sends then to
818 // sock_ to be buffered.
819 AssertSyncReadEquals(kMsg1, kLen1);
820 // The payload from two data frames, each with kMsg3 will be combined
821 // together into a single read().
822 AssertSyncReadEquals(kMsg33, kLen33);
823 AssertSyncReadEquals(kMsg2, kLen2);
826 TEST_F(SpdyProxyClientSocketSpdy3Test, ReadWillSplitDataFromLargeFrame) {
827 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
828 MockWrite writes[] = {
829 CreateMockWrite(*conn, 0, SYNCHRONOUS),
832 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
833 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
834 scoped_ptr<SpdyFrame> msg33(ConstructBodyFrame(kMsg33, kLen33));
835 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
836 MockRead reads[] = {
837 CreateMockRead(*resp, 1, ASYNC),
838 CreateMockRead(*msg1, 2, ASYNC),
839 CreateMockRead(*msg33, 3, ASYNC),
840 MockRead(ASYNC, 0, 4), // EOF
843 Initialize(reads, arraysize(reads), writes, arraysize(writes));
845 AssertConnectSucceeds();
847 Run(2); // SpdySession consumes the next two reads and sends then to
848 // sock_ to be buffered.
849 AssertSyncReadEquals(kMsg1, kLen1);
850 // The payload from the single large data frame will be read across
851 // two different reads.
852 AssertSyncReadEquals(kMsg3, kLen3);
853 AssertSyncReadEquals(kMsg3, kLen3);
856 TEST_F(SpdyProxyClientSocketSpdy3Test, MultipleReadsFromSameLargeFrame) {
857 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
858 MockWrite writes[] = {
859 CreateMockWrite(*conn, 0, SYNCHRONOUS),
862 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
863 scoped_ptr<SpdyFrame> msg333(ConstructBodyFrame(kMsg333, kLen333));
864 MockRead reads[] = {
865 CreateMockRead(*resp, 1, ASYNC),
866 CreateMockRead(*msg333, 2, ASYNC),
867 MockRead(ASYNC, 0, 3), // EOF
870 Initialize(reads, arraysize(reads), writes, arraysize(writes));
872 AssertConnectSucceeds();
874 Run(1); // SpdySession consumes the next read and sends it to
875 // sock_ to be buffered.
876 // The payload from the single large data frame will be read across
877 // two different reads.
878 AssertSyncReadEquals(kMsg33, kLen33);
880 // Now attempt to do a read of more data than remains buffered
881 scoped_refptr<IOBuffer> buf(new IOBuffer(kLen33));
882 ASSERT_EQ(kLen3, sock_->Read(buf, kLen33, read_callback_.callback()));
883 ASSERT_EQ(std::string(kMsg3, kLen3), std::string(buf->data(), kLen3));
884 ASSERT_TRUE(sock_->IsConnected());
887 TEST_F(SpdyProxyClientSocketSpdy3Test, ReadAuthResponseBody) {
888 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
889 MockWrite writes[] = {
890 CreateMockWrite(*conn, 0, SYNCHRONOUS),
893 scoped_ptr<SpdyFrame> resp(ConstructConnectAuthReplyFrame());
894 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
895 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
896 MockRead reads[] = {
897 CreateMockRead(*resp, 1, ASYNC),
898 CreateMockRead(*msg1, 2, ASYNC),
899 CreateMockRead(*msg2, 3, ASYNC),
900 MockRead(ASYNC, 0, 4), // EOF
903 Initialize(reads, arraysize(reads), writes, arraysize(writes));
905 AssertConnectFails(ERR_PROXY_AUTH_REQUESTED);
907 Run(2); // SpdySession consumes the next two reads and sends then to
908 // sock_ to be buffered.
909 AssertSyncReadEquals(kMsg1, kLen1);
910 AssertSyncReadEquals(kMsg2, kLen2);
913 TEST_F(SpdyProxyClientSocketSpdy3Test, ReadErrorResponseBody) {
914 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
915 MockWrite writes[] = {
916 CreateMockWrite(*conn, 0, SYNCHRONOUS),
919 scoped_ptr<SpdyFrame> resp(ConstructConnectErrorReplyFrame());
920 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
921 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
922 MockRead reads[] = {
923 CreateMockRead(*resp, 1, ASYNC),
924 CreateMockRead(*msg1, 2, ASYNC),
925 CreateMockRead(*msg2, 3, ASYNC),
926 MockRead(ASYNC, 0, 4), // EOF
929 Initialize(reads, arraysize(reads), writes, arraysize(writes));
931 AssertConnectFails(ERR_TUNNEL_CONNECTION_FAILED);
934 // ----------- Reads and Writes
936 TEST_F(SpdyProxyClientSocketSpdy3Test, AsyncReadAroundWrite) {
937 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
938 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
939 MockWrite writes[] = {
940 CreateMockWrite(*conn, 0, SYNCHRONOUS),
941 CreateMockWrite(*msg2, 3, SYNCHRONOUS),
944 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
945 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
946 scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
947 MockRead reads[] = {
948 CreateMockRead(*resp, 1, ASYNC),
949 CreateMockRead(*msg1, 2, ASYNC), // sync read
950 CreateMockRead(*msg3, 4, ASYNC), // async read
951 MockRead(ASYNC, 0, 5), // EOF
954 Initialize(reads, arraysize(reads), writes, arraysize(writes));
956 AssertConnectSucceeds();
958 Run(1);
959 AssertSyncReadEquals(kMsg1, kLen1);
961 AssertReadStarts(kMsg3, kLen3);
962 // Read should block until after the write succeeds
964 AssertAsyncWriteSucceeds(kMsg2, kLen2); // Runs 1 step
966 ASSERT_FALSE(read_callback_.have_result());
967 Run(1);
968 // Now the read will return
969 AssertReadReturns(kMsg3, kLen3);
972 TEST_F(SpdyProxyClientSocketSpdy3Test, AsyncWriteAroundReads) {
973 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
974 scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
975 MockWrite writes[] = {
976 CreateMockWrite(*conn, 0, SYNCHRONOUS),
977 CreateMockWrite(*msg2, 4, ASYNC),
980 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
981 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
982 scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
983 MockRead reads[] = {
984 CreateMockRead(*resp, 1, ASYNC),
985 CreateMockRead(*msg1, 2, ASYNC),
986 CreateMockRead(*msg3, 3, ASYNC),
987 MockRead(ASYNC, 0, 5), // EOF
990 Initialize(reads, arraysize(reads), writes, arraysize(writes));
992 AssertConnectSucceeds();
994 Run(1);
995 AssertSyncReadEquals(kMsg1, kLen1);
996 // Write should block until the read completes
997 AssertWriteReturns(kMsg2, kLen2, ERR_IO_PENDING);
999 AssertAsyncReadEquals(kMsg3, kLen3);
1001 ASSERT_FALSE(write_callback_.have_result());
1003 // Now the write will complete
1004 Run(1);
1005 AssertWriteLength(kLen2);
1008 // ----------- Reading/Writing on Closed socket
1010 // Reading from an already closed socket should return 0
1011 TEST_F(SpdyProxyClientSocketSpdy3Test, ReadOnClosedSocketReturnsZero) {
1012 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1013 MockWrite writes[] = {
1014 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1017 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1018 MockRead reads[] = {
1019 CreateMockRead(*resp, 1, ASYNC),
1020 MockRead(ASYNC, 0, 2), // EOF
1023 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1025 AssertConnectSucceeds();
1027 Run(1);
1029 ASSERT_FALSE(sock_->IsConnected());
1030 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
1031 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
1032 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
1033 ASSERT_FALSE(sock_->IsConnectedAndIdle());
1036 // Read pending when socket is closed should return 0
1037 TEST_F(SpdyProxyClientSocketSpdy3Test, PendingReadOnCloseReturnsZero) {
1038 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1039 MockWrite writes[] = {
1040 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1043 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1044 MockRead reads[] = {
1045 CreateMockRead(*resp, 1, ASYNC),
1046 MockRead(ASYNC, 0, 2), // EOF
1049 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1051 AssertConnectSucceeds();
1053 AssertReadStarts(kMsg1, kLen1);
1055 Run(1);
1057 ASSERT_EQ(0, read_callback_.WaitForResult());
1060 // Reading from a disconnected socket is an error
1061 TEST_F(SpdyProxyClientSocketSpdy3Test,
1062 ReadOnDisconnectSocketReturnsNotConnected) {
1063 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1064 MockWrite writes[] = {
1065 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1068 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1069 MockRead reads[] = {
1070 CreateMockRead(*resp, 1, ASYNC),
1071 MockRead(ASYNC, 0, 2), // EOF
1074 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1076 AssertConnectSucceeds();
1078 sock_->Disconnect();
1080 ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED,
1081 sock_->Read(NULL, 1, CompletionCallback()));
1084 // Reading buffered data from an already closed socket should return
1085 // buffered data, then 0.
1086 TEST_F(SpdyProxyClientSocketSpdy3Test, ReadOnClosedSocketReturnsBufferedData) {
1087 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1088 MockWrite writes[] = {
1089 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1092 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1093 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
1094 MockRead reads[] = {
1095 CreateMockRead(*resp, 1, ASYNC),
1096 CreateMockRead(*msg1, 2, ASYNC),
1097 MockRead(ASYNC, 0, 3), // EOF
1100 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1102 AssertConnectSucceeds();
1104 Run(2);
1106 ASSERT_FALSE(sock_->IsConnected());
1107 scoped_refptr<IOBuffer> buf(new IOBuffer(kLen1));
1108 ASSERT_EQ(kLen1, sock_->Read(buf, kLen1, CompletionCallback()));
1109 ASSERT_EQ(std::string(kMsg1, kLen1), std::string(buf->data(), kLen1));
1111 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
1112 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
1113 sock_->Disconnect();
1114 ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED,
1115 sock_->Read(NULL, 1, CompletionCallback()));
1118 // Calling Write() on a closed socket is an error
1119 TEST_F(SpdyProxyClientSocketSpdy3Test, WriteOnClosedStream) {
1120 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1121 MockWrite writes[] = {
1122 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1125 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1126 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
1127 MockRead reads[] = {
1128 CreateMockRead(*resp, 1, ASYNC),
1129 MockRead(ASYNC, 0, 2), // EOF
1132 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1134 AssertConnectSucceeds();
1136 Run(1); // Read EOF which will close the stream
1137 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
1138 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED,
1139 sock_->Write(buf, buf->size(), CompletionCallback()));
1142 // Calling Write() on a disconnected socket is an error
1143 TEST_F(SpdyProxyClientSocketSpdy3Test, WriteOnDisconnectedSocket) {
1144 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1145 MockWrite writes[] = {
1146 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1149 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1150 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
1151 MockRead reads[] = {
1152 CreateMockRead(*resp, 1, ASYNC),
1153 MockRead(ASYNC, 0, 2), // EOF
1156 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1158 AssertConnectSucceeds();
1160 sock_->Disconnect();
1162 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
1163 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED,
1164 sock_->Write(buf, buf->size(), CompletionCallback()));
1167 // If the socket is closed with a pending Write(), the callback
1168 // should be called with ERR_CONNECTION_CLOSED.
1169 TEST_F(SpdyProxyClientSocketSpdy3Test, WritePendingOnClose) {
1170 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1171 MockWrite writes[] = {
1172 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1173 MockWrite(ASYNC, ERR_IO_PENDING, 2),
1176 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1177 MockRead reads[] = {
1178 CreateMockRead(*resp, 1, ASYNC),
1179 MockRead(ASYNC, 0, 3), // EOF
1182 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1184 AssertConnectSucceeds();
1186 EXPECT_TRUE(sock_->IsConnected());
1188 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
1189 EXPECT_EQ(ERR_IO_PENDING,
1190 sock_->Write(buf, buf->size(), write_callback_.callback()));
1192 Run(1);
1194 EXPECT_EQ(ERR_CONNECTION_CLOSED, write_callback_.WaitForResult());
1197 // If the socket is Disconnected with a pending Write(), the callback
1198 // should not be called.
1199 TEST_F(SpdyProxyClientSocketSpdy3Test, DisconnectWithWritePending) {
1200 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1201 MockWrite writes[] = {
1202 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1203 MockWrite(SYNCHRONOUS, 0, 2), // EOF
1206 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1207 MockRead reads[] = {
1208 CreateMockRead(*resp, 1, ASYNC),
1209 MockRead(ASYNC, 0, 3), // EOF
1212 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1214 AssertConnectSucceeds();
1216 EXPECT_TRUE(sock_->IsConnected());
1218 scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
1219 EXPECT_EQ(ERR_IO_PENDING,
1220 sock_->Write(buf, buf->size(), write_callback_.callback()));
1222 sock_->Disconnect();
1224 EXPECT_FALSE(sock_->IsConnected());
1225 EXPECT_FALSE(write_callback_.have_result());
1228 // If the socket is Disconnected with a pending Read(), the callback
1229 // should not be called.
1230 TEST_F(SpdyProxyClientSocketSpdy3Test, DisconnectWithReadPending) {
1231 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1232 MockWrite writes[] = {
1233 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1236 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1237 MockRead reads[] = {
1238 CreateMockRead(*resp, 1, ASYNC),
1239 MockRead(ASYNC, 0, 2), // EOF
1242 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1244 AssertConnectSucceeds();
1246 EXPECT_TRUE(sock_->IsConnected());
1248 scoped_refptr<IOBuffer> buf(new IOBuffer(kLen1));
1249 ASSERT_EQ(ERR_IO_PENDING,
1250 sock_->Read(buf, kLen1, read_callback_.callback()));
1252 sock_->Disconnect();
1254 EXPECT_FALSE(sock_->IsConnected());
1255 EXPECT_FALSE(read_callback_.have_result());
1258 // If the socket is Reset when both a read and write are pending,
1259 // both should be called back.
1260 TEST_F(SpdyProxyClientSocketSpdy3Test, RstWithReadAndWritePending) {
1261 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1262 MockWrite writes[] = {
1263 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1264 MockWrite(ASYNC, ERR_IO_PENDING, 2),
1267 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1268 scoped_ptr<SpdyFrame> rst(ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
1269 MockRead reads[] = {
1270 CreateMockRead(*resp, 1, ASYNC),
1271 CreateMockRead(*rst, 3, ASYNC),
1274 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1276 AssertConnectSucceeds();
1278 EXPECT_TRUE(sock_->IsConnected());
1280 scoped_refptr<IOBuffer> read_buf(new IOBuffer(kLen1));
1281 ASSERT_EQ(ERR_IO_PENDING,
1282 sock_->Read(read_buf, kLen1, read_callback_.callback()));
1284 scoped_refptr<IOBufferWithSize> write_buf(CreateBuffer(kMsg1, kLen1));
1285 EXPECT_EQ(ERR_IO_PENDING,
1286 sock_->Write(write_buf, write_buf->size(),
1287 write_callback_.callback()));
1289 Run(2);
1291 EXPECT_TRUE(sock_.get());
1292 EXPECT_TRUE(read_callback_.have_result());
1293 EXPECT_TRUE(write_callback_.have_result());
1296 // Makes sure the proxy client socket's source gets the expected NetLog events
1297 // and only the expected NetLog events (No SpdySession events).
1298 TEST_F(SpdyProxyClientSocketSpdy3Test, NetLog) {
1299 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1300 MockWrite writes[] = {
1301 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1304 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1305 scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
1306 MockRead reads[] = {
1307 CreateMockRead(*resp, 1, ASYNC),
1308 CreateMockRead(*msg1, 2, ASYNC),
1309 MockRead(ASYNC, 0, 3), // EOF
1312 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1314 AssertConnectSucceeds();
1316 Run(1); // SpdySession consumes the next read and sends it to
1317 // sock_ to be buffered.
1318 AssertSyncReadEquals(kMsg1, kLen1);
1320 NetLog::Source sock_source = sock_->NetLog().source();
1321 sock_.reset();
1323 CapturingNetLog::CapturedEntryList entry_list;
1324 net_log_.GetEntriesForSource(sock_source, &entry_list);
1326 ASSERT_EQ(entry_list.size(), 10u);
1327 EXPECT_TRUE(LogContainsBeginEvent(entry_list, 0, NetLog::TYPE_SOCKET_ALIVE));
1328 EXPECT_TRUE(LogContainsEvent(entry_list, 1,
1329 NetLog::TYPE_SPDY_PROXY_CLIENT_SESSION,
1330 NetLog::PHASE_NONE));
1331 EXPECT_TRUE(LogContainsBeginEvent(entry_list, 2,
1332 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_SEND_REQUEST));
1333 EXPECT_TRUE(LogContainsEvent(entry_list, 3,
1334 NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
1335 NetLog::PHASE_NONE));
1336 EXPECT_TRUE(LogContainsEndEvent(entry_list, 4,
1337 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_SEND_REQUEST));
1338 EXPECT_TRUE(LogContainsBeginEvent(entry_list, 5,
1339 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_READ_HEADERS));
1340 EXPECT_TRUE(LogContainsEvent(entry_list, 6,
1341 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
1342 NetLog::PHASE_NONE));
1343 EXPECT_TRUE(LogContainsEndEvent(entry_list, 7,
1344 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_READ_HEADERS));
1345 EXPECT_TRUE(LogContainsEvent(entry_list, 8,
1346 NetLog::TYPE_SOCKET_BYTES_RECEIVED,
1347 NetLog::PHASE_NONE));
1348 EXPECT_TRUE(LogContainsEndEvent(entry_list, 9, NetLog::TYPE_SOCKET_ALIVE));
1351 // CompletionCallback that causes the SpdyProxyClientSocket to be
1352 // deleted when Run is invoked.
1353 class DeleteSockCallback : public TestCompletionCallbackBase {
1354 public:
1355 explicit DeleteSockCallback(scoped_ptr<SpdyProxyClientSocket>* sock)
1356 : sock_(sock),
1357 ALLOW_THIS_IN_INITIALIZER_LIST(callback_(
1358 base::Bind(&DeleteSockCallback::OnComplete,
1359 base::Unretained(this)))) {
1362 virtual ~DeleteSockCallback() {
1365 const CompletionCallback& callback() const { return callback_; }
1367 private:
1368 void OnComplete(int result) {
1369 sock_->reset(NULL);
1370 SetResult(result);
1373 scoped_ptr<SpdyProxyClientSocket>* sock_;
1374 CompletionCallback callback_;
1376 DISALLOW_COPY_AND_ASSIGN(DeleteSockCallback);
1379 // If the socket is Reset when both a read and write are pending, and the
1380 // read callback causes the socket to be deleted, the write callback should
1381 // not be called.
1382 TEST_F(SpdyProxyClientSocketSpdy3Test, RstWithReadAndWritePendingDelete) {
1383 scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1384 MockWrite writes[] = {
1385 CreateMockWrite(*conn, 0, SYNCHRONOUS),
1386 MockWrite(ASYNC, ERR_IO_PENDING, 2),
1389 scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1390 scoped_ptr<SpdyFrame> rst(ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
1391 MockRead reads[] = {
1392 CreateMockRead(*resp, 1, ASYNC),
1393 CreateMockRead(*rst, 3, ASYNC),
1396 Initialize(reads, arraysize(reads), writes, arraysize(writes));
1398 AssertConnectSucceeds();
1400 EXPECT_TRUE(sock_->IsConnected());
1402 DeleteSockCallback read_callback(&sock_);
1404 scoped_refptr<IOBuffer> read_buf(new IOBuffer(kLen1));
1405 ASSERT_EQ(ERR_IO_PENDING,
1406 sock_->Read(read_buf, kLen1, read_callback.callback()));
1408 scoped_refptr<IOBufferWithSize> write_buf(CreateBuffer(kMsg1, kLen1));
1409 EXPECT_EQ(ERR_IO_PENDING, sock_->Write(write_buf, write_buf->size(),
1410 write_callback_.callback()));
1412 Run(2);
1414 EXPECT_FALSE(sock_.get());
1415 EXPECT_TRUE(read_callback.have_result());
1416 EXPECT_FALSE(write_callback_.have_result());
1419 } // namespace net