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