15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_proxy_client_socket_pool.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
97d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/strings/string_util.h"
10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/test_completion_callback.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_network_session.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_proxy_client_socket.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_response_headers.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/client_socket_handle.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/client_socket_pool_histograms.h"
18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/socket/next_proto.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/socket_test_util.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/spdy_protocol.h"
21eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "net/spdy/spdy_test_util_common.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMaxSockets = 32;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMaxSocketsPerGroup = 6;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char * const kAuthHeaders[] = {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "proxy-authorization", "Basic Zm9vOmJhcg=="
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kAuthHeadersSize = arraysize(kAuthHeaders) / 2;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum HttpProxyType {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HTTP,
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HTTPS,
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SPDY
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstruct HttpProxyClientSocketPoolTestParams {
42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpProxyClientSocketPoolTestParams()
43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      : proxy_type(HTTP),
44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        protocol(kProtoSPDY2) {}
45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
46eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpProxyClientSocketPoolTestParams(
47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      HttpProxyType proxy_type,
48eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      NextProto protocol)
49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      : proxy_type(proxy_type),
50eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        protocol(protocol) {}
51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpProxyType proxy_type;
53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  NextProto protocol;
54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch};
55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef ::testing::TestWithParam<HttpProxyType> TestWithHttpParam;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass HttpProxyClientSocketPoolTest
61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    : public ::testing::TestWithParam<HttpProxyClientSocketPoolTestParams> {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpProxyClientSocketPoolTest()
64eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      : session_deps_(GetParam().protocol),
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        ssl_config_(),
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        ignored_transport_socket_params_(
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            new TransportSocketParams(HostPortPair("proxy", 80),
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                      LOWEST,
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                      false,
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                      false,
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                      OnHostResolutionCallback())),
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        ignored_ssl_socket_params_(
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            new SSLSocketParams(ignored_transport_socket_params_,
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                NULL,
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                NULL,
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                ProxyServer::SCHEME_DIRECT,
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                HostPortPair("www.google.com", 443),
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                ssl_config_,
797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                kPrivacyModeDisabled,
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                0,
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                false,
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                false)),
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        tcp_histograms_("MockTCP"),
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        transport_socket_pool_(
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            kMaxSockets,
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            kMaxSocketsPerGroup,
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            &tcp_histograms_,
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            session_deps_.deterministic_socket_factory.get()),
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ssl_histograms_("MockSSL"),
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        ssl_socket_pool_(kMaxSockets,
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         kMaxSocketsPerGroup,
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         &ssl_histograms_,
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         session_deps_.host_resolver.get(),
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         session_deps_.cert_verifier.get(),
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         NULL /* server_bound_cert_store */,
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         NULL /* transport_security_state */,
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         std::string() /* ssl_session_cache_shard */,
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         session_deps_.deterministic_socket_factory.get(),
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         &transport_socket_pool_,
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         NULL,
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         NULL,
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         session_deps_.ssl_config_service.get(),
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         BoundNetLog().net_log()),
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        session_(CreateNetworkSession()),
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        http_proxy_histograms_("HttpProxyUnitTest"),
106eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        spdy_util_(GetParam().protocol),
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        pool_(kMaxSockets,
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              kMaxSocketsPerGroup,
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              &http_proxy_histograms_,
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              NULL,
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              &transport_socket_pool_,
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              &ssl_socket_pool_,
1137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)              NULL) {}
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  virtual ~HttpProxyClientSocketPoolTest() {
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddAuthToCache() {
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::string16 kFoo(ASCIIToUTF16("foo"));
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::string16 kBar(ASCIIToUTF16("bar"));
121eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    GURL proxy_url(GetParam().proxy_type == HTTP ? "http://proxy" : "https://proxy:80");
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    session_->http_auth_cache()->Add(proxy_url,
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     "MyRealm1",
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     HttpAuth::AUTH_SCHEME_BASIC,
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     "Basic realm=MyRealm1",
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     AuthCredentials(kFoo, kBar),
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     "/");
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<TransportSocketParams> GetTcpParams() {
131eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (GetParam().proxy_type != HTTP)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return scoped_refptr<TransportSocketParams>();
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ignored_transport_socket_params_;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<SSLSocketParams> GetSslParams() {
137eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (GetParam().proxy_type == HTTP)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return scoped_refptr<SSLSocketParams>();
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ignored_ssl_socket_params_;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the a correctly constructed HttpProxyParms
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // for the HTTP or HTTPS proxy.
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<HttpProxySocketParams> GetParams(bool tunnel) {
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return scoped_refptr<HttpProxySocketParams>(new HttpProxySocketParams(
146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        GetTcpParams(),
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        GetSslParams(),
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        GURL(tunnel ? "https://www.google.com/" : "http://www.google.com"),
149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        std::string(),
150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        HostPortPair("www.google.com", tunnel ? 443 : 80),
151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        session_->http_auth_cache(),
152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        session_->http_auth_handler_factory(),
153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        session_->spdy_session_pool(),
154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        tunnel));
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<HttpProxySocketParams> GetTunnelParams() {
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return GetParams(true);
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<HttpProxySocketParams> GetNoTunnelParams() {
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return GetParams(false);
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DeterministicMockClientSocketFactory& socket_factory() {
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return *session_deps_.deterministic_socket_factory.get();
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Initialize(MockRead* reads, size_t reads_count,
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  MockWrite* writes, size_t writes_count,
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  MockRead* spdy_reads, size_t spdy_reads_count,
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  MockWrite* spdy_writes, size_t spdy_writes_count) {
173eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (GetParam().proxy_type == SPDY) {
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_.reset(new DeterministicSocketData(spdy_reads, spdy_reads_count,
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              spdy_writes, spdy_writes_count));
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_.reset(new DeterministicSocketData(reads, reads_count, writes,
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              writes_count));
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    data_->set_connect_data(MockConnect(SYNCHRONOUS, OK));
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    data_->StopAfter(2);  // Request / Response
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    socket_factory().AddSocketDataProvider(data_.get());
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
186eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (GetParam().proxy_type != HTTP) {
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ssl_data_.reset(new SSLSocketDataProvider(SYNCHRONOUS, OK));
188eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      if (GetParam().proxy_type == SPDY) {
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        InitializeSpdySsl();
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      socket_factory().AddSSLSocketDataProvider(ssl_data_.get());
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void InitializeSpdySsl() {
196eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    ssl_data_->SetNextProto(GetParam().protocol);
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpNetworkSession* CreateNetworkSession() {
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return SpdySessionDependencies::SpdyCreateSessionDeterministic(
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        &session_deps_);
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SpdySessionDependencies session_deps_;
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLConfig ssl_config_;
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<TransportSocketParams> ignored_transport_socket_params_;
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<SSLSocketParams> ignored_ssl_socket_params_;
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClientSocketPoolHistograms tcp_histograms_;
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockTransportClientSocketPool transport_socket_pool_;
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClientSocketPoolHistograms ssl_histograms_;
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockHostResolver host_resolver_;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<CertVerifier> cert_verifier_;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLClientSocketPool ssl_socket_pool_;
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const scoped_refptr<HttpNetworkSession> session_;
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClientSocketPoolHistograms http_proxy_histograms_;
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
221a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  SpdyTestUtil spdy_util_;
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SSLSocketDataProvider> ssl_data_;
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DeterministicSocketData> data_;
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpProxyClientSocketPool pool_;
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClientSocketHandle handle_;
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback_;
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//-----------------------------------------------------------------------------
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// All tests are run with three different proxy types: HTTP, HTTPS (non-SPDY)
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and SPDY.
232eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch//
233eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// TODO(akalin): Use ::testing::Combine() when we are able to use
234eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// <tr1/tuple>.
235eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochINSTANTIATE_TEST_CASE_P(
236eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    HttpProxyClientSocketPoolTests,
237eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    HttpProxyClientSocketPoolTest,
238eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    ::testing::Values(
239eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        HttpProxyClientSocketPoolTestParams(HTTP, kProtoSPDY2),
240eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        HttpProxyClientSocketPoolTestParams(HTTPS, kProtoSPDY2),
241eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        HttpProxyClientSocketPoolTestParams(SPDY, kProtoSPDY2),
242eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        HttpProxyClientSocketPoolTestParams(HTTP, kProtoSPDY3),
243eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        HttpProxyClientSocketPoolTestParams(HTTPS, kProtoSPDY3),
244eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        HttpProxyClientSocketPoolTestParams(SPDY, kProtoSPDY3),
245eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        HttpProxyClientSocketPoolTestParams(HTTP, kProtoSPDY31),
246eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        HttpProxyClientSocketPoolTestParams(HTTPS, kProtoSPDY31),
247eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        HttpProxyClientSocketPoolTestParams(SPDY, kProtoSPDY31),
248eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        HttpProxyClientSocketPoolTestParams(HTTP, kProtoSPDY4a2),
249eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        HttpProxyClientSocketPoolTestParams(HTTPS, kProtoSPDY4a2),
250558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        HttpProxyClientSocketPoolTestParams(SPDY, kProtoSPDY4a2),
251558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        HttpProxyClientSocketPoolTestParams(HTTP, kProtoHTTP2Draft04),
252558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        HttpProxyClientSocketPoolTestParams(HTTPS, kProtoHTTP2Draft04),
253558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        HttpProxyClientSocketPoolTestParams(SPDY, kProtoHTTP2Draft04)));
254eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
255eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpProxyClientSocketPoolTest, NoTunnel) {
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Initialize(NULL, 0, NULL, 0, NULL, 0, NULL, 0);
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = handle_.Init("a", GetNoTunnelParams(), LOW, CompletionCallback(),
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        &pool_, BoundNetLog());
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(handle_.is_initialized());
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(handle_.socket());
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpProxyClientSocket* tunnel_socket =
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          static_cast<HttpProxyClientSocket*>(handle_.socket());
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(tunnel_socket->IsConnected());
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
268eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpProxyClientSocketPoolTest, NeedAuth) {
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes[] = {
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(ASYNC, 0, "CONNECT www.google.com:443 HTTP/1.1\r\n"
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads[] = {
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // No credentials.
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 1, "HTTP/1.1 407 Proxy Authentication Required\r\n"),
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 2, "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 3, "Content-Length: 10\r\n\r\n"),
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 4, "0123456789"),
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
28190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
28290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyConnect(NULL, 0, 1));
28390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> rst(
28490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req, 0, ASYNC),
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*rst, 2, ASYNC),
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
289eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const char* const kAuthChallenge[] = {
290eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    spdy_util_.GetStatusKey(), "407 Proxy Authentication Required",
291eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    spdy_util_.GetVersionKey(), "HTTP/1.1",
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "proxy-authenticate", "Basic realm=\"MyRealm1\"",
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(
295a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      spdy_util_.ConstructSpdyControlFrame(NULL,
296a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           0,
297a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           false,
298a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           1,
299a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           LOWEST,
300a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           SYN_REPLY,
301a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           CONTROL_FLAG_NONE,
302a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           kAuthChallenge,
303a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           arraysize(kAuthChallenge),
304a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           0));
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp, 1, ASYNC),
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 3)
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Initialize(reads, arraysize(reads), writes, arraysize(writes),
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             spdy_reads, arraysize(spdy_reads), spdy_writes,
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             arraysize(spdy_writes));
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data_->StopAfter(4);
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = handle_.Init("a", GetTunnelParams(), LOW, callback_.callback(),
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        &pool_, BoundNetLog());
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.is_initialized());
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.socket());
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
321eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  data_->RunFor(GetParam().proxy_type == SPDY ? 2 : 4);
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback_.WaitForResult();
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, rv);
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(handle_.is_initialized());
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(handle_.socket());
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyClientSocket* tunnel_socket =
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<ProxyClientSocket*>(handle_.socket());
328eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (GetParam().proxy_type == SPDY) {
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(tunnel_socket->IsConnected());
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(tunnel_socket->IsUsingSpdy());
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(tunnel_socket->IsConnected());
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(tunnel_socket->IsUsingSpdy());
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(tunnel_socket->IsUsingSpdy());
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
338eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpProxyClientSocketPoolTest, HaveAuth) {
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // It's pretty much impossible to make the SPDY case behave synchronously
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // so we skip this test for SPDY
341eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (GetParam().proxy_type == SPDY)
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes[] = {
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(SYNCHRONOUS, 0,
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "CONNECT www.google.com:443 HTTP/1.1\r\n"
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads[] = {
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Initialize(reads, arraysize(reads), writes, arraysize(writes), NULL, 0,
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             NULL, 0);
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddAuthToCache();
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = handle_.Init("a", GetTunnelParams(), LOW, callback_.callback(),
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        &pool_, BoundNetLog());
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(handle_.is_initialized());
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(handle_.socket());
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpProxyClientSocket* tunnel_socket =
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          static_cast<HttpProxyClientSocket*>(handle_.socket());
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(tunnel_socket->IsConnected());
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
368eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpProxyClientSocketPoolTest, AsyncHaveAuth) {
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes[] = {
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(ASYNC, 0, "CONNECT www.google.com:443 HTTP/1.1\r\n"
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads[] = {
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
38090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyConnect(kAuthHeaders, kAuthHeadersSize, 1));
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req, 0, ASYNC)
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
384eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp, 1, ASYNC),
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 2)
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Initialize(reads, arraysize(reads), writes, arraysize(writes),
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             spdy_reads, arraysize(spdy_reads), spdy_writes,
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             arraysize(spdy_writes));
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddAuthToCache();
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = handle_.Init("a", GetTunnelParams(), LOW, callback_.callback(),
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        &pool_, BoundNetLog());
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.is_initialized());
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.socket());
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data_->RunFor(2);
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback_.WaitForResult());
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(handle_.is_initialized());
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(handle_.socket());
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpProxyClientSocket* tunnel_socket =
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          static_cast<HttpProxyClientSocket*>(handle_.socket());
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(tunnel_socket->IsConnected());
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
410eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpProxyClientSocketPoolTest, TCPError) {
411eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (GetParam().proxy_type == SPDY) return;
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data_.reset(new DeterministicSocketData(NULL, 0, NULL, 0));
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data_->set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_CLOSED));
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  socket_factory().AddSocketDataProvider(data_.get());
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = handle_.Init("a", GetTunnelParams(), LOW, callback_.callback(),
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        &pool_, BoundNetLog());
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.is_initialized());
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.socket());
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, callback_.WaitForResult());
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.is_initialized());
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.socket());
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
429eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpProxyClientSocketPoolTest, SSLError) {
430eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (GetParam().proxy_type == HTTP) return;
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data_.reset(new DeterministicSocketData(NULL, 0, NULL, 0));
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data_->set_connect_data(MockConnect(ASYNC, OK));
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  socket_factory().AddSocketDataProvider(data_.get());
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data_.reset(new SSLSocketDataProvider(ASYNC,
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            ERR_CERT_AUTHORITY_INVALID));
437eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (GetParam().proxy_type == SPDY) {
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InitializeSpdySsl();
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  socket_factory().AddSSLSocketDataProvider(ssl_data_.get());
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = handle_.Init("a", GetTunnelParams(), LOW, callback_.callback(),
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        &pool_, BoundNetLog());
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.is_initialized());
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.socket());
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_PROXY_CERTIFICATE_INVALID, callback_.WaitForResult());
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.is_initialized());
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.socket());
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
454eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpProxyClientSocketPoolTest, SslClientAuth) {
455eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (GetParam().proxy_type == HTTP) return;
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data_.reset(new DeterministicSocketData(NULL, 0, NULL, 0));
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data_->set_connect_data(MockConnect(ASYNC, OK));
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  socket_factory().AddSocketDataProvider(data_.get());
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data_.reset(new SSLSocketDataProvider(ASYNC,
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
462eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (GetParam().proxy_type == SPDY) {
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InitializeSpdySsl();
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  socket_factory().AddSSLSocketDataProvider(ssl_data_.get());
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = handle_.Init("a", GetTunnelParams(), LOW, callback_.callback(),
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        &pool_, BoundNetLog());
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.is_initialized());
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.socket());
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, callback_.WaitForResult());
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.is_initialized());
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.socket());
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
479eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpProxyClientSocketPoolTest, TunnelUnexpectedClose) {
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes[] = {
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(ASYNC, 0,
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "CONNECT www.google.com:443 HTTP/1.1\r\n"
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads[] = {
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 1, "HTTP/1.1 200 Conn"),
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, ERR_CONNECTION_CLOSED, 2),
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
49190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
49290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyConnect(kAuthHeaders, kAuthHeadersSize, 1));
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req, 0, ASYNC)
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, ERR_CONNECTION_CLOSED, 1),
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Initialize(reads, arraysize(reads), writes, arraysize(writes),
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             spdy_reads, arraysize(spdy_reads), spdy_writes,
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             arraysize(spdy_writes));
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddAuthToCache();
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = handle_.Init("a", GetTunnelParams(), LOW, callback_.callback(),
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        &pool_, BoundNetLog());
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.is_initialized());
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.socket());
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data_->RunFor(3);
512eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (GetParam().proxy_type == SPDY) {
513868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // SPDY cannot process a headers block unless it's complete and so it
514868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // returns ERR_CONNECTION_CLOSED in this case.
515868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_EQ(ERR_CONNECTION_CLOSED, callback_.WaitForResult());
516868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  } else {
5177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    EXPECT_EQ(ERR_RESPONSE_HEADERS_TRUNCATED, callback_.WaitForResult());
518868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.is_initialized());
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.socket());
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52318bf6eff4fb54bcd655b30cbcda8d102e23e4e2fSelim GurunTEST_P(HttpProxyClientSocketPoolTest, Tunnel1xxResponse) {
52418bf6eff4fb54bcd655b30cbcda8d102e23e4e2fSelim Gurun  // Tests that 1xx responses are rejected for a CONNECT request.
52518bf6eff4fb54bcd655b30cbcda8d102e23e4e2fSelim Gurun  if (GetParam().proxy_type == SPDY) {
52618bf6eff4fb54bcd655b30cbcda8d102e23e4e2fSelim Gurun    // SPDY doesn't have 1xx responses.
52718bf6eff4fb54bcd655b30cbcda8d102e23e4e2fSelim Gurun    return;
52818bf6eff4fb54bcd655b30cbcda8d102e23e4e2fSelim Gurun  }
52918bf6eff4fb54bcd655b30cbcda8d102e23e4e2fSelim Gurun
53018bf6eff4fb54bcd655b30cbcda8d102e23e4e2fSelim Gurun  MockWrite writes[] = {
53118bf6eff4fb54bcd655b30cbcda8d102e23e4e2fSelim Gurun    MockWrite(ASYNC, 0,
53218bf6eff4fb54bcd655b30cbcda8d102e23e4e2fSelim Gurun              "CONNECT www.google.com:443 HTTP/1.1\r\n"
53318bf6eff4fb54bcd655b30cbcda8d102e23e4e2fSelim Gurun              "Host: www.google.com\r\n"
53418bf6eff4fb54bcd655b30cbcda8d102e23e4e2fSelim Gurun              "Proxy-Connection: keep-alive\r\n\r\n"),
53518bf6eff4fb54bcd655b30cbcda8d102e23e4e2fSelim Gurun  };
53618bf6eff4fb54bcd655b30cbcda8d102e23e4e2fSelim Gurun  MockRead reads[] = {
53718bf6eff4fb54bcd655b30cbcda8d102e23e4e2fSelim Gurun    MockRead(ASYNC, 1, "HTTP/1.1 100 Continue\r\n\r\n"),
53818bf6eff4fb54bcd655b30cbcda8d102e23e4e2fSelim Gurun    MockRead(ASYNC, 2, "HTTP/1.1 200 Connection Established\r\n\r\n"),
53918bf6eff4fb54bcd655b30cbcda8d102e23e4e2fSelim Gurun  };
54018bf6eff4fb54bcd655b30cbcda8d102e23e4e2fSelim Gurun
54118bf6eff4fb54bcd655b30cbcda8d102e23e4e2fSelim Gurun  Initialize(reads, arraysize(reads), writes, arraysize(writes),
54218bf6eff4fb54bcd655b30cbcda8d102e23e4e2fSelim Gurun             NULL, 0, NULL, 0);
54318bf6eff4fb54bcd655b30cbcda8d102e23e4e2fSelim Gurun
54418bf6eff4fb54bcd655b30cbcda8d102e23e4e2fSelim Gurun  int rv = handle_.Init("a", CreateTunnelParams(), LOW, callback_.callback(),
54518bf6eff4fb54bcd655b30cbcda8d102e23e4e2fSelim Gurun                        &pool_, BoundNetLog());
54618bf6eff4fb54bcd655b30cbcda8d102e23e4e2fSelim Gurun  EXPECT_EQ(ERR_IO_PENDING, rv);
54718bf6eff4fb54bcd655b30cbcda8d102e23e4e2fSelim Gurun  EXPECT_FALSE(handle_.is_initialized());
54818bf6eff4fb54bcd655b30cbcda8d102e23e4e2fSelim Gurun  EXPECT_FALSE(handle_.socket());
54918bf6eff4fb54bcd655b30cbcda8d102e23e4e2fSelim Gurun
55018bf6eff4fb54bcd655b30cbcda8d102e23e4e2fSelim Gurun  data_->RunFor(2);
55118bf6eff4fb54bcd655b30cbcda8d102e23e4e2fSelim Gurun  EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, callback_.WaitForResult());
55218bf6eff4fb54bcd655b30cbcda8d102e23e4e2fSelim Gurun}
55318bf6eff4fb54bcd655b30cbcda8d102e23e4e2fSelim Gurun
554eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpProxyClientSocketPoolTest, TunnelSetupError) {
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes[] = {
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(ASYNC, 0,
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "CONNECT www.google.com:443 HTTP/1.1\r\n"
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads[] = {
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 1, "HTTP/1.1 304 Not Modified\r\n\r\n"),
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
56590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
56690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyConnect(kAuthHeaders, kAuthHeadersSize, 1));
56790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> rst(
56890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req, 0, ASYNC),
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*rst, 2, ASYNC),
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
573eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdySynReplyError(1));
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp, 1, ASYNC),
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 3),
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Initialize(reads, arraysize(reads), writes, arraysize(writes),
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             spdy_reads, arraysize(spdy_reads), spdy_writes,
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             arraysize(spdy_writes));
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddAuthToCache();
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = handle_.Init("a", GetTunnelParams(), LOW, callback_.callback(),
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        &pool_, BoundNetLog());
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.is_initialized());
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.socket());
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data_->RunFor(2);
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback_.WaitForResult();
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // All Proxy CONNECT responses are not trustworthy
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.is_initialized());
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.socket());
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
599eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpProxyClientSocketPoolTest, TunnelSetupRedirect) {
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string redirectTarget = "https://foo.google.com/";
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string responseText = "HTTP/1.1 302 Found\r\n"
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   "Location: " + redirectTarget + "\r\n"
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   "Set-Cookie: foo=bar\r\n"
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   "\r\n";
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes[] = {
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(ASYNC, 0,
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "CONNECT www.google.com:443 HTTP/1.1\r\n"
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads[] = {
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 1, responseText.c_str()),
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> req(
61790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyConnect(kAuthHeaders, kAuthHeadersSize, 1));
61890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> rst(
61990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req, 0, ASYNC),
623eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    CreateMockWrite(*rst, 3, ASYNC),
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* const responseHeaders[] = {
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "location", redirectTarget.c_str(),
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "set-cookie", "foo=bar",
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int responseHeadersSize = arraysize(responseHeaders) / 2;
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(
632eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      spdy_util_.ConstructSpdySynReplyError(
633eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          "302 Found",
634eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          responseHeaders, responseHeadersSize,
635eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          1));
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp, 1, ASYNC),
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 2),
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Initialize(reads, arraysize(reads), writes, arraysize(writes),
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             spdy_reads, arraysize(spdy_reads), spdy_writes,
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             arraysize(spdy_writes));
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddAuthToCache();
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = handle_.Init("a", GetTunnelParams(), LOW, callback_.callback(),
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        &pool_, BoundNetLog());
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.is_initialized());
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.socket());
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data_->RunFor(2);
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback_.WaitForResult();
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
656eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (GetParam().proxy_type == HTTP) {
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We don't trust 302 responses to CONNECT from HTTP proxies.
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(handle_.is_initialized());
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(handle_.socket());
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Expect ProxyClientSocket to return the proxy's response, sanitized.
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_HTTPS_PROXY_TUNNEL_RESPONSE, rv);
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(handle_.is_initialized());
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(handle_.socket());
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ProxyClientSocket* tunnel_socket =
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        static_cast<ProxyClientSocket*>(handle_.socket());
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = tunnel_socket->GetConnectResponseInfo();
670868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const HttpResponseHeaders* headers = response->headers.get();
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Make sure Set-Cookie header was stripped.
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(headers->HasHeader("set-cookie"));
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Make sure Content-Length: 0 header was added.
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(headers->HasHeaderValue("content-length", "0"));
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Make sure Location header was included and correct.
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string location;
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(headers->IsRedirect(&location));
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(location, redirectTarget);
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// It would be nice to also test the timeouts in HttpProxyClientSocketPool.
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
688