| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "net/http/http_proxy_client_socket_pool.h" | |
| 6 | |
| 7 #include "base/callback.h" | |
| 8 #include "base/compiler_specific.h" | |
| 9 #include "base/string_util.h" | |
| 10 #include "base/utf_string_conversions.h" | |
| 11 #include "net/base/mock_host_resolver.h" | |
| 12 #include "net/base/net_errors.h" | |
| 13 #include "net/base/ssl_config_service_defaults.h" | |
| 14 #include "net/base/test_completion_callback.h" | |
| 15 #include "net/http/http_auth_handler_factory.h" | |
| 16 #include "net/http/http_network_session.h" | |
| 17 #include "net/http/http_proxy_client_socket.h" | |
| 18 #include "net/http/http_server_properties_impl.h" | |
| 19 #include "net/proxy/proxy_service.h" | |
| 20 #include "net/socket/client_socket_handle.h" | |
| 21 #include "net/socket/client_socket_pool_histograms.h" | |
| 22 #include "net/socket/socket_test_util.h" | |
| 23 #include "net/spdy/spdy_protocol.h" | |
| 24 #include "net/spdy/spdy_test_util_spdy2.h" | |
| 25 #include "testing/gtest/include/gtest/gtest.h" | |
| 26 | |
| 27 using namespace net::test_spdy2; | |
| 28 | |
| 29 namespace net { | |
| 30 | |
| 31 namespace { | |
| 32 | |
| 33 const int kMaxSockets = 32; | |
| 34 const int kMaxSocketsPerGroup = 6; | |
| 35 const char * const kAuthHeaders[] = { | |
| 36 "proxy-authorization", "Basic Zm9vOmJhcg==" | |
| 37 }; | |
| 38 const int kAuthHeadersSize = arraysize(kAuthHeaders) / 2; | |
| 39 | |
| 40 enum HttpProxyType { | |
| 41 HTTP, | |
| 42 HTTPS, | |
| 43 SPDY | |
| 44 }; | |
| 45 | |
| 46 typedef ::testing::TestWithParam<HttpProxyType> TestWithHttpParam; | |
| 47 | |
| 48 } // namespace | |
| 49 | |
| 50 class HttpProxyClientSocketPoolSpdy21Test : public TestWithHttpParam { | |
| 51 protected: | |
| 52 HttpProxyClientSocketPoolSpdy21Test() | |
| 53 : ssl_config_(), | |
| 54 ignored_transport_socket_params_(new TransportSocketParams( | |
| 55 HostPortPair("proxy", 80), LOWEST, false, false)), | |
| 56 ignored_ssl_socket_params_(new SSLSocketParams( | |
| 57 ignored_transport_socket_params_, NULL, NULL, | |
| 58 ProxyServer::SCHEME_DIRECT, HostPortPair("www.google.com", 443), | |
| 59 ssl_config_, 0, false, false)), | |
| 60 tcp_histograms_("MockTCP"), | |
| 61 transport_socket_pool_( | |
| 62 kMaxSockets, kMaxSocketsPerGroup, | |
| 63 &tcp_histograms_, | |
| 64 &socket_factory_), | |
| 65 ssl_histograms_("MockSSL"), | |
| 66 cert_verifier_(CertVerifier::CreateDefault()), | |
| 67 proxy_service_(ProxyService::CreateDirect()), | |
| 68 ssl_config_service_(new SSLConfigServiceDefaults), | |
| 69 ssl_socket_pool_(kMaxSockets, kMaxSocketsPerGroup, | |
| 70 &ssl_histograms_, | |
| 71 &host_resolver_, | |
| 72 cert_verifier_.get(), | |
| 73 NULL /* server_bound_cert_store */, | |
| 74 NULL /* transport_security_state */, | |
| 75 NULL /* ssl_host_info_factory */, | |
| 76 "" /* ssl_session_cache_shard */, | |
| 77 &socket_factory_, | |
| 78 &transport_socket_pool_, | |
| 79 NULL, | |
| 80 NULL, | |
| 81 ssl_config_service_.get(), | |
| 82 BoundNetLog().net_log()), | |
| 83 http_auth_handler_factory_( | |
| 84 HttpAuthHandlerFactory::CreateDefault(&host_resolver_)), | |
| 85 session_(CreateNetworkSession()), | |
| 86 http_proxy_histograms_("HttpProxyUnitTest"), | |
| 87 ssl_data_(NULL), | |
| 88 data_(NULL), | |
| 89 pool_(kMaxSockets, kMaxSocketsPerGroup, | |
| 90 &http_proxy_histograms_, | |
| 91 NULL, | |
| 92 &transport_socket_pool_, | |
| 93 &ssl_socket_pool_, | |
| 94 NULL) { | |
| 95 } | |
| 96 | |
| 97 virtual ~HttpProxyClientSocketPoolSpdy21Test() { | |
| 98 } | |
| 99 | |
| 100 void AddAuthToCache() { | |
| 101 const string16 kFoo(ASCIIToUTF16("foo")); | |
| 102 const string16 kBar(ASCIIToUTF16("bar")); | |
| 103 GURL proxy_url(GetParam() == HTTP ? "http://proxy" : "https://proxy:80"); | |
| 104 session_->http_auth_cache()->Add(proxy_url, | |
| 105 "MyRealm1", | |
| 106 HttpAuth::AUTH_SCHEME_BASIC, | |
| 107 "Basic realm=MyRealm1", | |
| 108 AuthCredentials(kFoo, kBar), | |
| 109 "/"); | |
| 110 } | |
| 111 | |
| 112 scoped_refptr<TransportSocketParams> GetTcpParams() { | |
| 113 if (GetParam() != HTTP) | |
| 114 return scoped_refptr<TransportSocketParams>(); | |
| 115 return ignored_transport_socket_params_; | |
| 116 } | |
| 117 | |
| 118 scoped_refptr<SSLSocketParams> GetSslParams() { | |
| 119 if (GetParam() == HTTP) | |
| 120 return scoped_refptr<SSLSocketParams>(); | |
| 121 return ignored_ssl_socket_params_; | |
| 122 } | |
| 123 | |
| 124 // Returns the a correctly constructed HttpProxyParms | |
| 125 // for the HTTP or HTTPS proxy. | |
| 126 scoped_refptr<HttpProxySocketParams> GetParams(bool tunnel) { | |
| 127 return scoped_refptr<HttpProxySocketParams>( | |
| 128 new HttpProxySocketParams( | |
| 129 GetTcpParams(), | |
| 130 GetSslParams(), | |
| 131 GURL(tunnel ? "https://www.google.com/" : "http://www.google.com"), | |
| 132 "", | |
| 133 HostPortPair("www.google.com", tunnel ? 443 : 80), | |
| 134 session_->http_auth_cache(), | |
| 135 session_->http_auth_handler_factory(), | |
| 136 session_->spdy_session_pool(), | |
| 137 tunnel)); | |
| 138 } | |
| 139 | |
| 140 scoped_refptr<HttpProxySocketParams> GetTunnelParams() { | |
| 141 return GetParams(true); | |
| 142 } | |
| 143 | |
| 144 scoped_refptr<HttpProxySocketParams> GetNoTunnelParams() { | |
| 145 return GetParams(false); | |
| 146 } | |
| 147 | |
| 148 DeterministicMockClientSocketFactory& socket_factory() { | |
| 149 return socket_factory_; | |
| 150 } | |
| 151 | |
| 152 void Initialize(MockRead* reads, size_t reads_count, | |
| 153 MockWrite* writes, size_t writes_count, | |
| 154 MockRead* spdy_reads, size_t spdy_reads_count, | |
| 155 MockWrite* spdy_writes, size_t spdy_writes_count) { | |
| 156 if (GetParam() == SPDY) | |
| 157 data_ = new DeterministicSocketData(spdy_reads, spdy_reads_count, | |
| 158 spdy_writes, spdy_writes_count); | |
| 159 else | |
| 160 data_ = new DeterministicSocketData(reads, reads_count, writes, | |
| 161 writes_count); | |
| 162 | |
| 163 data_->set_connect_data(MockConnect(SYNCHRONOUS, OK)); | |
| 164 data_->StopAfter(2); // Request / Response | |
| 165 | |
| 166 socket_factory_.AddSocketDataProvider(data_.get()); | |
| 167 | |
| 168 if (GetParam() != HTTP) { | |
| 169 ssl_data_.reset(new SSLSocketDataProvider(SYNCHRONOUS, OK)); | |
| 170 if (GetParam() == SPDY) { | |
| 171 InitializeSpdySsl(); | |
| 172 } | |
| 173 socket_factory_.AddSSLSocketDataProvider(ssl_data_.get()); | |
| 174 } | |
| 175 } | |
| 176 | |
| 177 void InitializeSpdySsl() { | |
| 178 ssl_data_->SetNextProto(kProtoSPDY21); | |
| 179 } | |
| 180 | |
| 181 HttpNetworkSession* CreateNetworkSession() { | |
| 182 HttpNetworkSession::Params params; | |
| 183 params.host_resolver = &host_resolver_; | |
| 184 params.cert_verifier = cert_verifier_.get(); | |
| 185 params.proxy_service = proxy_service_.get(); | |
| 186 params.client_socket_factory = &socket_factory_; | |
| 187 params.ssl_config_service = ssl_config_service_; | |
| 188 params.http_auth_handler_factory = http_auth_handler_factory_.get(); | |
| 189 params.http_server_properties = &http_server_properties_; | |
| 190 return new HttpNetworkSession(params); | |
| 191 } | |
| 192 | |
| 193 private: | |
| 194 SSLConfig ssl_config_; | |
| 195 | |
| 196 scoped_refptr<TransportSocketParams> ignored_transport_socket_params_; | |
| 197 scoped_refptr<SSLSocketParams> ignored_ssl_socket_params_; | |
| 198 ClientSocketPoolHistograms tcp_histograms_; | |
| 199 DeterministicMockClientSocketFactory socket_factory_; | |
| 200 MockTransportClientSocketPool transport_socket_pool_; | |
| 201 ClientSocketPoolHistograms ssl_histograms_; | |
| 202 MockHostResolver host_resolver_; | |
| 203 scoped_ptr<CertVerifier> cert_verifier_; | |
| 204 const scoped_ptr<ProxyService> proxy_service_; | |
| 205 const scoped_refptr<SSLConfigService> ssl_config_service_; | |
| 206 SSLClientSocketPool ssl_socket_pool_; | |
| 207 | |
| 208 const scoped_ptr<HttpAuthHandlerFactory> http_auth_handler_factory_; | |
| 209 HttpServerPropertiesImpl http_server_properties_; | |
| 210 const scoped_refptr<HttpNetworkSession> session_; | |
| 211 ClientSocketPoolHistograms http_proxy_histograms_; | |
| 212 SpdyTestStateHelper spdy_state_; | |
| 213 | |
| 214 protected: | |
| 215 scoped_ptr<SSLSocketDataProvider> ssl_data_; | |
| 216 scoped_refptr<DeterministicSocketData> data_; | |
| 217 HttpProxyClientSocketPool pool_; | |
| 218 ClientSocketHandle handle_; | |
| 219 TestCompletionCallback callback_; | |
| 220 }; | |
| 221 | |
| 222 //----------------------------------------------------------------------------- | |
| 223 // All tests are run with three different proxy types: HTTP, HTTPS (non-SPDY) | |
| 224 // and SPDY. | |
| 225 INSTANTIATE_TEST_CASE_P(HttpProxyClientSocketPoolSpdy21Tests, | |
| 226 HttpProxyClientSocketPoolSpdy21Test, | |
| 227 ::testing::Values(HTTP, HTTPS, SPDY)); | |
| 228 | |
| 229 TEST_P(HttpProxyClientSocketPoolSpdy21Test, NoTunnel) { | |
| 230 Initialize(NULL, 0, NULL, 0, NULL, 0, NULL, 0); | |
| 231 | |
| 232 int rv = handle_.Init("a", GetNoTunnelParams(), LOW, CompletionCallback(), | |
| 233 &pool_, BoundNetLog()); | |
| 234 EXPECT_EQ(OK, rv); | |
| 235 EXPECT_TRUE(handle_.is_initialized()); | |
| 236 ASSERT_TRUE(handle_.socket()); | |
| 237 HttpProxyClientSocket* tunnel_socket = | |
| 238 static_cast<HttpProxyClientSocket*>(handle_.socket()); | |
| 239 EXPECT_TRUE(tunnel_socket->IsConnected()); | |
| 240 } | |
| 241 | |
| 242 TEST_P(HttpProxyClientSocketPoolSpdy21Test, NeedAuth) { | |
| 243 MockWrite writes[] = { | |
| 244 MockWrite(ASYNC, 0, "CONNECT www.google.com:443 HTTP/1.1\r\n" | |
| 245 "Host: www.google.com\r\n" | |
| 246 "Proxy-Connection: keep-alive\r\n\r\n"), | |
| 247 }; | |
| 248 MockRead reads[] = { | |
| 249 // No credentials. | |
| 250 MockRead(ASYNC, 1, "HTTP/1.1 407 Proxy Authentication Required\r\n"), | |
| 251 MockRead(ASYNC, 2, "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), | |
| 252 MockRead(ASYNC, 3, "Content-Length: 10\r\n\r\n"), | |
| 253 MockRead(ASYNC, 4, "0123456789"), | |
| 254 }; | |
| 255 scoped_ptr<SpdyFrame> req(ConstructSpdyConnect(NULL, 0, 1)); | |
| 256 scoped_ptr<SpdyFrame> rst(ConstructSpdyRstStream(1, CANCEL)); | |
| 257 MockWrite spdy_writes[] = { | |
| 258 CreateMockWrite(*req, 0, ASYNC), | |
| 259 CreateMockWrite(*rst, 2, ASYNC), | |
| 260 }; | |
| 261 static const char* const kAuthChallenge[] = { | |
| 262 "status", "407 Proxy Authentication Required", | |
| 263 "version", "HTTP/1.1", | |
| 264 "proxy-authenticate", "Basic realm=\"MyRealm1\"", | |
| 265 }; | |
| 266 scoped_ptr<SpdyFrame> resp( | |
| 267 | |
| 268 ConstructSpdyControlFrame(NULL, | |
| 269 0, | |
| 270 false, | |
| 271 1, | |
| 272 LOWEST, | |
| 273 SYN_REPLY, | |
| 274 CONTROL_FLAG_NONE, | |
| 275 kAuthChallenge, | |
| 276 arraysize(kAuthChallenge))); | |
| 277 MockRead spdy_reads[] = { | |
| 278 CreateMockWrite(*resp, 1, ASYNC), | |
| 279 MockRead(ASYNC, 0, 3) | |
| 280 }; | |
| 281 | |
| 282 Initialize(reads, arraysize(reads), writes, arraysize(writes), | |
| 283 spdy_reads, arraysize(spdy_reads), spdy_writes, | |
| 284 arraysize(spdy_writes)); | |
| 285 | |
| 286 data_->StopAfter(4); | |
| 287 int rv = handle_.Init("a", GetTunnelParams(), LOW, callback_.callback(), | |
| 288 &pool_, BoundNetLog()); | |
| 289 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 290 EXPECT_FALSE(handle_.is_initialized()); | |
| 291 EXPECT_FALSE(handle_.socket()); | |
| 292 | |
| 293 data_->RunFor(GetParam() == SPDY ? 2 : 4); | |
| 294 rv = callback_.WaitForResult(); | |
| 295 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, rv); | |
| 296 EXPECT_TRUE(handle_.is_initialized()); | |
| 297 ASSERT_TRUE(handle_.socket()); | |
| 298 ProxyClientSocket* tunnel_socket = | |
| 299 static_cast<ProxyClientSocket*>(handle_.socket()); | |
| 300 if (GetParam() == SPDY) { | |
| 301 EXPECT_TRUE(tunnel_socket->IsConnected()); | |
| 302 EXPECT_TRUE(tunnel_socket->IsUsingSpdy()); | |
| 303 } else { | |
| 304 EXPECT_FALSE(tunnel_socket->IsConnected()); | |
| 305 EXPECT_FALSE(tunnel_socket->IsUsingSpdy()); | |
| 306 EXPECT_FALSE(tunnel_socket->IsUsingSpdy()); | |
| 307 } | |
| 308 } | |
| 309 | |
| 310 TEST_P(HttpProxyClientSocketPoolSpdy21Test, HaveAuth) { | |
| 311 // It's pretty much impossible to make the SPDY case behave synchronously | |
| 312 // so we skip this test for SPDY | |
| 313 if (GetParam() == SPDY) | |
| 314 return; | |
| 315 MockWrite writes[] = { | |
| 316 MockWrite(SYNCHRONOUS, 0, | |
| 317 "CONNECT www.google.com:443 HTTP/1.1\r\n" | |
| 318 "Host: www.google.com\r\n" | |
| 319 "Proxy-Connection: keep-alive\r\n" | |
| 320 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), | |
| 321 }; | |
| 322 MockRead reads[] = { | |
| 323 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"), | |
| 324 }; | |
| 325 | |
| 326 Initialize(reads, arraysize(reads), writes, arraysize(writes), NULL, 0, | |
| 327 NULL, 0); | |
| 328 AddAuthToCache(); | |
| 329 | |
| 330 int rv = handle_.Init("a", GetTunnelParams(), LOW, callback_.callback(), | |
| 331 &pool_, BoundNetLog()); | |
| 332 EXPECT_EQ(OK, rv); | |
| 333 EXPECT_TRUE(handle_.is_initialized()); | |
| 334 ASSERT_TRUE(handle_.socket()); | |
| 335 HttpProxyClientSocket* tunnel_socket = | |
| 336 static_cast<HttpProxyClientSocket*>(handle_.socket()); | |
| 337 EXPECT_TRUE(tunnel_socket->IsConnected()); | |
| 338 } | |
| 339 | |
| 340 TEST_P(HttpProxyClientSocketPoolSpdy21Test, AsyncHaveAuth) { | |
| 341 MockWrite writes[] = { | |
| 342 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" | |
| 343 "Host: www.google.com\r\n" | |
| 344 "Proxy-Connection: keep-alive\r\n" | |
| 345 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), | |
| 346 }; | |
| 347 MockRead reads[] = { | |
| 348 MockRead(SYNCHRONOUS, "HTTP/1.1 200 Connection Established\r\n\r\n"), | |
| 349 }; | |
| 350 | |
| 351 scoped_ptr<SpdyFrame> req(ConstructSpdyConnect(kAuthHeaders, | |
| 352 kAuthHeadersSize, 1)); | |
| 353 MockWrite spdy_writes[] = { | |
| 354 CreateMockWrite(*req, 0, ASYNC) | |
| 355 }; | |
| 356 scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); | |
| 357 MockRead spdy_reads[] = { | |
| 358 CreateMockRead(*resp, 1, ASYNC), | |
| 359 MockRead(ASYNC, 0, 2) | |
| 360 }; | |
| 361 | |
| 362 Initialize(reads, arraysize(reads), writes, arraysize(writes), | |
| 363 spdy_reads, arraysize(spdy_reads), spdy_writes, | |
| 364 arraysize(spdy_writes)); | |
| 365 AddAuthToCache(); | |
| 366 | |
| 367 int rv = handle_.Init("a", GetTunnelParams(), LOW, callback_.callback(), | |
| 368 &pool_, BoundNetLog()); | |
| 369 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 370 EXPECT_FALSE(handle_.is_initialized()); | |
| 371 EXPECT_FALSE(handle_.socket()); | |
| 372 | |
| 373 data_->RunFor(2); | |
| 374 EXPECT_EQ(OK, callback_.WaitForResult()); | |
| 375 EXPECT_TRUE(handle_.is_initialized()); | |
| 376 ASSERT_TRUE(handle_.socket()); | |
| 377 HttpProxyClientSocket* tunnel_socket = | |
| 378 static_cast<HttpProxyClientSocket*>(handle_.socket()); | |
| 379 EXPECT_TRUE(tunnel_socket->IsConnected()); | |
| 380 } | |
| 381 | |
| 382 TEST_P(HttpProxyClientSocketPoolSpdy21Test, TCPError) { | |
| 383 if (GetParam() == SPDY) return; | |
| 384 data_ = new DeterministicSocketData(NULL, 0, NULL, 0); | |
| 385 data_->set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_CLOSED)); | |
| 386 | |
| 387 socket_factory().AddSocketDataProvider(data_.get()); | |
| 388 | |
| 389 int rv = handle_.Init("a", GetTunnelParams(), LOW, callback_.callback(), | |
| 390 &pool_, BoundNetLog()); | |
| 391 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 392 EXPECT_FALSE(handle_.is_initialized()); | |
| 393 EXPECT_FALSE(handle_.socket()); | |
| 394 | |
| 395 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, callback_.WaitForResult()); | |
| 396 | |
| 397 EXPECT_FALSE(handle_.is_initialized()); | |
| 398 EXPECT_FALSE(handle_.socket()); | |
| 399 } | |
| 400 | |
| 401 TEST_P(HttpProxyClientSocketPoolSpdy21Test, SSLError) { | |
| 402 if (GetParam() == HTTP) return; | |
| 403 data_ = new DeterministicSocketData(NULL, 0, NULL, 0); | |
| 404 data_->set_connect_data(MockConnect(ASYNC, OK)); | |
| 405 socket_factory().AddSocketDataProvider(data_.get()); | |
| 406 | |
| 407 ssl_data_.reset(new SSLSocketDataProvider(ASYNC, | |
| 408 ERR_CERT_AUTHORITY_INVALID)); | |
| 409 if (GetParam() == SPDY) { | |
| 410 InitializeSpdySsl(); | |
| 411 } | |
| 412 socket_factory().AddSSLSocketDataProvider(ssl_data_.get()); | |
| 413 | |
| 414 int rv = handle_.Init("a", GetTunnelParams(), LOW, callback_.callback(), | |
| 415 &pool_, BoundNetLog()); | |
| 416 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 417 EXPECT_FALSE(handle_.is_initialized()); | |
| 418 EXPECT_FALSE(handle_.socket()); | |
| 419 | |
| 420 EXPECT_EQ(ERR_PROXY_CERTIFICATE_INVALID, callback_.WaitForResult()); | |
| 421 | |
| 422 EXPECT_FALSE(handle_.is_initialized()); | |
| 423 EXPECT_FALSE(handle_.socket()); | |
| 424 } | |
| 425 | |
| 426 TEST_P(HttpProxyClientSocketPoolSpdy21Test, SslClientAuth) { | |
| 427 if (GetParam() == HTTP) return; | |
| 428 data_ = new DeterministicSocketData(NULL, 0, NULL, 0); | |
| 429 data_->set_connect_data(MockConnect(ASYNC, OK)); | |
| 430 socket_factory().AddSocketDataProvider(data_.get()); | |
| 431 | |
| 432 ssl_data_.reset(new SSLSocketDataProvider(ASYNC, | |
| 433 ERR_SSL_CLIENT_AUTH_CERT_NEEDED)); | |
| 434 if (GetParam() == SPDY) { | |
| 435 InitializeSpdySsl(); | |
| 436 } | |
| 437 socket_factory().AddSSLSocketDataProvider(ssl_data_.get()); | |
| 438 | |
| 439 int rv = handle_.Init("a", GetTunnelParams(), LOW, callback_.callback(), | |
| 440 &pool_, BoundNetLog()); | |
| 441 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 442 EXPECT_FALSE(handle_.is_initialized()); | |
| 443 EXPECT_FALSE(handle_.socket()); | |
| 444 | |
| 445 EXPECT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, callback_.WaitForResult()); | |
| 446 | |
| 447 EXPECT_FALSE(handle_.is_initialized()); | |
| 448 EXPECT_FALSE(handle_.socket()); | |
| 449 } | |
| 450 | |
| 451 TEST_P(HttpProxyClientSocketPoolSpdy21Test, TunnelUnexpectedClose) { | |
| 452 MockWrite writes[] = { | |
| 453 MockWrite(ASYNC, 0, | |
| 454 "CONNECT www.google.com:443 HTTP/1.1\r\n" | |
| 455 "Host: www.google.com\r\n" | |
| 456 "Proxy-Connection: keep-alive\r\n" | |
| 457 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), | |
| 458 }; | |
| 459 MockRead reads[] = { | |
| 460 MockRead(ASYNC, 1, "HTTP/1.1 200 Conn"), | |
| 461 MockRead(ASYNC, ERR_CONNECTION_CLOSED, 2), | |
| 462 }; | |
| 463 scoped_ptr<SpdyFrame> req(ConstructSpdyConnect(kAuthHeaders, | |
| 464 kAuthHeadersSize, 1)); | |
| 465 MockWrite spdy_writes[] = { | |
| 466 CreateMockWrite(*req, 0, ASYNC) | |
| 467 }; | |
| 468 MockRead spdy_reads[] = { | |
| 469 MockRead(ASYNC, ERR_CONNECTION_CLOSED, 1), | |
| 470 }; | |
| 471 | |
| 472 Initialize(reads, arraysize(reads), writes, arraysize(writes), | |
| 473 spdy_reads, arraysize(spdy_reads), spdy_writes, | |
| 474 arraysize(spdy_writes)); | |
| 475 AddAuthToCache(); | |
| 476 | |
| 477 int rv = handle_.Init("a", GetTunnelParams(), LOW, callback_.callback(), | |
| 478 &pool_, BoundNetLog()); | |
| 479 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 480 EXPECT_FALSE(handle_.is_initialized()); | |
| 481 EXPECT_FALSE(handle_.socket()); | |
| 482 | |
| 483 data_->RunFor(3); | |
| 484 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback_.WaitForResult()); | |
| 485 EXPECT_FALSE(handle_.is_initialized()); | |
| 486 EXPECT_FALSE(handle_.socket()); | |
| 487 } | |
| 488 | |
| 489 TEST_P(HttpProxyClientSocketPoolSpdy21Test, TunnelSetupError) { | |
| 490 MockWrite writes[] = { | |
| 491 MockWrite(ASYNC, 0, | |
| 492 "CONNECT www.google.com:443 HTTP/1.1\r\n" | |
| 493 "Host: www.google.com\r\n" | |
| 494 "Proxy-Connection: keep-alive\r\n" | |
| 495 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), | |
| 496 }; | |
| 497 MockRead reads[] = { | |
| 498 MockRead(ASYNC, 1, "HTTP/1.1 304 Not Modified\r\n\r\n"), | |
| 499 }; | |
| 500 scoped_ptr<SpdyFrame> req(ConstructSpdyConnect(kAuthHeaders, | |
| 501 kAuthHeadersSize, 1)); | |
| 502 scoped_ptr<SpdyFrame> rst(ConstructSpdyRstStream(1, CANCEL)); | |
| 503 MockWrite spdy_writes[] = { | |
| 504 CreateMockWrite(*req, 0, ASYNC), | |
| 505 CreateMockWrite(*rst, 2, ASYNC), | |
| 506 }; | |
| 507 scoped_ptr<SpdyFrame> resp(ConstructSpdySynReplyError(1)); | |
| 508 MockRead spdy_reads[] = { | |
| 509 CreateMockRead(*resp, 1, ASYNC), | |
| 510 MockRead(ASYNC, 0, 3), | |
| 511 }; | |
| 512 | |
| 513 Initialize(reads, arraysize(reads), writes, arraysize(writes), | |
| 514 spdy_reads, arraysize(spdy_reads), spdy_writes, | |
| 515 arraysize(spdy_writes)); | |
| 516 AddAuthToCache(); | |
| 517 | |
| 518 int rv = handle_.Init("a", GetTunnelParams(), LOW, callback_.callback(), | |
| 519 &pool_, BoundNetLog()); | |
| 520 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 521 EXPECT_FALSE(handle_.is_initialized()); | |
| 522 EXPECT_FALSE(handle_.socket()); | |
| 523 | |
| 524 data_->RunFor(2); | |
| 525 | |
| 526 rv = callback_.WaitForResult(); | |
| 527 if (GetParam() == HTTP) { | |
| 528 // HTTP Proxy CONNECT responses are not trustworthy | |
| 529 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv); | |
| 530 EXPECT_FALSE(handle_.is_initialized()); | |
| 531 EXPECT_FALSE(handle_.socket()); | |
| 532 } else { | |
| 533 // HTTPS or SPDY Proxy CONNECT responses are trustworthy | |
| 534 EXPECT_EQ(ERR_HTTPS_PROXY_TUNNEL_RESPONSE, rv); | |
| 535 EXPECT_TRUE(handle_.is_initialized()); | |
| 536 EXPECT_TRUE(handle_.socket()); | |
| 537 } | |
| 538 } | |
| 539 | |
| 540 // It would be nice to also test the timeouts in HttpProxyClientSocketPool. | |
| 541 | |
| 542 } // namespace net | |
| OLD | NEW |