Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / net / spdy / spdy_proxy_client_socket_unittest.cc
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.
4
5 #include "net/spdy/spdy_proxy_client_socket.h"
6
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"
30
31 //-----------------------------------------------------------------------------
32
33 namespace {
34
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";
43
44 static const int kStreamId = 1;
45
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;
56
57 static const char kRedirectUrl[] = "https://example.com/";
58
59 }  // anonymous namespace
60
61 namespace net {
62
63 class SpdyProxyClientSocketTest
64     : public PlatformTest,
65       public testing::WithParamInterface<NextProto> {
66  public:
67   SpdyProxyClientSocketTest();
68
69   virtual void TearDown();
70
71  protected:
72   void Initialize(MockRead* reads, size_t reads_count, MockWrite* writes,
73                   size_t writes_count);
74   void PopulateConnectRequestIR(SpdySynStreamIR* syn_ir);
75   void PopulateConnectReplyIR(SpdySynReplyIR* reply_ir, 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);
96
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                                      "/");
106   }
107
108   void Run(int steps) {
109     data_->StopAfter(steps);
110     data_->Run();
111   }
112
113   void CloseSpdySession(net::Error error, const std::string& description) {
114     spdy_session_->CloseSessionOnError(error, description);
115   }
116
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_;
123
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_;
131
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_;
138
139   DISALLOW_COPY_AND_ASSIGN(SpdyProxyClientSocketTest);
140 };
141
142 INSTANTIATE_TEST_CASE_P(
143     NextProto,
144     SpdyProxyClientSocketTest,
145     testing::Values(kProtoDeprecatedSPDY2,
146                     kProtoSPDY3, kProtoSPDY31, kProtoSPDY4));
147
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();
164 }
165
166 void SpdyProxyClientSocketTest::TearDown() {
167   sock_.reset(NULL);
168   if (session_.get() != NULL)
169     session_->spdy_session_pool()->CloseAllSessions();
170
171   // Empty the current queue.
172   base::MessageLoop::current()->RunUntilIdle();
173   PlatformTest::TearDown();
174 }
175
176 void SpdyProxyClientSocketTest::Initialize(MockRead* reads,
177                                                 size_t reads_count,
178                                                 MockWrite* writes,
179                                                 size_t writes_count) {
180   data_.reset(new DeterministicSocketData(reads, reads_count,
181                                           writes, writes_count));
182   data_->set_connect_data(connect_data_);
183   data_->SetStop(2);
184
185   session_deps_.deterministic_socket_factory->AddSocketDataProvider(
186       data_.get());
187   session_deps_.host_resolver->set_synchronous_mode(true);
188
189   session_ = SpdySessionDependencies::SpdyCreateSessionDeterministic(
190       &session_deps_);
191
192   // Creates the SPDY session and stream.
193   spdy_session_ =
194       CreateInsecureSpdySession(
195           session_, endpoint_spdy_session_key_, BoundNetLog());
196   base::WeakPtr<SpdyStream> spdy_stream(
197       CreateStreamSynchronously(
198           SPDY_BIDIRECTIONAL_STREAM, spdy_session_, url_, LOWEST,
199           net_log_.bound()));
200   ASSERT_TRUE(spdy_stream.get() != NULL);
201
202   // Create the SpdyProxyClientSocket.
203   sock_.reset(
204       new SpdyProxyClientSocket(spdy_stream, user_agent_,
205                                 endpoint_host_port_pair_, url_,
206                                 proxy_host_port_, net_log_.bound(),
207                                 session_->http_auth_cache(),
208                                 session_->http_auth_handler_factory()));
209 }
210
211 scoped_refptr<IOBufferWithSize> SpdyProxyClientSocketTest::CreateBuffer(
212     const char* data, int size) {
213   scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(size));
214   memcpy(buf->data(), data, size);
215   return buf;
216 }
217
218 void SpdyProxyClientSocketTest::AssertConnectSucceeds() {
219   ASSERT_EQ(ERR_IO_PENDING, sock_->Connect(read_callback_.callback()));
220   data_->Run();
221   ASSERT_EQ(OK, read_callback_.WaitForResult());
222 }
223
224 void SpdyProxyClientSocketTest::AssertConnectFails(int result) {
225   ASSERT_EQ(ERR_IO_PENDING, sock_->Connect(read_callback_.callback()));
226   data_->Run();
227   ASSERT_EQ(result, read_callback_.WaitForResult());
228 }
229
230 void SpdyProxyClientSocketTest::AssertConnectionEstablished() {
231   const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
232   ASSERT_TRUE(response != NULL);
233   ASSERT_EQ(200, response->headers->response_code());
234 }
235
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());
242 }
243
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();
253
254   EXPECT_TRUE(sock_->IsConnected());
255
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));
259 }
260
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());
269 }
270
271 void SpdyProxyClientSocketTest::AssertReadReturns(const char* data,
272                                                        int len) {
273   EXPECT_TRUE(sock_->IsConnected());
274
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));
278 }
279
280 void SpdyProxyClientSocketTest::AssertAsyncWriteSucceeds(const char* data,
281                                                               int len) {
282   AssertWriteReturns(data, len, ERR_IO_PENDING);
283   data_->RunFor(1);
284   AssertWriteLength(len);
285 }
286
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()));
293 }
294
295 void SpdyProxyClientSocketTest::AssertWriteLength(int len) {
296   EXPECT_EQ(len, write_callback_.WaitForResult());
297 }
298
299 void SpdyProxyClientSocketTest::AssertAsyncWriteWithReadsSucceeds(
300     const char* data, int len, int num_reads) {
301   scoped_refptr<IOBufferWithSize> buf(CreateBuffer(data, len));
302
303   EXPECT_EQ(ERR_IO_PENDING,
304             sock_->Write(buf.get(), buf->size(), write_callback_.callback()));
305
306   for (int i = 0; i < num_reads; i++) {
307     Run(1);
308     AssertSyncReadEquals(kMsg2, kLen2);
309   }
310
311   write_callback_.WaitForResult();
312 }
313
314 void SpdyProxyClientSocketTest::PopulateConnectRequestIR(
315     SpdySynStreamIR* syn_ir) {
316   spdy_util_.SetPriority(LOWEST, syn_ir);
317   syn_ir->SetHeader(spdy_util_.GetMethodKey(), "CONNECT");
318   syn_ir->SetHeader(spdy_util_.GetPathKey(), kOriginHostPort);
319   syn_ir->SetHeader(spdy_util_.GetHostKey(), kOriginHost);
320   syn_ir->SetHeader("user-agent", kUserAgent);
321   spdy_util_.MaybeAddVersionHeader(syn_ir);
322 }
323
324 void SpdyProxyClientSocketTest::PopulateConnectReplyIR(SpdySynReplyIR* reply_ir,
325                                                        const char* status) {
326   reply_ir->SetHeader(spdy_util_.GetStatusKey(), status);
327   spdy_util_.MaybeAddVersionHeader(reply_ir);
328 }
329
330 // Constructs a standard SPDY SYN_STREAM frame for a CONNECT request.
331 SpdyFrame*
332 SpdyProxyClientSocketTest::ConstructConnectRequestFrame() {
333   SpdySynStreamIR syn_ir(kStreamId);
334   PopulateConnectRequestIR(&syn_ir);
335   return spdy_util_.CreateFramer(false)->SerializeFrame(syn_ir);
336 }
337
338 // Constructs a SPDY SYN_STREAM frame for a CONNECT request which includes
339 // Proxy-Authorization headers.
340 SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectAuthRequestFrame() {
341   SpdySynStreamIR syn_ir(kStreamId);
342   PopulateConnectRequestIR(&syn_ir);
343   syn_ir.SetHeader("proxy-authorization", "Basic Zm9vOmJhcg==");
344   return spdy_util_.CreateFramer(false)->SerializeFrame(syn_ir);
345 }
346
347 // Constructs a standard SPDY SYN_REPLY frame to match the SPDY CONNECT.
348 SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectReplyFrame() {
349   SpdySynReplyIR reply_ir(kStreamId);
350   PopulateConnectReplyIR(&reply_ir, "200");
351   return spdy_util_.CreateFramer(false)->SerializeFrame(reply_ir);
352 }
353
354 // Constructs a standard SPDY SYN_REPLY frame to match the SPDY CONNECT,
355 // including Proxy-Authenticate headers.
356 SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectAuthReplyFrame() {
357   SpdySynReplyIR reply_ir(kStreamId);
358   PopulateConnectReplyIR(&reply_ir, "407");
359   reply_ir.SetHeader("proxy-authenticate", "Basic realm=\"MyRealm1\"");
360   return framer_.SerializeFrame(reply_ir);
361 }
362
363 // Constructs a SPDY SYN_REPLY frame with an HTTP 302 redirect.
364 SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectRedirectReplyFrame() {
365   SpdySynReplyIR reply_ir(kStreamId);
366   PopulateConnectReplyIR(&reply_ir, "302");
367   reply_ir.SetHeader("location", kRedirectUrl);
368   reply_ir.SetHeader("set-cookie", "foo=bar");
369   return framer_.SerializeFrame(reply_ir);
370 }
371
372 // Constructs a SPDY SYN_REPLY frame with an HTTP 500 error.
373 SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectErrorReplyFrame() {
374   SpdySynReplyIR reply_ir(kStreamId);
375   PopulateConnectReplyIR(&reply_ir, "500");
376   return framer_.SerializeFrame(reply_ir);
377 }
378
379 SpdyFrame* SpdyProxyClientSocketTest::ConstructBodyFrame(
380     const char* data,
381     int length) {
382   return framer_.CreateDataFrame(kStreamId, data, length, DATA_FLAG_NONE);
383 }
384
385 // ----------- Connect
386
387 TEST_P(SpdyProxyClientSocketTest, ConnectSendsCorrectRequest) {
388   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
389   MockWrite writes[] = {
390     CreateMockWrite(*conn, 0, SYNCHRONOUS),
391   };
392
393   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
394   MockRead reads[] = {
395     CreateMockRead(*resp, 1, ASYNC),
396     MockRead(ASYNC, 0, 2),  // EOF
397   };
398
399   Initialize(reads, arraysize(reads), writes, arraysize(writes));
400
401   ASSERT_FALSE(sock_->IsConnected());
402
403   AssertConnectSucceeds();
404
405   AssertConnectionEstablished();
406 }
407
408 TEST_P(SpdyProxyClientSocketTest, ConnectWithAuthRequested) {
409   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
410   MockWrite writes[] = {
411     CreateMockWrite(*conn, 0, SYNCHRONOUS),
412   };
413
414   scoped_ptr<SpdyFrame> resp(ConstructConnectAuthReplyFrame());
415   MockRead reads[] = {
416     CreateMockRead(*resp, 1, ASYNC),
417     MockRead(ASYNC, 0, 2),  // EOF
418   };
419
420   Initialize(reads, arraysize(reads), writes, arraysize(writes));
421
422   AssertConnectFails(ERR_PROXY_AUTH_REQUESTED);
423
424   const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
425   ASSERT_TRUE(response != NULL);
426   ASSERT_EQ(407, response->headers->response_code());
427 }
428
429 TEST_P(SpdyProxyClientSocketTest, ConnectWithAuthCredentials) {
430   scoped_ptr<SpdyFrame> conn(ConstructConnectAuthRequestFrame());
431   MockWrite writes[] = {
432     CreateMockWrite(*conn, 0, SYNCHRONOUS),
433   };
434
435   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
436   MockRead reads[] = {
437     CreateMockRead(*resp, 1, ASYNC),
438     MockRead(ASYNC, 0, 2),  // EOF
439   };
440
441   Initialize(reads, arraysize(reads), writes, arraysize(writes));
442   AddAuthToCache();
443
444   AssertConnectSucceeds();
445
446   AssertConnectionEstablished();
447 }
448
449 TEST_P(SpdyProxyClientSocketTest, ConnectRedirects) {
450   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
451   MockWrite writes[] = {
452     CreateMockWrite(*conn, 0, SYNCHRONOUS),
453   };
454
455   scoped_ptr<SpdyFrame> resp(ConstructConnectRedirectReplyFrame());
456   MockRead reads[] = {
457     CreateMockRead(*resp, 1, ASYNC),
458     MockRead(ASYNC, 0, 2),  // EOF
459   };
460
461   Initialize(reads, arraysize(reads), writes, arraysize(writes));
462
463   AssertConnectFails(ERR_HTTPS_PROXY_TUNNEL_RESPONSE);
464
465   const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
466   ASSERT_TRUE(response != NULL);
467
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"));
472
473   std::string location;
474   ASSERT_TRUE(headers->IsRedirect(&location));
475   ASSERT_EQ(location, kRedirectUrl);
476 }
477
478 TEST_P(SpdyProxyClientSocketTest, ConnectFails) {
479   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
480   MockWrite writes[] = {
481     CreateMockWrite(*conn, 0, SYNCHRONOUS),
482   };
483
484   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
485   MockRead reads[] = {
486     MockRead(ASYNC, 0, 1),  // EOF
487   };
488
489   Initialize(reads, arraysize(reads), writes, arraysize(writes));
490
491   ASSERT_FALSE(sock_->IsConnected());
492
493   AssertConnectFails(ERR_CONNECTION_CLOSED);
494
495   ASSERT_FALSE(sock_->IsConnected());
496 }
497
498 // ----------- WasEverUsed
499
500 TEST_P(SpdyProxyClientSocketTest, WasEverUsedReturnsCorrectValues) {
501   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
502   MockWrite writes[] = {
503     CreateMockWrite(*conn, 0, SYNCHRONOUS),
504   };
505
506   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
507   MockRead reads[] = {
508     CreateMockRead(*resp, 1, ASYNC),
509     MockRead(ASYNC, 0, 2),  // EOF
510   };
511
512   Initialize(reads, arraysize(reads), writes, arraysize(writes));
513
514   EXPECT_FALSE(sock_->WasEverUsed());
515   AssertConnectSucceeds();
516   EXPECT_TRUE(sock_->WasEverUsed());
517   sock_->Disconnect();
518   EXPECT_TRUE(sock_->WasEverUsed());
519 }
520
521 // ----------- GetPeerAddress
522
523 TEST_P(SpdyProxyClientSocketTest, GetPeerAddressReturnsCorrectValues) {
524   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
525   MockWrite writes[] = {
526     CreateMockWrite(*conn, 0, SYNCHRONOUS),
527   };
528
529   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
530   MockRead reads[] = {
531     CreateMockRead(*resp, 1, ASYNC),
532     MockRead(ASYNC, 0, 2),  // EOF
533   };
534
535   Initialize(reads, arraysize(reads), writes, arraysize(writes));
536
537   net::IPEndPoint addr;
538   EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr));
539
540   AssertConnectSucceeds();
541   EXPECT_TRUE(sock_->IsConnected());
542   EXPECT_EQ(OK, sock_->GetPeerAddress(&addr));
543
544   Run(1);
545
546   EXPECT_FALSE(sock_->IsConnected());
547   EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr));
548
549   sock_->Disconnect();
550
551   EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr));
552 }
553
554 // ----------- Write
555
556 TEST_P(SpdyProxyClientSocketTest, WriteSendsDataInDataFrame) {
557   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
558   scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
559   scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
560   MockWrite writes[] = {
561     CreateMockWrite(*conn, 0, SYNCHRONOUS),
562     CreateMockWrite(*msg1, 2, SYNCHRONOUS),
563     CreateMockWrite(*msg2, 3, SYNCHRONOUS),
564   };
565
566   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
567   MockRead reads[] = {
568     CreateMockRead(*resp, 1, ASYNC),
569     MockRead(ASYNC, 0, 4),  // EOF
570   };
571
572   Initialize(reads, arraysize(reads), writes, arraysize(writes));
573
574   AssertConnectSucceeds();
575
576   AssertAsyncWriteSucceeds(kMsg1, kLen1);
577   AssertAsyncWriteSucceeds(kMsg2, kLen2);
578 }
579
580 TEST_P(SpdyProxyClientSocketTest, WriteSplitsLargeDataIntoMultipleFrames) {
581   std::string chunk_data(kMaxSpdyFrameChunkSize, 'x');
582   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
583   scoped_ptr<SpdyFrame> chunk(ConstructBodyFrame(chunk_data.data(),
584                                                        chunk_data.length()));
585   MockWrite writes[] = {
586     CreateMockWrite(*conn, 0, SYNCHRONOUS),
587     CreateMockWrite(*chunk, 2, SYNCHRONOUS),
588     CreateMockWrite(*chunk, 3, SYNCHRONOUS),
589     CreateMockWrite(*chunk, 4, SYNCHRONOUS)
590   };
591
592   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
593   MockRead reads[] = {
594     CreateMockRead(*resp, 1, ASYNC),
595     MockRead(ASYNC, 0, 5),  // EOF
596   };
597
598   Initialize(reads, arraysize(reads), writes, arraysize(writes));
599
600   AssertConnectSucceeds();
601
602   std::string big_data(kMaxSpdyFrameChunkSize * 3, 'x');
603   scoped_refptr<IOBufferWithSize> buf(CreateBuffer(big_data.data(),
604                                                    big_data.length()));
605
606   EXPECT_EQ(ERR_IO_PENDING,
607             sock_->Write(buf.get(), buf->size(), write_callback_.callback()));
608   data_->RunFor(3);
609
610   EXPECT_EQ(buf->size(), write_callback_.WaitForResult());
611 }
612
613 // ----------- Read
614
615 TEST_P(SpdyProxyClientSocketTest, ReadReadsDataInDataFrame) {
616   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
617   MockWrite writes[] = {
618     CreateMockWrite(*conn, 0, SYNCHRONOUS),
619   };
620
621   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
622   scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
623   MockRead reads[] = {
624     CreateMockRead(*resp, 1, ASYNC),
625     CreateMockRead(*msg1, 2, ASYNC),
626     MockRead(ASYNC, 0, 3),  // EOF
627   };
628
629   Initialize(reads, arraysize(reads), writes, arraysize(writes));
630
631   AssertConnectSucceeds();
632
633   Run(1);  // SpdySession consumes the next read and sends it to
634            // sock_ to be buffered.
635   AssertSyncReadEquals(kMsg1, kLen1);
636 }
637
638 TEST_P(SpdyProxyClientSocketTest, ReadDataFromBufferedFrames) {
639   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
640   MockWrite writes[] = {
641     CreateMockWrite(*conn, 0, SYNCHRONOUS),
642   };
643
644   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
645   scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
646   scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
647   MockRead reads[] = {
648     CreateMockRead(*resp, 1, ASYNC),
649     CreateMockRead(*msg1, 2, ASYNC),
650     CreateMockRead(*msg2, 3, ASYNC),
651     MockRead(ASYNC, 0, 4),  // EOF
652   };
653
654   Initialize(reads, arraysize(reads), writes, arraysize(writes));
655
656   AssertConnectSucceeds();
657
658   Run(1);  // SpdySession consumes the next read and sends it to
659            // sock_ to be buffered.
660   AssertSyncReadEquals(kMsg1, kLen1);
661   Run(1);  // SpdySession consumes the next read and sends it to
662            // sock_ to be buffered.
663   AssertSyncReadEquals(kMsg2, kLen2);
664 }
665
666 TEST_P(SpdyProxyClientSocketTest, ReadDataMultipleBufferedFrames) {
667   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
668   MockWrite writes[] = {
669     CreateMockWrite(*conn, 0, SYNCHRONOUS),
670   };
671
672   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
673   scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
674   scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
675   MockRead reads[] = {
676     CreateMockRead(*resp, 1, ASYNC),
677     CreateMockRead(*msg1, 2, ASYNC),
678     CreateMockRead(*msg2, 3, ASYNC),
679     MockRead(ASYNC, 0, 4),  // EOF
680   };
681
682   Initialize(reads, arraysize(reads), writes, arraysize(writes));
683
684   AssertConnectSucceeds();
685
686   Run(2);  // SpdySession consumes the next two reads and sends then to
687            // sock_ to be buffered.
688   AssertSyncReadEquals(kMsg1, kLen1);
689   AssertSyncReadEquals(kMsg2, kLen2);
690 }
691
692 TEST_P(SpdyProxyClientSocketTest,
693        LargeReadWillMergeDataFromDifferentFrames) {
694   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
695   MockWrite writes[] = {
696     CreateMockWrite(*conn, 0, SYNCHRONOUS),
697   };
698
699   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
700   scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
701   scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
702   MockRead reads[] = {
703     CreateMockRead(*resp, 1, ASYNC),
704     CreateMockRead(*msg3, 2, ASYNC),
705     CreateMockRead(*msg3, 3, ASYNC),
706     MockRead(ASYNC, 0, 4),  // EOF
707   };
708
709   Initialize(reads, arraysize(reads), writes, arraysize(writes));
710
711   AssertConnectSucceeds();
712
713   Run(2);  // SpdySession consumes the next two reads and sends then to
714            // sock_ to be buffered.
715   // The payload from two data frames, each with kMsg3 will be combined
716   // together into a single read().
717   AssertSyncReadEquals(kMsg33, kLen33);
718 }
719
720 TEST_P(SpdyProxyClientSocketTest, MultipleShortReadsThenMoreRead) {
721   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
722   MockWrite writes[] = {
723     CreateMockWrite(*conn, 0, SYNCHRONOUS),
724   };
725
726   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
727   scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
728   scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
729   scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
730   MockRead reads[] = {
731     CreateMockRead(*resp, 1, ASYNC),
732     CreateMockRead(*msg1, 2, ASYNC),
733     CreateMockRead(*msg3, 3, ASYNC),
734     CreateMockRead(*msg3, 4, ASYNC),
735     CreateMockRead(*msg2, 5, ASYNC),
736     MockRead(ASYNC, 0, 6),  // EOF
737   };
738
739   Initialize(reads, arraysize(reads), writes, arraysize(writes));
740
741   AssertConnectSucceeds();
742
743   Run(4);  // SpdySession consumes the next four reads and sends then to
744            // sock_ to be buffered.
745   AssertSyncReadEquals(kMsg1, kLen1);
746   // The payload from two data frames, each with kMsg3 will be combined
747   // together into a single read().
748   AssertSyncReadEquals(kMsg33, kLen33);
749   AssertSyncReadEquals(kMsg2, kLen2);
750 }
751
752 TEST_P(SpdyProxyClientSocketTest, ReadWillSplitDataFromLargeFrame) {
753   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
754   MockWrite writes[] = {
755     CreateMockWrite(*conn, 0, SYNCHRONOUS),
756   };
757
758   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
759   scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
760   scoped_ptr<SpdyFrame> msg33(ConstructBodyFrame(kMsg33, kLen33));
761   scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
762   MockRead reads[] = {
763     CreateMockRead(*resp, 1, ASYNC),
764     CreateMockRead(*msg1, 2, ASYNC),
765     CreateMockRead(*msg33, 3, ASYNC),
766     MockRead(ASYNC, 0, 4),  // EOF
767   };
768
769   Initialize(reads, arraysize(reads), writes, arraysize(writes));
770
771   AssertConnectSucceeds();
772
773   Run(2);  // SpdySession consumes the next two reads and sends then to
774            // sock_ to be buffered.
775   AssertSyncReadEquals(kMsg1, kLen1);
776   // The payload from the single large data frame will be read across
777   // two different reads.
778   AssertSyncReadEquals(kMsg3, kLen3);
779   AssertSyncReadEquals(kMsg3, kLen3);
780 }
781
782 TEST_P(SpdyProxyClientSocketTest, MultipleReadsFromSameLargeFrame) {
783   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
784   MockWrite writes[] = {
785     CreateMockWrite(*conn, 0, SYNCHRONOUS),
786   };
787
788   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
789   scoped_ptr<SpdyFrame> msg333(ConstructBodyFrame(kMsg333, kLen333));
790   MockRead reads[] = {
791     CreateMockRead(*resp, 1, ASYNC),
792     CreateMockRead(*msg333, 2, ASYNC),
793     MockRead(ASYNC, 0, 3),  // EOF
794   };
795
796   Initialize(reads, arraysize(reads), writes, arraysize(writes));
797
798   AssertConnectSucceeds();
799
800   Run(1);  // SpdySession consumes the next read and sends it to
801            // sock_ to be buffered.
802   // The payload from the single large data frame will be read across
803   // two different reads.
804   AssertSyncReadEquals(kMsg33, kLen33);
805
806   // Now attempt to do a read of more data than remains buffered
807   scoped_refptr<IOBuffer> buf(new IOBuffer(kLen33));
808   ASSERT_EQ(kLen3, sock_->Read(buf.get(), kLen33, read_callback_.callback()));
809   ASSERT_EQ(std::string(kMsg3, kLen3), std::string(buf->data(), kLen3));
810   ASSERT_TRUE(sock_->IsConnected());
811 }
812
813 TEST_P(SpdyProxyClientSocketTest, ReadAuthResponseBody) {
814   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
815   MockWrite writes[] = {
816     CreateMockWrite(*conn, 0, SYNCHRONOUS),
817   };
818
819   scoped_ptr<SpdyFrame> resp(ConstructConnectAuthReplyFrame());
820   scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
821   scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
822   MockRead reads[] = {
823     CreateMockRead(*resp, 1, ASYNC),
824     CreateMockRead(*msg1, 2, ASYNC),
825     CreateMockRead(*msg2, 3, ASYNC),
826     MockRead(ASYNC, 0, 4),  // EOF
827   };
828
829   Initialize(reads, arraysize(reads), writes, arraysize(writes));
830
831   AssertConnectFails(ERR_PROXY_AUTH_REQUESTED);
832
833   Run(2);  // SpdySession consumes the next two reads and sends then to
834            // sock_ to be buffered.
835   AssertSyncReadEquals(kMsg1, kLen1);
836   AssertSyncReadEquals(kMsg2, kLen2);
837 }
838
839 TEST_P(SpdyProxyClientSocketTest, ReadErrorResponseBody) {
840   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
841   MockWrite writes[] = {
842     CreateMockWrite(*conn, 0, SYNCHRONOUS),
843   };
844
845   scoped_ptr<SpdyFrame> resp(ConstructConnectErrorReplyFrame());
846   scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
847   scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
848   MockRead reads[] = {
849     CreateMockRead(*resp, 1, ASYNC),
850     CreateMockRead(*msg1, 2, ASYNC),
851     CreateMockRead(*msg2, 3, ASYNC),
852     MockRead(ASYNC, 0, 4),  // EOF
853   };
854
855   Initialize(reads, arraysize(reads), writes, arraysize(writes));
856
857   AssertConnectFails(ERR_TUNNEL_CONNECTION_FAILED);
858 }
859
860 // ----------- Reads and Writes
861
862 TEST_P(SpdyProxyClientSocketTest, AsyncReadAroundWrite) {
863   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
864   scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
865   MockWrite writes[] = {
866     CreateMockWrite(*conn, 0, SYNCHRONOUS),
867     CreateMockWrite(*msg2, 3, SYNCHRONOUS),
868   };
869
870   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
871   scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
872   scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
873   MockRead reads[] = {
874     CreateMockRead(*resp, 1, ASYNC),
875     CreateMockRead(*msg1, 2, ASYNC),  // sync read
876     CreateMockRead(*msg3, 4, ASYNC),  // async read
877     MockRead(ASYNC, 0, 5),  // EOF
878   };
879
880   Initialize(reads, arraysize(reads), writes, arraysize(writes));
881
882   AssertConnectSucceeds();
883
884   Run(1);
885   AssertSyncReadEquals(kMsg1, kLen1);
886
887   AssertReadStarts(kMsg3, kLen3);
888   // Read should block until after the write succeeds
889
890   AssertAsyncWriteSucceeds(kMsg2, kLen2);  // Runs 1 step
891
892   ASSERT_FALSE(read_callback_.have_result());
893   Run(1);
894   // Now the read will return
895   AssertReadReturns(kMsg3, kLen3);
896 }
897
898 TEST_P(SpdyProxyClientSocketTest, AsyncWriteAroundReads) {
899   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
900   scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
901   MockWrite writes[] = {
902     CreateMockWrite(*conn, 0, SYNCHRONOUS),
903     CreateMockWrite(*msg2, 4, ASYNC),
904   };
905
906   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
907   scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
908   scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
909   MockRead reads[] = {
910     CreateMockRead(*resp, 1, ASYNC),
911     CreateMockRead(*msg1, 2, ASYNC),
912     CreateMockRead(*msg3, 3, ASYNC),
913     MockRead(ASYNC, 0, 5),  // EOF
914   };
915
916   Initialize(reads, arraysize(reads), writes, arraysize(writes));
917
918   AssertConnectSucceeds();
919
920   Run(1);
921   AssertSyncReadEquals(kMsg1, kLen1);
922   // Write should block until the read completes
923   AssertWriteReturns(kMsg2, kLen2, ERR_IO_PENDING);
924
925   AssertAsyncReadEquals(kMsg3, kLen3);
926
927   ASSERT_FALSE(write_callback_.have_result());
928
929   // Now the write will complete
930   Run(1);
931   AssertWriteLength(kLen2);
932 }
933
934 // ----------- Reading/Writing on Closed socket
935
936 // Reading from an already closed socket should return 0
937 TEST_P(SpdyProxyClientSocketTest, ReadOnClosedSocketReturnsZero) {
938   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
939   MockWrite writes[] = {
940     CreateMockWrite(*conn, 0, SYNCHRONOUS),
941   };
942
943   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
944   MockRead reads[] = {
945     CreateMockRead(*resp, 1, ASYNC),
946     MockRead(ASYNC, 0, 2),  // EOF
947   };
948
949   Initialize(reads, arraysize(reads), writes, arraysize(writes));
950
951   AssertConnectSucceeds();
952
953   Run(1);
954
955   ASSERT_FALSE(sock_->IsConnected());
956   ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
957   ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
958   ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
959   ASSERT_FALSE(sock_->IsConnectedAndIdle());
960 }
961
962 // Read pending when socket is closed should return 0
963 TEST_P(SpdyProxyClientSocketTest, PendingReadOnCloseReturnsZero) {
964   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
965   MockWrite writes[] = {
966     CreateMockWrite(*conn, 0, SYNCHRONOUS),
967   };
968
969   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
970   MockRead reads[] = {
971     CreateMockRead(*resp, 1, ASYNC),
972     MockRead(ASYNC, 0, 2),  // EOF
973   };
974
975   Initialize(reads, arraysize(reads), writes, arraysize(writes));
976
977   AssertConnectSucceeds();
978
979   AssertReadStarts(kMsg1, kLen1);
980
981   Run(1);
982
983   ASSERT_EQ(0, read_callback_.WaitForResult());
984 }
985
986 // Reading from a disconnected socket is an error
987 TEST_P(SpdyProxyClientSocketTest,
988        ReadOnDisconnectSocketReturnsNotConnected) {
989   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
990   MockWrite writes[] = {
991     CreateMockWrite(*conn, 0, SYNCHRONOUS),
992   };
993
994   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
995   MockRead reads[] = {
996     CreateMockRead(*resp, 1, ASYNC),
997     MockRead(ASYNC, 0, 2),  // EOF
998   };
999
1000   Initialize(reads, arraysize(reads), writes, arraysize(writes));
1001
1002   AssertConnectSucceeds();
1003
1004   sock_->Disconnect();
1005
1006   ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED,
1007             sock_->Read(NULL, 1, CompletionCallback()));
1008 }
1009
1010 // Reading buffered data from an already closed socket should return
1011 // buffered data, then 0.
1012 TEST_P(SpdyProxyClientSocketTest, ReadOnClosedSocketReturnsBufferedData) {
1013   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1014   MockWrite writes[] = {
1015     CreateMockWrite(*conn, 0, SYNCHRONOUS),
1016   };
1017
1018   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1019   scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
1020   MockRead reads[] = {
1021     CreateMockRead(*resp, 1, ASYNC),
1022     CreateMockRead(*msg1, 2, ASYNC),
1023     MockRead(ASYNC, 0, 3),  // EOF
1024   };
1025
1026   Initialize(reads, arraysize(reads), writes, arraysize(writes));
1027
1028   AssertConnectSucceeds();
1029
1030   Run(2);
1031
1032   ASSERT_FALSE(sock_->IsConnected());
1033   scoped_refptr<IOBuffer> buf(new IOBuffer(kLen1));
1034   ASSERT_EQ(kLen1, sock_->Read(buf.get(), kLen1, CompletionCallback()));
1035   ASSERT_EQ(std::string(kMsg1, kLen1), std::string(buf->data(), kLen1));
1036
1037   ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
1038   ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionCallback()));
1039   sock_->Disconnect();
1040   ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED,
1041             sock_->Read(NULL, 1, CompletionCallback()));
1042 }
1043
1044 // Calling Write() on a closed socket is an error
1045 TEST_P(SpdyProxyClientSocketTest, WriteOnClosedStream) {
1046   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1047   MockWrite writes[] = {
1048     CreateMockWrite(*conn, 0, SYNCHRONOUS),
1049   };
1050
1051   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1052   scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
1053   MockRead reads[] = {
1054     CreateMockRead(*resp, 1, ASYNC),
1055     MockRead(ASYNC, 0, 2),  // EOF
1056   };
1057
1058   Initialize(reads, arraysize(reads), writes, arraysize(writes));
1059
1060   AssertConnectSucceeds();
1061
1062   Run(1);  // Read EOF which will close the stream
1063   scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
1064   EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED,
1065             sock_->Write(buf.get(), buf->size(), CompletionCallback()));
1066 }
1067
1068 // Calling Write() on a disconnected socket is an error
1069 TEST_P(SpdyProxyClientSocketTest, WriteOnDisconnectedSocket) {
1070   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1071   MockWrite writes[] = {
1072     CreateMockWrite(*conn, 0, SYNCHRONOUS),
1073   };
1074
1075   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1076   scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
1077   MockRead reads[] = {
1078     CreateMockRead(*resp, 1, ASYNC),
1079     MockRead(ASYNC, 0, 2),  // EOF
1080   };
1081
1082   Initialize(reads, arraysize(reads), writes, arraysize(writes));
1083
1084   AssertConnectSucceeds();
1085
1086   sock_->Disconnect();
1087
1088   scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
1089   EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED,
1090             sock_->Write(buf.get(), buf->size(), CompletionCallback()));
1091 }
1092
1093 // If the socket is closed with a pending Write(), the callback
1094 // should be called with ERR_CONNECTION_CLOSED.
1095 TEST_P(SpdyProxyClientSocketTest, WritePendingOnClose) {
1096   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1097   MockWrite writes[] = {
1098     CreateMockWrite(*conn, 0, SYNCHRONOUS),
1099     MockWrite(ASYNC, ERR_ABORTED, 2),
1100   };
1101
1102   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1103   MockRead reads[] = {
1104     CreateMockRead(*resp, 1, ASYNC),
1105     MockRead(ASYNC, 0, 3),  // EOF
1106   };
1107
1108   Initialize(reads, arraysize(reads), writes, arraysize(writes));
1109
1110   AssertConnectSucceeds();
1111
1112   EXPECT_TRUE(sock_->IsConnected());
1113
1114   scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
1115   EXPECT_EQ(ERR_IO_PENDING,
1116             sock_->Write(buf.get(), buf->size(), write_callback_.callback()));
1117
1118   CloseSpdySession(ERR_ABORTED, std::string());
1119
1120   EXPECT_EQ(ERR_CONNECTION_CLOSED, write_callback_.WaitForResult());
1121 }
1122
1123 // If the socket is Disconnected with a pending Write(), the callback
1124 // should not be called.
1125 TEST_P(SpdyProxyClientSocketTest, DisconnectWithWritePending) {
1126   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1127   MockWrite writes[] = {
1128     CreateMockWrite(*conn, 0, SYNCHRONOUS),
1129     MockWrite(SYNCHRONOUS, 0, 2),  // EOF
1130   };
1131
1132   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1133   MockRead reads[] = {
1134     CreateMockRead(*resp, 1, ASYNC),
1135     MockRead(ASYNC, 0, 3),  // EOF
1136   };
1137
1138   Initialize(reads, arraysize(reads), writes, arraysize(writes));
1139
1140   AssertConnectSucceeds();
1141
1142   EXPECT_TRUE(sock_->IsConnected());
1143
1144   scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
1145   EXPECT_EQ(ERR_IO_PENDING,
1146             sock_->Write(buf.get(), buf->size(), write_callback_.callback()));
1147
1148   sock_->Disconnect();
1149
1150   EXPECT_FALSE(sock_->IsConnected());
1151   EXPECT_FALSE(write_callback_.have_result());
1152 }
1153
1154 // If the socket is Disconnected with a pending Read(), the callback
1155 // should not be called.
1156 TEST_P(SpdyProxyClientSocketTest, DisconnectWithReadPending) {
1157   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1158   MockWrite writes[] = {
1159     CreateMockWrite(*conn, 0, SYNCHRONOUS),
1160   };
1161
1162   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1163   MockRead reads[] = {
1164     CreateMockRead(*resp, 1, ASYNC),
1165     MockRead(ASYNC, 0, 2),  // EOF
1166   };
1167
1168   Initialize(reads, arraysize(reads), writes, arraysize(writes));
1169
1170   AssertConnectSucceeds();
1171
1172   EXPECT_TRUE(sock_->IsConnected());
1173
1174   scoped_refptr<IOBuffer> buf(new IOBuffer(kLen1));
1175   ASSERT_EQ(ERR_IO_PENDING,
1176             sock_->Read(buf.get(), kLen1, read_callback_.callback()));
1177
1178   sock_->Disconnect();
1179
1180   EXPECT_FALSE(sock_->IsConnected());
1181   EXPECT_FALSE(read_callback_.have_result());
1182 }
1183
1184 // If the socket is Reset when both a read and write are pending,
1185 // both should be called back.
1186 TEST_P(SpdyProxyClientSocketTest, RstWithReadAndWritePending) {
1187   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1188   MockWrite writes[] = {
1189     CreateMockWrite(*conn, 0, SYNCHRONOUS),
1190     MockWrite(ASYNC, ERR_ABORTED, 3),
1191   };
1192
1193   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1194   scoped_ptr<SpdyFrame> rst(
1195       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
1196   MockRead reads[] = {
1197     CreateMockRead(*resp, 1, ASYNC),
1198     CreateMockRead(*rst, 2, ASYNC),
1199     MockRead(ASYNC, 0, 4)  // EOF
1200   };
1201
1202   Initialize(reads, arraysize(reads), writes, arraysize(writes));
1203
1204   AssertConnectSucceeds();
1205
1206   EXPECT_TRUE(sock_->IsConnected());
1207
1208   scoped_refptr<IOBuffer> read_buf(new IOBuffer(kLen1));
1209   ASSERT_EQ(ERR_IO_PENDING,
1210             sock_->Read(read_buf.get(), kLen1, read_callback_.callback()));
1211
1212   scoped_refptr<IOBufferWithSize> write_buf(CreateBuffer(kMsg1, kLen1));
1213   EXPECT_EQ(
1214       ERR_IO_PENDING,
1215       sock_->Write(
1216           write_buf.get(), write_buf->size(), write_callback_.callback()));
1217
1218   Run(2);
1219
1220   EXPECT_TRUE(sock_.get());
1221   EXPECT_TRUE(read_callback_.have_result());
1222   EXPECT_TRUE(write_callback_.have_result());
1223 }
1224
1225 // Makes sure the proxy client socket's source gets the expected NetLog events
1226 // and only the expected NetLog events (No SpdySession events).
1227 TEST_P(SpdyProxyClientSocketTest, NetLog) {
1228   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1229   MockWrite writes[] = {
1230     CreateMockWrite(*conn, 0, SYNCHRONOUS),
1231   };
1232
1233   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1234   scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
1235   MockRead reads[] = {
1236     CreateMockRead(*resp, 1, ASYNC),
1237     CreateMockRead(*msg1, 2, ASYNC),
1238     MockRead(ASYNC, 0, 3),  // EOF
1239   };
1240
1241   Initialize(reads, arraysize(reads), writes, arraysize(writes));
1242
1243   AssertConnectSucceeds();
1244
1245   Run(1);  // SpdySession consumes the next read and sends it to
1246            // sock_ to be buffered.
1247   AssertSyncReadEquals(kMsg1, kLen1);
1248
1249   NetLog::Source sock_source = sock_->NetLog().source();
1250   sock_.reset();
1251
1252   CapturingNetLog::CapturedEntryList entry_list;
1253   net_log_.GetEntriesForSource(sock_source, &entry_list);
1254
1255   ASSERT_EQ(entry_list.size(), 10u);
1256   EXPECT_TRUE(LogContainsBeginEvent(entry_list, 0, NetLog::TYPE_SOCKET_ALIVE));
1257   EXPECT_TRUE(LogContainsEvent(entry_list, 1,
1258                   NetLog::TYPE_SPDY_PROXY_CLIENT_SESSION,
1259                   NetLog::PHASE_NONE));
1260   EXPECT_TRUE(LogContainsBeginEvent(entry_list, 2,
1261                   NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_SEND_REQUEST));
1262   EXPECT_TRUE(LogContainsEvent(entry_list, 3,
1263                   NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
1264                   NetLog::PHASE_NONE));
1265   EXPECT_TRUE(LogContainsEndEvent(entry_list, 4,
1266                   NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_SEND_REQUEST));
1267   EXPECT_TRUE(LogContainsBeginEvent(entry_list, 5,
1268                   NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_READ_HEADERS));
1269   EXPECT_TRUE(LogContainsEvent(entry_list, 6,
1270                   NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
1271                   NetLog::PHASE_NONE));
1272   EXPECT_TRUE(LogContainsEndEvent(entry_list, 7,
1273                   NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_READ_HEADERS));
1274   EXPECT_TRUE(LogContainsEvent(entry_list, 8,
1275                   NetLog::TYPE_SOCKET_BYTES_RECEIVED,
1276                   NetLog::PHASE_NONE));
1277   EXPECT_TRUE(LogContainsEndEvent(entry_list, 9, NetLog::TYPE_SOCKET_ALIVE));
1278 }
1279
1280 // CompletionCallback that causes the SpdyProxyClientSocket to be
1281 // deleted when Run is invoked.
1282 class DeleteSockCallback : public TestCompletionCallbackBase {
1283  public:
1284   explicit DeleteSockCallback(scoped_ptr<SpdyProxyClientSocket>* sock)
1285       : sock_(sock),
1286         callback_(base::Bind(&DeleteSockCallback::OnComplete,
1287                              base::Unretained(this))) {
1288   }
1289
1290   virtual ~DeleteSockCallback() {
1291   }
1292
1293   const CompletionCallback& callback() const { return callback_; }
1294
1295  private:
1296   void OnComplete(int result) {
1297     sock_->reset(NULL);
1298     SetResult(result);
1299   }
1300
1301   scoped_ptr<SpdyProxyClientSocket>* sock_;
1302   CompletionCallback callback_;
1303
1304   DISALLOW_COPY_AND_ASSIGN(DeleteSockCallback);
1305 };
1306
1307 // If the socket is Reset when both a read and write are pending, and the
1308 // read callback causes the socket to be deleted, the write callback should
1309 // not be called.
1310 TEST_P(SpdyProxyClientSocketTest, RstWithReadAndWritePendingDelete) {
1311   scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
1312   MockWrite writes[] = {
1313     CreateMockWrite(*conn, 0, SYNCHRONOUS),
1314     MockWrite(ASYNC, ERR_ABORTED, 3),
1315   };
1316
1317   scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
1318   scoped_ptr<SpdyFrame> rst(
1319       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
1320   MockRead reads[] = {
1321     CreateMockRead(*resp, 1, ASYNC),
1322     CreateMockRead(*rst, 2, ASYNC),
1323     MockRead(ASYNC, 0, 4),  // EOF
1324   };
1325
1326   Initialize(reads, arraysize(reads), writes, arraysize(writes));
1327
1328   AssertConnectSucceeds();
1329
1330   EXPECT_TRUE(sock_->IsConnected());
1331
1332   DeleteSockCallback read_callback(&sock_);
1333
1334   scoped_refptr<IOBuffer> read_buf(new IOBuffer(kLen1));
1335   ASSERT_EQ(ERR_IO_PENDING,
1336             sock_->Read(read_buf.get(), kLen1, read_callback.callback()));
1337
1338   scoped_refptr<IOBufferWithSize> write_buf(CreateBuffer(kMsg1, kLen1));
1339   EXPECT_EQ(
1340       ERR_IO_PENDING,
1341       sock_->Write(
1342           write_buf.get(), write_buf->size(), write_callback_.callback()));
1343
1344   Run(1);
1345
1346   EXPECT_FALSE(sock_.get());
1347   EXPECT_TRUE(read_callback.have_result());
1348   EXPECT_FALSE(write_callback_.have_result());
1349 }
1350
1351 }  // namespace net