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"
121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "net/base/proxy_delegate.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/test_completion_callback.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_network_session.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_proxy_client_socket.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_response_headers.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/client_socket_handle.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/client_socket_pool_histograms.h"
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/socket/next_proto.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/socket_test_util.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/spdy_protocol.h"
22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "net/spdy/spdy_test_util_common.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMaxSockets = 32;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMaxSocketsPerGroup = 6;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char * const kAuthHeaders[] = {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "proxy-authorization", "Basic Zm9vOmJhcg=="
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kAuthHeadersSize = arraysize(kAuthHeaders) / 2;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum HttpProxyType {
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HTTP,
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HTTPS,
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SPDY
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstruct HttpProxyClientSocketPoolTestParams {
43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpProxyClientSocketPoolTestParams()
44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      : proxy_type(HTTP),
454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        protocol(kProtoSPDY3) {}
46eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpProxyClientSocketPoolTestParams(
48eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      HttpProxyType proxy_type,
49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      NextProto protocol)
50eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      : proxy_type(proxy_type),
51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        protocol(protocol) {}
52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpProxyType proxy_type;
54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  NextProto protocol;
55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch};
56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef ::testing::TestWithParam<HttpProxyType> TestWithHttpParam;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const char kHttpProxyHost[] = "httpproxy.example.com";
603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const char kHttpsProxyHost[] = "httpsproxy.example.com";
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass TestProxyDelegate : public ProxyDelegate {
631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci public:
641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TestProxyDelegate()
651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      : on_before_tunnel_request_called_(false),
661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        on_tunnel_headers_received_called_(false) {
671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual ~TestProxyDelegate() OVERRIDE {
701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool on_before_tunnel_request_called() const {
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return on_before_tunnel_request_called_;
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool on_tunnel_headers_received_called() const {
771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return on_tunnel_headers_received_called_;
781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void VerifyOnTunnelHeadersReceived(const std::string& origin,
811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                     const std::string& proxy_server,
821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                     const std::string& status_line) const {
831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_TRUE(on_tunnel_headers_received_called_);
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_TRUE(HostPortPair::FromString(origin).Equals(
851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    on_tunnel_headers_received_origin_));
861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_TRUE(HostPortPair::FromString(proxy_server).Equals(
871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    on_tunnel_headers_received_proxy_server_));
881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(status_line, on_tunnel_headers_received_status_line_);
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // ProxyDelegate:
921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void OnResolveProxy(const GURL& url,
931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              int load_flags,
941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              const ProxyService& proxy_service,
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              ProxyInfo* result) OVERRIDE {
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void OnFallback(const ProxyServer& bad_proxy,
991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                          int net_error) OVERRIDE {
1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void OnBeforeSendHeaders(URLRequest* request,
1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                   const ProxyInfo& proxy_info,
1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                   HttpRequestHeaders* headers) OVERRIDE {
1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void OnBeforeTunnelRequest(
1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      const net::HostPortPair& proxy_server,
1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      net::HttpRequestHeaders* extra_headers) OVERRIDE {
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    on_before_tunnel_request_called_ = true;
1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (extra_headers) {
1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      extra_headers->SetHeader("Foo", proxy_server.ToString());
1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void OnTunnelHeadersReceived(
1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      const net::HostPortPair& origin,
1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      const net::HostPortPair& proxy_server,
1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      const net::HttpResponseHeaders& response_headers) OVERRIDE {
1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    on_tunnel_headers_received_called_ = true;
1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    on_tunnel_headers_received_origin_ = origin;
1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    on_tunnel_headers_received_proxy_server_ = proxy_server;
1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    on_tunnel_headers_received_status_line_ = response_headers.GetStatusLine();
1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci private:
1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool on_before_tunnel_request_called_;
1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool on_tunnel_headers_received_called_;
1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  HostPortPair on_tunnel_headers_received_origin_;
1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  HostPortPair on_tunnel_headers_received_proxy_server_;
1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::string on_tunnel_headers_received_status_line_;
1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci};
1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass HttpProxyClientSocketPoolTest
136eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    : public ::testing::TestWithParam<HttpProxyClientSocketPoolTestParams> {
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
138eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpProxyClientSocketPoolTest()
139eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      : session_deps_(GetParam().protocol),
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        tcp_histograms_("MockTCP"),
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        transport_socket_pool_(
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            kMaxSockets,
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            kMaxSocketsPerGroup,
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            &tcp_histograms_,
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            session_deps_.deterministic_socket_factory.get()),
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ssl_histograms_("MockSSL"),
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        ssl_socket_pool_(kMaxSockets,
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         kMaxSocketsPerGroup,
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         &ssl_histograms_,
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         session_deps_.host_resolver.get(),
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         session_deps_.cert_verifier.get(),
1525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                         NULL /* channel_id_store */,
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         NULL /* transport_security_state */,
154a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                         NULL /* cert_transparency_verifier */,
155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         std::string() /* ssl_session_cache_shard */,
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         session_deps_.deterministic_socket_factory.get(),
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         &transport_socket_pool_,
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         NULL,
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         NULL,
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         session_deps_.ssl_config_service.get(),
1615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                         false,
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         BoundNetLog().net_log()),
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        session_(CreateNetworkSession()),
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        http_proxy_histograms_("HttpProxyUnitTest"),
165eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        spdy_util_(GetParam().protocol),
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        pool_(kMaxSockets,
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              kMaxSocketsPerGroup,
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              &http_proxy_histograms_,
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              NULL,
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              &transport_socket_pool_,
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              &ssl_socket_pool_,
1721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci              NULL,
1737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)              NULL) {}
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  virtual ~HttpProxyClientSocketPoolTest() {
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddAuthToCache() {
1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::string16 kFoo(base::ASCIIToUTF16("foo"));
1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::string16 kBar(base::ASCIIToUTF16("bar"));
1813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    GURL proxy_url(GetParam().proxy_type == HTTP ?
1823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                   (std::string("http://") + kHttpProxyHost) :
1833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                   (std::string("https://") + kHttpsProxyHost));
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    session_->http_auth_cache()->Add(proxy_url,
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     "MyRealm1",
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     HttpAuth::AUTH_SCHEME_BASIC,
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     "Basic realm=MyRealm1",
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     AuthCredentials(kFoo, kBar),
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     "/");
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_refptr<TransportSocketParams> CreateHttpProxyParams() const {
193eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (GetParam().proxy_type != HTTP)
1943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      return NULL;
1951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return new TransportSocketParams(
1961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        HostPortPair(kHttpProxyHost, 80),
1971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        false,
1981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        false,
1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        OnHostResolutionCallback(),
2001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT);
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_refptr<SSLSocketParams> CreateHttpsProxyParams() const {
204eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (GetParam().proxy_type == HTTP)
2053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      return NULL;
2063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return new SSLSocketParams(
2073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        new TransportSocketParams(
2083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            HostPortPair(kHttpsProxyHost, 443),
2093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            false,
2103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            false,
2111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            OnHostResolutionCallback(),
2121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT),
2133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        NULL,
2143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        NULL,
2153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        HostPortPair(kHttpsProxyHost, 443),
2163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        SSLConfig(),
217e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch        PRIVACY_MODE_DISABLED,
2183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        0,
2193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        false,
2203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        false);
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the a correctly constructed HttpProxyParms
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // for the HTTP or HTTPS proxy.
2251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<HttpProxySocketParams> CreateParams(
2261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      bool tunnel,
2271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ProxyDelegate* proxy_delegate) {
228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return scoped_refptr<HttpProxySocketParams>(new HttpProxySocketParams(
2293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        CreateHttpProxyParams(),
2303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        CreateHttpsProxyParams(),
231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        GURL(tunnel ? "https://www.google.com/" : "http://www.google.com"),
232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        std::string(),
233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        HostPortPair("www.google.com", tunnel ? 443 : 80),
234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        session_->http_auth_cache(),
235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        session_->http_auth_handler_factory(),
236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        session_->spdy_session_pool(),
2371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        tunnel,
2381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        proxy_delegate));
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<HttpProxySocketParams> CreateTunnelParams(
2421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ProxyDelegate* proxy_delegate) {
2431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return CreateParams(true, proxy_delegate);
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<HttpProxySocketParams> CreateNoTunnelParams(
2471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ProxyDelegate* proxy_delegate) {
2481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return CreateParams(false, proxy_delegate);
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DeterministicMockClientSocketFactory* socket_factory() {
2523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return session_deps_.deterministic_socket_factory.get();
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Initialize(MockRead* reads, size_t reads_count,
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  MockWrite* writes, size_t writes_count,
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  MockRead* spdy_reads, size_t spdy_reads_count,
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  MockWrite* spdy_writes, size_t spdy_writes_count) {
259eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (GetParam().proxy_type == SPDY) {
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_.reset(new DeterministicSocketData(spdy_reads, spdy_reads_count,
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              spdy_writes, spdy_writes_count));
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_.reset(new DeterministicSocketData(reads, reads_count, writes,
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              writes_count));
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    data_->set_connect_data(MockConnect(SYNCHRONOUS, OK));
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    data_->StopAfter(2);  // Request / Response
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    socket_factory()->AddSocketDataProvider(data_.get());
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
272eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (GetParam().proxy_type != HTTP) {
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ssl_data_.reset(new SSLSocketDataProvider(SYNCHRONOUS, OK));
274eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      if (GetParam().proxy_type == SPDY) {
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        InitializeSpdySsl();
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      socket_factory()->AddSSLSocketDataProvider(ssl_data_.get());
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void InitializeSpdySsl() {
282eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    ssl_data_->SetNextProto(GetParam().protocol);
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpNetworkSession* CreateNetworkSession() {
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return SpdySessionDependencies::SpdyCreateSessionDeterministic(
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        &session_deps_);
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  RequestPriority GetLastTransportRequestPriority() const {
2913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return transport_socket_pool_.last_request_priority();
2923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
2933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SpdySessionDependencies session_deps_;
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClientSocketPoolHistograms tcp_histograms_;
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockTransportClientSocketPool transport_socket_pool_;
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClientSocketPoolHistograms ssl_histograms_;
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockHostResolver host_resolver_;
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<CertVerifier> cert_verifier_;
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLClientSocketPool ssl_socket_pool_;
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const scoped_refptr<HttpNetworkSession> session_;
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClientSocketPoolHistograms http_proxy_histograms_;
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
308a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  SpdyTestUtil spdy_util_;
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SSLSocketDataProvider> ssl_data_;
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DeterministicSocketData> data_;
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpProxyClientSocketPool pool_;
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClientSocketHandle handle_;
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback_;
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//-----------------------------------------------------------------------------
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// All tests are run with three different proxy types: HTTP, HTTPS (non-SPDY)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and SPDY.
319eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch//
320eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// TODO(akalin): Use ::testing::Combine() when we are able to use
321eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// <tr1/tuple>.
322eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochINSTANTIATE_TEST_CASE_P(
323eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    HttpProxyClientSocketPoolTests,
324eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    HttpProxyClientSocketPoolTest,
325eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    ::testing::Values(
3264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        HttpProxyClientSocketPoolTestParams(HTTP, kProtoDeprecatedSPDY2),
3274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        HttpProxyClientSocketPoolTestParams(HTTPS, kProtoDeprecatedSPDY2),
3284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        HttpProxyClientSocketPoolTestParams(SPDY, kProtoDeprecatedSPDY2),
329eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        HttpProxyClientSocketPoolTestParams(HTTP, kProtoSPDY3),
330eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        HttpProxyClientSocketPoolTestParams(HTTPS, kProtoSPDY3),
331eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        HttpProxyClientSocketPoolTestParams(SPDY, kProtoSPDY3),
332eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        HttpProxyClientSocketPoolTestParams(HTTP, kProtoSPDY31),
333eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        HttpProxyClientSocketPoolTestParams(HTTPS, kProtoSPDY31),
334eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        HttpProxyClientSocketPoolTestParams(SPDY, kProtoSPDY31),
335a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        HttpProxyClientSocketPoolTestParams(HTTP, kProtoSPDY4),
336a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        HttpProxyClientSocketPoolTestParams(HTTPS, kProtoSPDY4),
337a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        HttpProxyClientSocketPoolTestParams(SPDY, kProtoSPDY4)));
338eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
339eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpProxyClientSocketPoolTest, NoTunnel) {
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Initialize(NULL, 0, NULL, 0, NULL, 0, NULL, 0);
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<TestProxyDelegate> proxy_delegate(new TestProxyDelegate());
3431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int rv = handle_.Init("a", CreateNoTunnelParams(proxy_delegate.get()), LOW,
3441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                        CompletionCallback(), &pool_, BoundNetLog());
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(handle_.is_initialized());
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(handle_.socket());
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpProxyClientSocket* tunnel_socket =
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          static_cast<HttpProxyClientSocket*>(handle_.socket());
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(tunnel_socket->IsConnected());
3511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_FALSE(proxy_delegate->on_before_tunnel_request_called());
3521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_FALSE(proxy_delegate->on_tunnel_headers_received_called());
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Make sure that HttpProxyConnectJob passes on its priority to its
3563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// (non-SSL) socket request on Init.
3573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)TEST_P(HttpProxyClientSocketPoolTest, SetSocketRequestPriorityOnInit) {
3583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Initialize(NULL, 0, NULL, 0, NULL, 0, NULL, 0);
3593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(OK,
3601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            handle_.Init("a", CreateNoTunnelParams(NULL), HIGHEST,
3613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                         CompletionCallback(), &pool_, BoundNetLog()));
3623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(HIGHEST, GetLastTransportRequestPriority());
3633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
3643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
365eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpProxyClientSocketPoolTest, NeedAuth) {
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes[] = {
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(ASYNC, 0, "CONNECT www.google.com:443 HTTP/1.1\r\n"
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads[] = {
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // No credentials.
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 1, "HTTP/1.1 407 Proxy Authentication Required\r\n"),
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 2, "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 3, "Content-Length: 10\r\n\r\n"),
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 4, "0123456789"),
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
37890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
3793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOW));
38090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> rst(
38190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req, 0, ASYNC),
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*rst, 2, ASYNC),
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
386116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  SpdyHeaderBlock resp_block;
387116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  resp_block[spdy_util_.GetStatusKey()] = "407";
388116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  resp_block["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
389116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  spdy_util_.MaybeAddVersionHeader(&resp_block);
390116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
391116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyReply(1, resp_block));
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp, 1, ASYNC),
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 3)
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Initialize(reads, arraysize(reads), writes, arraysize(writes),
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             spdy_reads, arraysize(spdy_reads), spdy_writes,
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             arraysize(spdy_writes));
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data_->StopAfter(4);
4021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int rv = handle_.Init("a", CreateTunnelParams(NULL), LOW,
4031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                        callback_.callback(), &pool_, BoundNetLog());
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.is_initialized());
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.socket());
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
408eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  data_->RunFor(GetParam().proxy_type == SPDY ? 2 : 4);
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback_.WaitForResult();
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, rv);
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(handle_.is_initialized());
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(handle_.socket());
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyClientSocket* tunnel_socket =
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<ProxyClientSocket*>(handle_.socket());
415eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (GetParam().proxy_type == SPDY) {
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(tunnel_socket->IsConnected());
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(tunnel_socket->IsUsingSpdy());
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(tunnel_socket->IsConnected());
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(tunnel_socket->IsUsingSpdy());
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
424eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpProxyClientSocketPoolTest, HaveAuth) {
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // It's pretty much impossible to make the SPDY case behave synchronously
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // so we skip this test for SPDY
427eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (GetParam().proxy_type == SPDY)
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::string proxy_host_port =
4301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      GetParam().proxy_type == HTTP ?
4311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          (kHttpProxyHost + std::string(":80")) :
4321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          (kHttpsProxyHost + std::string(":443"));
4331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::string request =
4341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "CONNECT www.google.com:443 HTTP/1.1\r\n"
4351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "Host: www.google.com\r\n"
4361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "Proxy-Connection: keep-alive\r\n"
4371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
4381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "Foo: " + proxy_host_port + "\r\n\r\n";
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes[] = {
4401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    MockWrite(SYNCHRONOUS, 0, request.c_str()),
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads[] = {
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Initialize(reads, arraysize(reads), writes, arraysize(writes), NULL, 0,
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             NULL, 0);
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddAuthToCache();
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<TestProxyDelegate> proxy_delegate(new TestProxyDelegate());
4511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int rv = handle_.Init("a", CreateTunnelParams(proxy_delegate.get()), LOW,
4521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                        callback_.callback(), &pool_, BoundNetLog());
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(handle_.is_initialized());
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(handle_.socket());
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpProxyClientSocket* tunnel_socket =
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          static_cast<HttpProxyClientSocket*>(handle_.socket());
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(tunnel_socket->IsConnected());
4591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  proxy_delegate->VerifyOnTunnelHeadersReceived(
4601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "www.google.com:443",
4611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      proxy_host_port.c_str(),
4621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "HTTP/1.1 200 Connection Established");
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpProxyClientSocketPoolTest, AsyncHaveAuth) {
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes[] = {
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(ASYNC, 0, "CONNECT www.google.com:443 HTTP/1.1\r\n"
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads[] = {
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
4773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      spdy_util_.ConstructSpdyConnect(kAuthHeaders, kAuthHeadersSize, 1, LOW));
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req, 0, ASYNC)
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
481eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp, 1, ASYNC),
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 2)
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Initialize(reads, arraysize(reads), writes, arraysize(writes),
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             spdy_reads, arraysize(spdy_reads), spdy_writes,
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             arraysize(spdy_writes));
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddAuthToCache();
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int rv = handle_.Init("a", CreateTunnelParams(NULL), LOW,
4931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                        callback_.callback(), &pool_, BoundNetLog());
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.is_initialized());
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.socket());
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data_->RunFor(2);
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback_.WaitForResult());
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(handle_.is_initialized());
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(handle_.socket());
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpProxyClientSocket* tunnel_socket =
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          static_cast<HttpProxyClientSocket*>(handle_.socket());
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(tunnel_socket->IsConnected());
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Make sure that HttpProxyConnectJob passes on its priority to its
5083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// SPDY session's socket request on Init (if applicable).
5093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)TEST_P(HttpProxyClientSocketPoolTest,
5103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)       SetSpdySessionSocketRequestPriorityOnInit) {
5113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (GetParam().proxy_type != SPDY)
5123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return;
5133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<SpdyFrame> req(
5153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      spdy_util_.ConstructSpdyConnect(kAuthHeaders, kAuthHeadersSize,
5163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                      1, MEDIUM));
5173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  MockWrite spdy_writes[] = {
5183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    CreateMockWrite(*req, 0, ASYNC)
5193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  };
5203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
5213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  MockRead spdy_reads[] = {
5223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    CreateMockRead(*resp, 1, ASYNC),
5233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockRead(ASYNC, 0, 2)
5243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  };
5253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Initialize(NULL, 0, NULL, 0,
5273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)             spdy_reads, arraysize(spdy_reads),
5283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)             spdy_writes, arraysize(spdy_writes));
5293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  AddAuthToCache();
5303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
5321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            handle_.Init("a", CreateTunnelParams(NULL), MEDIUM,
5333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                         callback_.callback(), &pool_, BoundNetLog()));
5343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(MEDIUM, GetLastTransportRequestPriority());
5353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  data_->RunFor(2);
5373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(OK, callback_.WaitForResult());
5383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
5393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
540eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpProxyClientSocketPoolTest, TCPError) {
541eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (GetParam().proxy_type == SPDY) return;
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data_.reset(new DeterministicSocketData(NULL, 0, NULL, 0));
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data_->set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_CLOSED));
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  socket_factory()->AddSocketDataProvider(data_.get());
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int rv = handle_.Init("a", CreateTunnelParams(NULL), LOW,
5481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                        callback_.callback(), &pool_, BoundNetLog());
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.is_initialized());
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.socket());
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, callback_.WaitForResult());
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.is_initialized());
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.socket());
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
559eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpProxyClientSocketPoolTest, SSLError) {
560eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (GetParam().proxy_type == HTTP) return;
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data_.reset(new DeterministicSocketData(NULL, 0, NULL, 0));
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data_->set_connect_data(MockConnect(ASYNC, OK));
5633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  socket_factory()->AddSocketDataProvider(data_.get());
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data_.reset(new SSLSocketDataProvider(ASYNC,
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            ERR_CERT_AUTHORITY_INVALID));
567eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (GetParam().proxy_type == SPDY) {
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InitializeSpdySsl();
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  socket_factory()->AddSSLSocketDataProvider(ssl_data_.get());
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int rv = handle_.Init("a", CreateTunnelParams(NULL), LOW,
5731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                        callback_.callback(), &pool_, BoundNetLog());
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.is_initialized());
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.socket());
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_PROXY_CERTIFICATE_INVALID, callback_.WaitForResult());
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.is_initialized());
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.socket());
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
584eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpProxyClientSocketPoolTest, SslClientAuth) {
585eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (GetParam().proxy_type == HTTP) return;
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data_.reset(new DeterministicSocketData(NULL, 0, NULL, 0));
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data_->set_connect_data(MockConnect(ASYNC, OK));
5883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  socket_factory()->AddSocketDataProvider(data_.get());
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data_.reset(new SSLSocketDataProvider(ASYNC,
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
592eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (GetParam().proxy_type == SPDY) {
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InitializeSpdySsl();
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  socket_factory()->AddSSLSocketDataProvider(ssl_data_.get());
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int rv = handle_.Init("a", CreateTunnelParams(NULL), LOW,
5981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                        callback_.callback(), &pool_, BoundNetLog());
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.is_initialized());
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.socket());
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, callback_.WaitForResult());
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.is_initialized());
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.socket());
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
609eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpProxyClientSocketPoolTest, TunnelUnexpectedClose) {
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes[] = {
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(ASYNC, 0,
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "CONNECT www.google.com:443 HTTP/1.1\r\n"
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads[] = {
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 1, "HTTP/1.1 200 Conn"),
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, ERR_CONNECTION_CLOSED, 2),
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
62190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
6223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      spdy_util_.ConstructSpdyConnect(kAuthHeaders, kAuthHeadersSize, 1, LOW));
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req, 0, ASYNC)
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, ERR_CONNECTION_CLOSED, 1),
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Initialize(reads, arraysize(reads), writes, arraysize(writes),
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             spdy_reads, arraysize(spdy_reads), spdy_writes,
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             arraysize(spdy_writes));
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddAuthToCache();
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int rv = handle_.Init("a", CreateTunnelParams(NULL), LOW,
6361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                        callback_.callback(), &pool_, BoundNetLog());
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.is_initialized());
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.socket());
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data_->RunFor(3);
642eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (GetParam().proxy_type == SPDY) {
643868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // SPDY cannot process a headers block unless it's complete and so it
644868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // returns ERR_CONNECTION_CLOSED in this case.
645868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_EQ(ERR_CONNECTION_CLOSED, callback_.WaitForResult());
646868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  } else {
6477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    EXPECT_EQ(ERR_RESPONSE_HEADERS_TRUNCATED, callback_.WaitForResult());
648868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.is_initialized());
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.socket());
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_P(HttpProxyClientSocketPoolTest, Tunnel1xxResponse) {
6544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Tests that 1xx responses are rejected for a CONNECT request.
6554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (GetParam().proxy_type == SPDY) {
6564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // SPDY doesn't have 1xx responses.
6574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
6584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
6594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
6604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  MockWrite writes[] = {
6614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    MockWrite(ASYNC, 0,
6624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)              "CONNECT www.google.com:443 HTTP/1.1\r\n"
6634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)              "Host: www.google.com\r\n"
6644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
6654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  };
6664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  MockRead reads[] = {
6674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    MockRead(ASYNC, 1, "HTTP/1.1 100 Continue\r\n\r\n"),
6684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    MockRead(ASYNC, 2, "HTTP/1.1 200 Connection Established\r\n\r\n"),
6694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  };
6704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
6714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  Initialize(reads, arraysize(reads), writes, arraysize(writes),
6724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)             NULL, 0, NULL, 0);
6734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
6741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int rv = handle_.Init("a", CreateTunnelParams(NULL), LOW,
6751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                        callback_.callback(), &pool_, BoundNetLog());
6764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
6774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_FALSE(handle_.is_initialized());
6784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_FALSE(handle_.socket());
6794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
6804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  data_->RunFor(2);
6814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, callback_.WaitForResult());
6824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
6834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
684eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpProxyClientSocketPoolTest, TunnelSetupError) {
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes[] = {
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(ASYNC, 0,
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "CONNECT www.google.com:443 HTTP/1.1\r\n"
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads[] = {
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 1, "HTTP/1.1 304 Not Modified\r\n\r\n"),
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
69590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
6963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      spdy_util_.ConstructSpdyConnect(kAuthHeaders, kAuthHeadersSize, 1, LOW));
69790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> rst(
69890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req, 0, ASYNC),
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*rst, 2, ASYNC),
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
703eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdySynReplyError(1));
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp, 1, ASYNC),
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 3),
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Initialize(reads, arraysize(reads), writes, arraysize(writes),
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             spdy_reads, arraysize(spdy_reads), spdy_writes,
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             arraysize(spdy_writes));
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddAuthToCache();
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int rv = handle_.Init("a", CreateTunnelParams(NULL), LOW,
7151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                        callback_.callback(), &pool_, BoundNetLog());
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.is_initialized());
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.socket());
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data_->RunFor(2);
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback_.WaitForResult();
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // All Proxy CONNECT responses are not trustworthy
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.is_initialized());
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.socket());
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
729eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpProxyClientSocketPoolTest, TunnelSetupRedirect) {
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string redirectTarget = "https://foo.google.com/";
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string responseText = "HTTP/1.1 302 Found\r\n"
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   "Location: " + redirectTarget + "\r\n"
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   "Set-Cookie: foo=bar\r\n"
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   "\r\n";
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes[] = {
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(ASYNC, 0,
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "CONNECT www.google.com:443 HTTP/1.1\r\n"
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads[] = {
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 1, responseText.c_str()),
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> req(
7473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      spdy_util_.ConstructSpdyConnect(kAuthHeaders, kAuthHeadersSize, 1, LOW));
74890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> rst(
74990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req, 0, ASYNC),
753eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    CreateMockWrite(*rst, 3, ASYNC),
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* const responseHeaders[] = {
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "location", redirectTarget.c_str(),
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "set-cookie", "foo=bar",
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int responseHeadersSize = arraysize(responseHeaders) / 2;
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(
762eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      spdy_util_.ConstructSpdySynReplyError(
763eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          "302 Found",
764eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          responseHeaders, responseHeadersSize,
765eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          1));
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp, 1, ASYNC),
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 2),
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Initialize(reads, arraysize(reads), writes, arraysize(writes),
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             spdy_reads, arraysize(spdy_reads), spdy_writes,
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             arraysize(spdy_writes));
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddAuthToCache();
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int rv = handle_.Init("a", CreateTunnelParams(NULL), LOW,
7771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                        callback_.callback(), &pool_, BoundNetLog());
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.is_initialized());
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_.socket());
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data_->RunFor(2);
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback_.WaitForResult();
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
786eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (GetParam().proxy_type == HTTP) {
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We don't trust 302 responses to CONNECT from HTTP proxies.
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(handle_.is_initialized());
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(handle_.socket());
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Expect ProxyClientSocket to return the proxy's response, sanitized.
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_HTTPS_PROXY_TUNNEL_RESPONSE, rv);
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(handle_.is_initialized());
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(handle_.socket());
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ProxyClientSocket* tunnel_socket =
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        static_cast<ProxyClientSocket*>(handle_.socket());
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = tunnel_socket->GetConnectResponseInfo();
800868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const HttpResponseHeaders* headers = response->headers.get();
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Make sure Set-Cookie header was stripped.
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(headers->HasHeader("set-cookie"));
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Make sure Content-Length: 0 header was added.
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(headers->HasHeaderValue("content-length", "0"));
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Make sure Location header was included and correct.
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string location;
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(headers->IsRedirect(&location));
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(location, redirectTarget);
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// It would be nice to also test the timeouts in HttpProxyClientSocketPool.
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}  // namespace
8183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
820