1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Use of this source code is governed by a BSD-style license that can be
3731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// found in the LICENSE file.
4731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
5731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "net/spdy/spdy_proxy_client_socket.h"
6731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
7731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/utf_string_conversions.h"
8731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "net/base/address_list.h"
9731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "net/base/net_log.h"
10731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "net/base/net_log_unittest.h"
11731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "net/base/mock_host_resolver.h"
12731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "net/base/test_completion_callback.h"
13731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "net/base/winsock_init.h"
14731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "net/http/http_response_info.h"
15731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "net/http/http_response_headers.h"
16731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "net/socket/client_socket_factory.h"
17731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "net/socket/tcp_client_socket.h"
18731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "net/socket/socket_test_util.h"
1972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "net/spdy/spdy_http_utils.h"
20731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "net/spdy/spdy_protocol.h"
21731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "net/spdy/spdy_session_pool.h"
22731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "net/spdy/spdy_test_util.h"
23731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "testing/platform_test.h"
24731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "testing/gtest/include/gtest/gtest.h"
25731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
26731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick//-----------------------------------------------------------------------------
27731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
28731df977c0511bca2206b5f333555b1205ff1f43Iain Merricknamespace {
29731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
30731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickstatic const char kUrl[] = "https://www.google.com/";
31731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickstatic const char kOriginHost[] = "www.google.com";
32731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickstatic const int kOriginPort = 443;
33731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickstatic const char kOriginHostPort[] = "www.google.com:443";
34731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickstatic const char kProxyUrl[] = "http://myproxy:6121/";
35731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickstatic const char kProxyHost[] = "myproxy";
36731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickstatic const int kProxyPort = 6121;
37731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickstatic const char kUserAgent[] = "Mozilla/1.0";
38731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
39731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickstatic const int kStreamId = 1;
40731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
41731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickstatic const char kMsg1[] = "\0hello!\xff";
42731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickstatic const int kLen1 = 8;
43731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickstatic const char kMsg2[] = "\012345678\0";
44731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickstatic const int kLen2 = 10;
45731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickstatic const char kMsg3[] = "bye!";
46731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickstatic const int kLen3 = 4;
47731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickstatic const char kMsg33[] = "bye!bye!";
48731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickstatic const int kLen33 = kLen3 + kLen3;
49731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickstatic const char kMsg333[] = "bye!bye!bye!";
50731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickstatic const int kLen333 = kLen3 + kLen3 + kLen3;
51731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
52731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}  // anonymous namespace
53731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
54731df977c0511bca2206b5f333555b1205ff1f43Iain Merricknamespace net {
55731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
56731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickclass SpdyProxyClientSocketTest : public PlatformTest {
57731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick public:
58731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  SpdyProxyClientSocketTest();
59731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
60731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  virtual void TearDown();
61731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
62731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick protected:
63731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  void Initialize(MockRead* reads, size_t reads_count, MockWrite* writes,
64731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                  size_t writes_count);
65731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  spdy::SpdyFrame* ConstructConnectRequestFrame();
66731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  spdy::SpdyFrame* ConstructConnectAuthRequestFrame();
67731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  spdy::SpdyFrame* ConstructConnectReplyFrame();
68731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  spdy::SpdyFrame* ConstructConnectAuthReplyFrame();
69731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  spdy::SpdyFrame* ConstructConnectErrorReplyFrame();
70731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  spdy::SpdyFrame* ConstructBodyFrame(const char* data, int length);
71731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_refptr<IOBufferWithSize> CreateBuffer(const char* data, int size);
72731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  void AssertConnectSucceeds();
73731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  void AssertConnectFails(int result);
74731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  void AssertConnectionEstablished();
75731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  void AssertSyncReadEquals(const char* data, int len);
76731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  void AssertAsyncReadEquals(const char* data, int len);
77731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  void AssertReadStarts(const char* data, int len);
78731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  void AssertReadReturns(const char* data, int len);
79731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  void AssertAsyncWriteSucceeds(const char* data, int len);
80731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  void AssertWriteReturns(const char* data, int len, int rv);
81731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  void AssertWriteLength(int len);
82731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  void AssertAsyncWriteWithReadsSucceeds(const char* data, int len,
83731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                        int num_reads);
84731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
85731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  void AddAuthToCache() {
86731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    const string16 kFoo(ASCIIToUTF16("foo"));
87731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    const string16 kBar(ASCIIToUTF16("bar"));
88dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    session_->http_auth_cache()->Add(GURL(kProxyUrl),
89dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                                     "MyRealm1",
90dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                                     HttpAuth::AUTH_SCHEME_BASIC,
91dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                                     "Basic realm=MyRealm1",
92dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                                     kFoo,
93dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                                     kBar,
94dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                                     "/");
95731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
96731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
97731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  void Run(int steps) {
98731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    data_->StopAfter(steps);
99731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    data_->Run();
100731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
101731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
102731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<SpdyProxyClientSocket> sock_;
103731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  TestCompletionCallback read_callback_;
104731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  TestCompletionCallback write_callback_;
105731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_refptr<DeterministicSocketData> data_;
106731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
107731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick private:
108731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_refptr<HttpNetworkSession> session_;
109731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_refptr<IOBuffer> read_buf_;
110731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  SpdySessionDependencies session_deps_;
111731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockConnect connect_data_;
112731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_refptr<SpdySession> spdy_session_;
113731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_refptr<SpdyStream> spdy_stream_;
114731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  spdy::SpdyFramer framer_;
115731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
116731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  std::string user_agent_;
117731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  GURL url_;
118731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  HostPortPair proxy_host_port_;
119731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  HostPortPair endpoint_host_port_pair_;
120731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ProxyServer proxy_;
121731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  HostPortProxyPair endpoint_host_port_proxy_pair_;
122ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_refptr<TransportSocketParams> transport_params_;
123731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
124731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DISALLOW_COPY_AND_ASSIGN(SpdyProxyClientSocketTest);
125731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick};
126731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
127731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickSpdyProxyClientSocketTest::SpdyProxyClientSocketTest()
128731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    : sock_(NULL),
129731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      read_callback_(),
130731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      write_callback_(),
131731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      data_(NULL),
132731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      session_(NULL),
133731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      read_buf_(NULL),
134731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      session_deps_(),
135731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      connect_data_(false, OK),
136731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      spdy_session_(NULL),
137731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      spdy_stream_(NULL),
138731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      framer_(),
139731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      user_agent_(kUserAgent),
140731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      url_(kUrl),
141731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      proxy_host_port_(kProxyHost, kProxyPort),
142731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      endpoint_host_port_pair_(kOriginHost, kOriginPort),
143731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      proxy_(ProxyServer::SCHEME_HTTPS, proxy_host_port_),
144731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      endpoint_host_port_proxy_pair_(endpoint_host_port_pair_, proxy_),
145ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      transport_params_(new TransportSocketParams(proxy_host_port_,
146ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                            LOWEST,
147ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                            url_,
148ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                            false,
149ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                            false)) {
150731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
151731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
152731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid SpdyProxyClientSocketTest::TearDown() {
153731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (session_ != NULL)
154731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    session_->spdy_session_pool()->CloseAllSessions();
155731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
156731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  spdy::SpdyFramer::set_enable_compression_default(true);
157731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Empty the current queue.
158731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MessageLoop::current()->RunAllPending();
159731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  PlatformTest::TearDown();
160731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
161731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
162731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid SpdyProxyClientSocketTest::Initialize(MockRead* reads,
163731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                           size_t reads_count,
164731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                           MockWrite* writes,
165731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                           size_t writes_count) {
166731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  data_ = new DeterministicSocketData(reads, reads_count, writes, writes_count);
167731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  data_->set_connect_data(connect_data_);
168731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  data_->SetStop(2);
169731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
170731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  session_deps_.deterministic_socket_factory->AddSocketDataProvider(
171731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      data_.get());
172731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  session_deps_.host_resolver->set_synchronous_mode(true);
173731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
174731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  session_ = SpdySessionDependencies::SpdyCreateSessionDeterministic(
175731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      &session_deps_);
176731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  SpdySession::SetSSLMode(false);
177731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  spdy::SpdyFramer::set_enable_compression_default(false);
178731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
179731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Creates a new spdy session
180731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  spdy_session_ =
181731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      session_->spdy_session_pool()->Get(endpoint_host_port_proxy_pair_,
182731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         BoundNetLog());
183731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
184731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Perform the TCP connect
185731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
186731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(OK,
187ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            connection->Init(endpoint_host_port_pair_.ToString(),
188ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                             transport_params_,
189ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                             LOWEST, NULL, session_->transport_socket_pool(),
190731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                             BoundNetLog()));
191731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  spdy_session_->InitializeWithSocket(connection.release(), false, OK);
192731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
193731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Create the SPDY Stream
194731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_EQ(
195731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      OK,
196731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      spdy_session_->CreateStream(url_, LOWEST, &spdy_stream_, BoundNetLog(),
197731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                  NULL));
198731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
199731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Create the SpdyProxyClientSocket
200731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  sock_.reset(
201731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      new SpdyProxyClientSocket(spdy_stream_, user_agent_,
202731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                endpoint_host_port_pair_, url_,
203dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                                proxy_host_port_, session_->http_auth_cache(),
204731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                session_->http_auth_handler_factory()));
205731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
206731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
207731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickscoped_refptr<IOBufferWithSize> SpdyProxyClientSocketTest::CreateBuffer(
208731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    const char* data, int size) {
209731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(size));
210731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  memcpy(buf->data(), data, size);
211731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  return buf;
212731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
213731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
214731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid SpdyProxyClientSocketTest::AssertConnectSucceeds() {
215731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_EQ(ERR_IO_PENDING, sock_->Connect(&read_callback_));
216731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  data_->Run();
217731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_EQ(OK, read_callback_.WaitForResult());
218731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
219731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
220731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid SpdyProxyClientSocketTest::AssertConnectFails(int result) {
221731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_EQ(ERR_IO_PENDING, sock_->Connect(&read_callback_));
222731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  data_->Run();
223731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_EQ(result, read_callback_.WaitForResult());
224731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
225731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
226731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid SpdyProxyClientSocketTest::AssertConnectionEstablished() {
227731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
228731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_TRUE(response != NULL);
229731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_EQ(200, response->headers->response_code());
230731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_EQ("Connection Established", response->headers->GetStatusText());
231731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
232731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
233731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid SpdyProxyClientSocketTest::AssertSyncReadEquals(const char* data,
234731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                                     int len) {
235731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_refptr<IOBuffer> buf(new IOBuffer(len));
236731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_EQ(len, sock_->Read(buf, len, NULL));
237731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_EQ(std::string(data, len), std::string(buf->data(), len));
238731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_TRUE(sock_->IsConnected());
239731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
240731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
241731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid SpdyProxyClientSocketTest::AssertAsyncReadEquals(const char* data,
242731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                                     int len) {
243731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  data_->StopAfter(1);
244731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Issue the read, which will be completed asynchronously
245731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_refptr<IOBuffer> buf(new IOBuffer(len));
246731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_EQ(ERR_IO_PENDING, sock_->Read(buf, len, &read_callback_));
247731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_TRUE(sock_->IsConnected());
248731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  data_->Run();
249731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
250731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_TRUE(sock_->IsConnected());
251731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
252731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Now the read will return
253731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(len, read_callback_.WaitForResult());
254731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_EQ(std::string(data, len), std::string(buf->data(), len));
255731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
256731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
257731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid SpdyProxyClientSocketTest::AssertReadStarts(const char* data, int len) {
258731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  data_->StopAfter(1);
259731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Issue the read, which will be completed asynchronously
260731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  read_buf_ = new IOBuffer(len);
261731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_EQ(ERR_IO_PENDING, sock_->Read(read_buf_, len, &read_callback_));
262731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_TRUE(sock_->IsConnected());
263731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
264731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
265731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid SpdyProxyClientSocketTest::AssertReadReturns(const char* data, int len) {
266731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_TRUE(sock_->IsConnected());
267731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
268731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Now the read will return
269731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(len, read_callback_.WaitForResult());
270731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_EQ(std::string(data, len), std::string(read_buf_->data(), len));
271731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
272731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
273731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid SpdyProxyClientSocketTest::AssertAsyncWriteSucceeds(const char* data,
274731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                                        int len) {
275731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertWriteReturns(data, len, ERR_IO_PENDING);
276731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  data_->RunFor(1);
277731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertWriteLength(len);
278731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
279731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
280731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid SpdyProxyClientSocketTest::AssertWriteReturns(const char* data, int len,
281731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                                   int rv) {
282731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_refptr<IOBufferWithSize> buf(CreateBuffer(data, len));
283731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(rv, sock_->Write(buf, buf->size(), &write_callback_));
284731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
285731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
286731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid SpdyProxyClientSocketTest::AssertWriteLength(int len) {
287731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(len, write_callback_.WaitForResult());
288731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
289731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
290731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid SpdyProxyClientSocketTest::AssertAsyncWriteWithReadsSucceeds(
291731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    const char* data, int len, int num_reads) {
292731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_refptr<IOBufferWithSize> buf(CreateBuffer(data, len));
293731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
294731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(ERR_IO_PENDING, sock_->Write(buf, buf->size(), &write_callback_));
295731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
296731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  for (int i = 0; i < num_reads; i++) {
297731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    Run(1);
298731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    AssertSyncReadEquals(kMsg2, kLen2);
299731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
300731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
301731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  write_callback_.WaitForResult();
302731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
303731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
304731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Constructs a standard SPDY SYN_STREAM frame for a CONNECT request.
305731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickspdy::SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectRequestFrame() {
306731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  const SpdyHeaderInfo kSynStartHeader = {
307731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    spdy::SYN_STREAM,
308731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    kStreamId,
309731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    0,
310731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    net::ConvertRequestPriorityToSpdyPriority(LOWEST),
311731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    spdy::CONTROL_FLAG_NONE,
312731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    false,
313731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    spdy::INVALID,
314731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    NULL,
315731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    0,
316731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    spdy::DATA_FLAG_NONE
317731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
318731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  const char* const kConnectHeaders[] = {
319731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    "method", "CONNECT",
320731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    "url", kOriginHostPort,
321731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    "host", kOriginHost,
322731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    "user-agent", kUserAgent,
323731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    "version", "HTTP/1.1",
324731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
325731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  return ConstructSpdyPacket(
326731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      kSynStartHeader, NULL, 0, kConnectHeaders, arraysize(kConnectHeaders)/2);
327731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
328731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
329731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Constructs a SPDY SYN_STREAM frame for a CONNECT request which includes
330731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Proxy-Authorization headers.
331731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickspdy::SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectAuthRequestFrame() {
332731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  const SpdyHeaderInfo kSynStartHeader = {
333731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    spdy::SYN_STREAM,
334731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    kStreamId,
335731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    0,
336731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    net::ConvertRequestPriorityToSpdyPriority(LOWEST),
337731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    spdy::CONTROL_FLAG_NONE,
338731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    false,
339731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    spdy::INVALID,
340731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    NULL,
341731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    0,
342731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    spdy::DATA_FLAG_NONE
343731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
344731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  const char* const kConnectHeaders[] = {
345731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    "method", "CONNECT",
346731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    "url", kOriginHostPort,
347731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    "host", kOriginHost,
348731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    "user-agent", kUserAgent,
349731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    "version", "HTTP/1.1",
350731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    "proxy-authorization", "Basic Zm9vOmJhcg==",
351731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
352731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  return ConstructSpdyPacket(
353731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      kSynStartHeader, NULL, 0, kConnectHeaders, arraysize(kConnectHeaders)/2);
354731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
355731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
356731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Constructs a standard SPDY SYN_REPLY frame to match the SPDY CONNECT.
357731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickspdy::SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectReplyFrame() {
358731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  const char* const kStandardReplyHeaders[] = {
359731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      "status", "200 Connection Established",
360731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      "version", "HTTP/1.1"
361731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
362731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  return ConstructSpdyControlFrame(NULL,
363731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                   0,
364731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                   false,
365731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                   kStreamId,
366731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                   LOWEST,
367731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                   spdy::SYN_REPLY,
368731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                   spdy::CONTROL_FLAG_NONE,
369731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                   kStandardReplyHeaders,
370731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                   arraysize(kStandardReplyHeaders));
371731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
372731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
373731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Constructs a standard SPDY SYN_REPLY frame to match the SPDY CONNECT.
374731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickspdy::SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectAuthReplyFrame() {
375731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  const char* const kStandardReplyHeaders[] = {
376731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      "status", "407 Proxy Authentication Required",
377731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      "version", "HTTP/1.1",
378731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      "proxy-authenticate", "Basic realm=\"MyRealm1\"",
379731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
380731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
381731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  return ConstructSpdyControlFrame(NULL,
382731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                   0,
383731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                   false,
384731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                   kStreamId,
385731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                   LOWEST,
386731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                   spdy::SYN_REPLY,
387731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                   spdy::CONTROL_FLAG_NONE,
388731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                   kStandardReplyHeaders,
389731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                   arraysize(kStandardReplyHeaders));
390731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
391731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
392731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Constructs a SPDY SYN_REPLY frame with an HTTP 500 error.
393731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickspdy::SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectErrorReplyFrame() {
394731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  const char* const kStandardReplyHeaders[] = {
395731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      "status", "500 Internal Server Error",
396731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      "version", "HTTP/1.1",
397731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
398731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
399731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  return ConstructSpdyControlFrame(NULL,
400731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                   0,
401731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                   false,
402731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                   kStreamId,
403731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                   LOWEST,
404731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                   spdy::SYN_REPLY,
405731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                   spdy::CONTROL_FLAG_NONE,
406731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                   kStandardReplyHeaders,
407731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                   arraysize(kStandardReplyHeaders));
408731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
409731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
410731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickspdy::SpdyFrame* SpdyProxyClientSocketTest::ConstructBodyFrame(const char* data,
411731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                                               int length) {
412731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  return framer_.CreateDataFrame(kStreamId, data, length, spdy::DATA_FLAG_NONE);
413731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
414731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
415731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// ----------- Connect
416731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
417731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(SpdyProxyClientSocketTest, ConnectSendsCorrectRequest) {
418731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
419731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockWrite writes[] = {
420731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockWrite(*conn, 0, false),
421731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
422731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
423731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
424731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockRead reads[] = {
425731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*resp, 1, true),
426731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    MockRead(true, 0, 3),  // EOF
427731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
428731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
429731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Initialize(reads, arraysize(reads), writes, arraysize(writes));
430731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
431731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_FALSE(sock_->IsConnected());
432731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
433731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertConnectSucceeds();
434731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
435731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertConnectionEstablished();
436731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
437731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
438731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(SpdyProxyClientSocketTest, ConnectWithAuthRequested) {
439731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
440731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockWrite writes[] = {
441731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockWrite(*conn, 0, false),
442731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
443731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
444731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectAuthReplyFrame());
445731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockRead reads[] = {
446731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*resp, 1, true),
447731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    MockRead(true, 0, 3),  // EOF
448731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
449731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
450731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Initialize(reads, arraysize(reads), writes, arraysize(writes));
451731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
452731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertConnectFails(ERR_TUNNEL_CONNECTION_FAILED);
453731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
454731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
455731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_TRUE(response != NULL);
456731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_EQ(407, response->headers->response_code());
457731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_EQ("Proxy Authentication Required",
458731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick            response->headers->GetStatusText());
459731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
460731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
461731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(SpdyProxyClientSocketTest, ConnectWithAuthCredentials) {
462731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectAuthRequestFrame());
463731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockWrite writes[] = {
464731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockWrite(*conn, 0, false),
465731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
466731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
467731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
468731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockRead reads[] = {
469731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*resp, 1, true),
470731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    MockRead(true, 0, 3),  // EOF
471731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
472731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
473731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Initialize(reads, arraysize(reads), writes, arraysize(writes));
474731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AddAuthToCache();
475731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
476731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertConnectSucceeds();
477731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
478731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertConnectionEstablished();
479731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
480731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
481731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(SpdyProxyClientSocketTest, ConnectFails) {
482731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
483731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockWrite writes[] = {
484731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockWrite(*conn, 0, false),
485731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
486731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
487731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
488731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockRead reads[] = {
489731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    MockRead(true, 0, 1),  // EOF
490731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
491731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
492731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Initialize(reads, arraysize(reads), writes, arraysize(writes));
493731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
494731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_FALSE(sock_->IsConnected());
495731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
496731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertConnectFails(ERR_CONNECTION_CLOSED);
497731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
498731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_FALSE(sock_->IsConnected());
499731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
500731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
501731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// ----------- WasEverUsed
502731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
503731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(SpdyProxyClientSocketTest, WasEverUsedReturnsCorrectValues) {
504731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
505731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockWrite writes[] = {
506731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockWrite(*conn, 0, false),
507731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
508731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
509731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
510731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockRead reads[] = {
511731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*resp, 1, true),
512731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    MockRead(true, 0, 2),  // EOF
513731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
514731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
515731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Initialize(reads, arraysize(reads), writes, arraysize(writes));
516731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
517731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_FALSE(sock_->WasEverUsed());
518731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertConnectSucceeds();
519731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_TRUE(sock_->WasEverUsed());
520731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  sock_->Disconnect();
521731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_TRUE(sock_->WasEverUsed());
522731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
523731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
524731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// ----------- GetPeerAddress
525731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
526731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(SpdyProxyClientSocketTest, GetPeerAddressReturnsCorrectValues) {
527731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
528731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockWrite writes[] = {
529731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockWrite(*conn, 0, false),
530731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
531731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
532731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
533731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockRead reads[] = {
534731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*resp, 1, true),
535731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    MockRead(true, 0, 2),  // EOF
536731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
537731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
538731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Initialize(reads, arraysize(reads), writes, arraysize(writes));
539731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
540731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  net::AddressList addr;
541731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr));
542731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
543731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertConnectSucceeds();
544731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_TRUE(sock_->IsConnected());
545731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(OK, sock_->GetPeerAddress(&addr));
546731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
547731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  sock_->Disconnect();
548731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->GetPeerAddress(&addr));
549731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
550731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
551731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// ----------- Write
552731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
553731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(SpdyProxyClientSocketTest, WriteSendsDataInDataFrame) {
554731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
555731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
556731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
557731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockWrite writes[] = {
558731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockWrite(*conn, 0, false),
559731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockWrite(*msg1, 2, false),
560731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockWrite(*msg2, 3, false),
561731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
562731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
563731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
564731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockRead reads[] = {
565731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*resp, 1, true),
566731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    MockRead(true, 0, 4),  // EOF
567731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
568731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
569731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Initialize(reads, arraysize(reads), writes, arraysize(writes));
570731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
571731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertConnectSucceeds();
572731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
573731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertAsyncWriteSucceeds(kMsg1, kLen1);
574731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertAsyncWriteSucceeds(kMsg2, kLen2);
575731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
576731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
577731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(SpdyProxyClientSocketTest, WriteSplitsLargeDataIntoMultipleFrames) {
578731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  std::string chunk_data(kMaxSpdyFrameChunkSize, 'x');
579731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
580731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> chunk(ConstructBodyFrame(chunk_data.data(),
581731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                                       chunk_data.length()));
582731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockWrite writes[] = {
583731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockWrite(*conn, 0, false),
584731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockWrite(*chunk, 2, false),
585731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockWrite(*chunk, 3, false),
586731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockWrite(*chunk, 4, false)
587731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
588731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
589731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
590731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockRead reads[] = {
591731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*resp, 1, true),
592731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    MockRead(true, 0, 5),  // EOF
593731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
594731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
595731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Initialize(reads, arraysize(reads), writes, arraysize(writes));
596731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
597731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertConnectSucceeds();
598731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
599731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  std::string big_data(kMaxSpdyFrameChunkSize * 3, 'x');
600731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_refptr<IOBufferWithSize> buf(CreateBuffer(big_data.data(),
601731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                                   big_data.length()));
602731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
603731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(ERR_IO_PENDING, sock_->Write(buf, buf->size(), &write_callback_));
604731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  data_->RunFor(3);
605731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
606731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(buf->size(), write_callback_.WaitForResult());
607731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
608731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
609731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// ----------- Read
610731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
611731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(SpdyProxyClientSocketTest, ReadReadsDataInDataFrame) {
612731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
613731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockWrite writes[] = {
614731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockWrite(*conn, 0, false),
615731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
616731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
617731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
618731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
619731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockRead reads[] = {
620731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*resp, 1, true),
621731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*msg1, 2, true),
622731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    MockRead(true, 0, 3),  // EOF
623731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
624731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
625731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Initialize(reads, arraysize(reads), writes, arraysize(writes));
626731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
627731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertConnectSucceeds();
628731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
629731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Run(1);  // SpdySession consumes the next read and sends it to
630731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick           // sock_ to be buffered.
631731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertSyncReadEquals(kMsg1, kLen1);
632731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
633731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
634731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(SpdyProxyClientSocketTest, ReadDataFromBufferedFrames) {
635731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
636731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockWrite writes[] = {
637731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockWrite(*conn, 0, false),
638731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
639731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
640731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
641731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
642731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
643731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockRead reads[] = {
644731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*resp, 1, true),
645731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*msg1, 2, true),
646731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*msg2, 3, true),
647731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    MockRead(true, 0, 4),  // EOF
648731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
649731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
650731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Initialize(reads, arraysize(reads), writes, arraysize(writes));
651731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
652731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertConnectSucceeds();
653731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
654731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Run(1);  // SpdySession consumes the next read and sends it to
655731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick           // sock_ to be buffered.
656731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertSyncReadEquals(kMsg1, kLen1);
657731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Run(1);  // SpdySession consumes the next read and sends it to
658731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick           // sock_ to be buffered.
659731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertSyncReadEquals(kMsg2, kLen2);
660731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
661731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
662731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(SpdyProxyClientSocketTest, ReadDataMultipleBufferedFrames) {
663731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
664731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockWrite writes[] = {
665731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockWrite(*conn, 0, false),
666731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
667731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
668731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
669731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
670731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
671731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockRead reads[] = {
672731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*resp, 1, true),
673731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*msg1, 2, true),
674731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*msg2, 3, true),
675731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    MockRead(true, 0, 4),  // EOF
676731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
677731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
678731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Initialize(reads, arraysize(reads), writes, arraysize(writes));
679731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
680731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertConnectSucceeds();
681731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
682731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Run(2);  // SpdySession consumes the next two reads and sends then to
683731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick           // sock_ to be buffered.
684731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertSyncReadEquals(kMsg1, kLen1);
685731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertSyncReadEquals(kMsg2, kLen2);
686731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
687731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
688731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(SpdyProxyClientSocketTest, LargeReadWillMergeDataFromDifferentFrames) {
689731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
690731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockWrite writes[] = {
691731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockWrite(*conn, 0, false),
692731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
693731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
694731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
695731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
696731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
697731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockRead reads[] = {
698731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*resp, 1, true),
699731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*msg3, 2, true),
700731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*msg3, 3, true),
701731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    MockRead(true, 0, 4),  // EOF
702731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
703731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
704731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Initialize(reads, arraysize(reads), writes, arraysize(writes));
705731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
706731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertConnectSucceeds();
707731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
708731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Run(2);  // SpdySession consumes the next two reads and sends then to
709731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick           // sock_ to be buffered.
710731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // The payload from two data frames, each with kMsg3 will be combined
711731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // together into a single read().
712731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertSyncReadEquals(kMsg33, kLen33);
713731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
714731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
715731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(SpdyProxyClientSocketTest, MultipleShortReadsThenMoreRead) {
716731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
717731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockWrite writes[] = {
718731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockWrite(*conn, 0, false),
719731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
720731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
721731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
722731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
723731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
724731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
725731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockRead reads[] = {
726731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*resp, 1, true),
727731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*msg1, 2, true),
728731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*msg3, 3, true),
729731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*msg3, 4, true),
730731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*msg2, 5, true),
731731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    MockRead(true, 0, 6),  // EOF
732731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
733731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
734731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Initialize(reads, arraysize(reads), writes, arraysize(writes));
735731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
736731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertConnectSucceeds();
737731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
738731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Run(4);  // SpdySession consumes the next four reads and sends then to
739731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick           // sock_ to be buffered.
740731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertSyncReadEquals(kMsg1, kLen1);
741731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // The payload from two data frames, each with kMsg3 will be combined
742731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // together into a single read().
743731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertSyncReadEquals(kMsg33, kLen33);
744731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertSyncReadEquals(kMsg2, kLen2);
745731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
746731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
747731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(SpdyProxyClientSocketTest, ReadWillSplitDataFromLargeFrame) {
748731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
749731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockWrite writes[] = {
750731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockWrite(*conn, 0, false),
751731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
752731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
753731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
754731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
755731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> msg33(ConstructBodyFrame(kMsg33, kLen33));
756731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
757731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockRead reads[] = {
758731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*resp, 1, true),
759731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*msg1, 2, true),
760731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*msg33, 3, true),
761731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    MockRead(true, 0, 4),  // EOF
762731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
763731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
764731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Initialize(reads, arraysize(reads), writes, arraysize(writes));
765731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
766731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertConnectSucceeds();
767731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
768731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Run(2);  // SpdySession consumes the next two reads and sends then to
769731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick           // sock_ to be buffered.
770731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertSyncReadEquals(kMsg1, kLen1);
771731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // The payload from the single large data frame will be read across
772731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // two different reads.
773731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertSyncReadEquals(kMsg3, kLen3);
774731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertSyncReadEquals(kMsg3, kLen3);
775731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
776731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
777731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(SpdyProxyClientSocketTest, MultipleReadsFromSameLargeFrame) {
778731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
779731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockWrite writes[] = {
780731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockWrite(*conn, 0, false),
781731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
782731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
783731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
784731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> msg333(ConstructBodyFrame(kMsg333, kLen333));
785731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockRead reads[] = {
786731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*resp, 1, true),
787731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*msg333, 2, true),
788731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    MockRead(true, 0, 3),  // EOF
789731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
790731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
791731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Initialize(reads, arraysize(reads), writes, arraysize(writes));
792731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
793731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertConnectSucceeds();
794731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
795731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Run(1);  // SpdySession consumes the next read and sends it to
796731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick           // sock_ to be buffered.
797731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // The payload from the single large data frame will be read across
798731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // two different reads.
799731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertSyncReadEquals(kMsg33, kLen33);
800731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
801731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Now attempt to do a read of more data than remains buffered
802731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_refptr<IOBuffer> buf(new IOBuffer(kLen33));
803731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_EQ(kLen3, sock_->Read(buf, kLen33, &read_callback_));
804731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_EQ(std::string(kMsg3, kLen3), std::string(buf->data(), kLen3));
805731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_TRUE(sock_->IsConnected());
806731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
807731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
808731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(SpdyProxyClientSocketTest, ReadAuthResponseBody) {
809731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
810731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockWrite writes[] = {
811731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockWrite(*conn, 0, false),
812731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
813731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
814731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectAuthReplyFrame());
815731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
816731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
817731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockRead reads[] = {
818731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*resp, 1, true),
819731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*msg1, 2, true),
820731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*msg2, 3, true),
821731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    MockRead(true, 0, 4),  // EOF
822731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
823731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
824731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Initialize(reads, arraysize(reads), writes, arraysize(writes));
825731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
826731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertConnectFails(ERR_TUNNEL_CONNECTION_FAILED);
827731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
828731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Run(2);  // SpdySession consumes the next two reads and sends then to
829731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick           // sock_ to be buffered.
830731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertSyncReadEquals(kMsg1, kLen1);
831731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertSyncReadEquals(kMsg2, kLen2);
832731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
833731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
834731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(SpdyProxyClientSocketTest, ReadErrorResponseBody) {
835731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
836731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockWrite writes[] = {
837731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockWrite(*conn, 0, false),
838731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
839731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
840731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectErrorReplyFrame());
841731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
842731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
843731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockRead reads[] = {
844731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*resp, 1, true),
845731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*msg1, 2, true),
846731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*msg2, 3, true),
847731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    MockRead(true, 0, 4),  // EOF
848731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
849731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
850731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Initialize(reads, arraysize(reads), writes, arraysize(writes));
851731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
85221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  AssertConnectFails(ERR_HTTPS_PROXY_TUNNEL_RESPONSE);
853731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
854731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Run(2);  // SpdySession consumes the next two reads and sends then to
855731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick           // sock_ to be buffered.
85621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->Read(NULL, 1, NULL));
85721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  scoped_refptr<IOBuffer> buf(new IOBuffer(kLen1 + kLen2));
85821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  scoped_ptr<HttpStream> stream(sock_->CreateConnectResponseStream());
85921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  stream->ReadResponseBody(buf, kLen1 + kLen2, &read_callback_);
860731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
861731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
862731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// ----------- Reads and Writes
863731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
864731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(SpdyProxyClientSocketTest, AsyncReadAroundWrite) {
865731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
866731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
867731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockWrite writes[] = {
868731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockWrite(*conn, 0, false),
869731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockWrite(*msg2, 3, false),
870731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
871731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
872731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
873731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
874731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
875731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockRead reads[] = {
876731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*resp, 1, true),
877731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*msg1, 2, true),  // sync read
878731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*msg3, 4, true),  // async read
879731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    MockRead(true, 0, 5),  // EOF
880731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
881731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
882731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Initialize(reads, arraysize(reads), writes, arraysize(writes));
883731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
884731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertConnectSucceeds();
885731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
886731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Run(1);
887731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertSyncReadEquals(kMsg1, kLen1);
888731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
889731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertReadStarts(kMsg3, kLen3);
890731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Read should block until after the write succeeds
891731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
892731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertAsyncWriteSucceeds(kMsg2, kLen2);  // Runs 1 step
893731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
894731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_FALSE(read_callback_.have_result());
895731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Run(1);
896731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Now the read will return
897731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertReadReturns(kMsg3, kLen3);
898731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
899731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
900731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(SpdyProxyClientSocketTest, AsyncWriteAroundReads) {
901731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
902731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
903731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockWrite writes[] = {
904731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockWrite(*conn, 0, false),
905731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockWrite(*msg2, 4, true),
906731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
907731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
908731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
909731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
910731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
911731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockRead reads[] = {
912731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*resp, 1, true),
913731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*msg1, 2, true),
914731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*msg3, 3, true),
915731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    MockRead(true, 0, 5),  // EOF
916731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
917731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
918731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Initialize(reads, arraysize(reads), writes, arraysize(writes));
919731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
920731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertConnectSucceeds();
921731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
922731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Run(1);
923731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertSyncReadEquals(kMsg1, kLen1);
924731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Write should block until the read completes
925731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertWriteReturns(kMsg2, kLen2, ERR_IO_PENDING);
926731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
927731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertAsyncReadEquals(kMsg3, kLen3);
928731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
929731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_FALSE(write_callback_.have_result());
930731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
931731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Now the write will complete
932731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Run(1);
933731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertWriteLength(kLen2);
934731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
935731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
936731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// ----------- Reading/Writing on Closed socket
937731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
938731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Reading from an already closed socket should return 0
939731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(SpdyProxyClientSocketTest, ReadOnClosedSocketReturnsZero) {
940731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
941731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockWrite writes[] = {
942731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockWrite(*conn, 0, false),
943731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
944731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
945731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
946731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockRead reads[] = {
947731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*resp, 1, true),
948731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    MockRead(true, 0, 2),  // EOF
949731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
950731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
951731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Initialize(reads, arraysize(reads), writes, arraysize(writes));
952731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
953731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertConnectSucceeds();
954731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
955731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Run(1);
956731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
957731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_EQ(0, sock_->Read(NULL, 1, NULL));
958731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_EQ(ERR_CONNECTION_CLOSED, sock_->Read(NULL, 1, NULL));
959731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_EQ(ERR_CONNECTION_CLOSED, sock_->Read(NULL, 1, NULL));
960731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
961731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
962731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Read pending when socket is closed should return 0
963731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(SpdyProxyClientSocketTest, PendingReadOnCloseReturnsZero) {
964731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
965731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockWrite writes[] = {
966731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockWrite(*conn, 0, false),
967731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
968731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
969731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
970731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockRead reads[] = {
971731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*resp, 1, true),
972731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    MockRead(true, 0, 2),  // EOF
973731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
974731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
975731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Initialize(reads, arraysize(reads), writes, arraysize(writes));
976731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
977731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertConnectSucceeds();
978731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
979731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertReadStarts(kMsg1, kLen1);
980731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
981731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Run(1);
982731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
983731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_EQ(0, read_callback_.WaitForResult());
984731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
985731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
986731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Reading from a disconnected socket is an error
987731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(SpdyProxyClientSocketTest, ReadOnDisconnectSocketReturnsNotConnected) {
988731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
989731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockWrite writes[] = {
990731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockWrite(*conn, 0, false),
991731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
992731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
993731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
994731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockRead reads[] = {
995731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*resp, 1, true),
996731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    MockRead(true, 0, 2),  // EOF
997731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
998731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
999731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Initialize(reads, arraysize(reads), writes, arraysize(writes));
1000731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1001731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertConnectSucceeds();
1002731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1003731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  sock_->Disconnect();
1004731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1005731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->Read(NULL, 1, NULL));
1006731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
1007731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1008731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Reading buffered data from an already closed socket should return
1009731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// buffered data, then 0.
1010731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(SpdyProxyClientSocketTest, ReadOnClosedSocketReturnsBufferedData) {
1011731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
1012731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockWrite writes[] = {
1013731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockWrite(*conn, 0, false),
1014731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
1015731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1016731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
1017731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
1018731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockRead reads[] = {
1019731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*resp, 1, true),
1020731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*msg1, 2, true),
1021731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    MockRead(true, 0, 3),  // EOF
1022731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
1023731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1024731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Initialize(reads, arraysize(reads), writes, arraysize(writes));
1025731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1026731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertConnectSucceeds();
1027731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1028731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Run(2);
1029731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1030731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertSyncReadEquals(kMsg1, kLen1);
1031731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_EQ(0, sock_->Read(NULL, 1, NULL));
1032731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_EQ(ERR_CONNECTION_CLOSED, sock_->Read(NULL, 1, NULL));
1033731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Verify that read *still* returns ERR_CONNECTION_CLOSED
1034731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_EQ(ERR_CONNECTION_CLOSED, sock_->Read(NULL, 1, NULL));
1035731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
1036731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1037731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Calling Write() on a closed socket is an error
1038731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(SpdyProxyClientSocketTest, WriteOnClosedStream) {
1039731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
1040731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockWrite writes[] = {
1041731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockWrite(*conn, 0, false),
1042731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
1043731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1044731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
1045731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
1046731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockRead reads[] = {
1047731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*resp, 1, true),
1048731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    MockRead(true, 0, 2),  // EOF
1049731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
1050731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1051731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Initialize(reads, arraysize(reads), writes, arraysize(writes));
1052731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1053731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertConnectSucceeds();
1054731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1055731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Run(1);  // Read EOF which will close the stream
1056731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
1057731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(ERR_CONNECTION_CLOSED, sock_->Write(buf, buf->size(), NULL));
1058731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
1059731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1060731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Calling Write() on a disconnected socket is an error
1061731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(SpdyProxyClientSocketTest, WriteOnDisconnectedSocket) {
1062731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
1063731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockWrite writes[] = {
1064731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockWrite(*conn, 0, false),
1065731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
1066731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1067731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
1068731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
1069731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockRead reads[] = {
1070731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*resp, 1, true),
1071731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    MockRead(true, 0, 2),  // EOF
1072731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
1073731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1074731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Initialize(reads, arraysize(reads), writes, arraysize(writes));
1075731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1076731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertConnectSucceeds();
1077731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1078731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  sock_->Disconnect();
1079731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1080731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
1081731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, sock_->Write(buf, buf->size(), NULL));
1082731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
1083731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1084731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// If the socket is closed with a pending Write(), the callback
1085731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// should be called with ERR_CONNECTION_CLOSED.
1086731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(SpdyProxyClientSocketTest, WritePendingOnClose) {
1087731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
1088731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockWrite writes[] = {
1089731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockWrite(*conn, 0, false),
1090731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    MockWrite(true, ERR_IO_PENDING, 2),
1091731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
1092731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1093731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
1094731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockRead reads[] = {
1095731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*resp, 1, true),
1096731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    MockRead(true, 0, 3),  // EOF
1097731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
1098731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1099731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Initialize(reads, arraysize(reads), writes, arraysize(writes));
1100731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1101731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertConnectSucceeds();
1102731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1103731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_TRUE(sock_->IsConnected());
1104731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1105731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
1106731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(ERR_IO_PENDING, sock_->Write(buf, buf->size(), &write_callback_));
1107731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1108731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Run(1);
1109731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1110731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(ERR_CONNECTION_CLOSED, write_callback_.WaitForResult());
1111731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
1112731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1113731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// If the socket is Disconnected with a pending Write(), the callback
1114731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// should not be called.
1115731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(SpdyProxyClientSocketTest, DisconnectWithWritePending) {
1116731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
1117731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockWrite writes[] = {
1118731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockWrite(*conn, 0, false),
1119731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    MockWrite(false, 0, 2),  // EOF
1120731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
1121731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1122731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
1123731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockRead reads[] = {
1124731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*resp, 1, true),
1125731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    MockRead(true, 0, 3),  // EOF
1126731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
1127731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1128731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Initialize(reads, arraysize(reads), writes, arraysize(writes));
1129731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1130731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertConnectSucceeds();
1131731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1132731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_TRUE(sock_->IsConnected());
1133731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1134731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
1135731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(ERR_IO_PENDING, sock_->Write(buf, buf->size(), &write_callback_));
1136731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1137731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  sock_->Disconnect();
1138731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1139731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_FALSE(sock_->IsConnected());
1140731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_FALSE(write_callback_.have_result());
1141731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
1142731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1143731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// If the socket is Disconnected with a pending Read(), the callback
1144731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// should not be called.
1145731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(SpdyProxyClientSocketTest, DisconnectWithReadPending) {
1146731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame());
1147731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockWrite writes[] = {
1148731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockWrite(*conn, 0, false),
1149731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
1150731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1151731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectReplyFrame());
1152731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockRead reads[] = {
1153731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*resp, 1, true),
1154731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    MockRead(true, 0, 2),  // EOF
1155731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
1156731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1157731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Initialize(reads, arraysize(reads), writes, arraysize(writes));
1158731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1159731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AssertConnectSucceeds();
1160731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1161731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_TRUE(sock_->IsConnected());
1162731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1163731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_refptr<IOBuffer> buf(new IOBuffer(kLen1));
1164731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_EQ(ERR_IO_PENDING, sock_->Read(buf, kLen1, &read_callback_));
1165731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1166731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  sock_->Disconnect();
1167731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1168731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_FALSE(sock_->IsConnected());
1169731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_FALSE(read_callback_.have_result());
1170731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
1171731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1172731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}  // namespace net
1173