Home | History | Annotate | Download | only in http
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "net/http/http_stream_factory_impl.h"
      6 
      7 #include <string>
      8 #include <vector>
      9 
     10 #include "base/basictypes.h"
     11 #include "base/compiler_specific.h"
     12 #include "net/base/net_log.h"
     13 #include "net/base/test_completion_callback.h"
     14 #include "net/cert/mock_cert_verifier.h"
     15 #include "net/dns/mock_host_resolver.h"
     16 #include "net/http/http_auth_handler_factory.h"
     17 #include "net/http/http_network_session.h"
     18 #include "net/http/http_network_session_peer.h"
     19 #include "net/http/http_network_transaction.h"
     20 #include "net/http/http_request_info.h"
     21 #include "net/http/http_server_properties.h"
     22 #include "net/http/http_server_properties_impl.h"
     23 #include "net/http/http_stream.h"
     24 #include "net/http/transport_security_state.h"
     25 #include "net/proxy/proxy_info.h"
     26 #include "net/proxy/proxy_service.h"
     27 #include "net/socket/client_socket_handle.h"
     28 #include "net/socket/mock_client_socket_pool_manager.h"
     29 #include "net/socket/next_proto.h"
     30 #include "net/socket/socket_test_util.h"
     31 #include "net/spdy/spdy_session.h"
     32 #include "net/spdy/spdy_session_pool.h"
     33 #include "net/spdy/spdy_test_util_common.h"
     34 #include "net/ssl/ssl_config_service.h"
     35 #include "net/ssl/ssl_config_service_defaults.h"
     36 // This file can be included from net/http even though
     37 // it is in net/websockets because it doesn't
     38 // introduce any link dependency to net/websockets.
     39 #include "net/websockets/websocket_handshake_stream_base.h"
     40 #include "testing/gtest/include/gtest/gtest.h"
     41 
     42 namespace net {
     43 
     44 namespace {
     45 
     46 class MockWebSocketHandshakeStream : public WebSocketHandshakeStreamBase {
     47  public:
     48   enum StreamType {
     49     kStreamTypeBasic,
     50     kStreamTypeSpdy,
     51   };
     52 
     53   explicit MockWebSocketHandshakeStream(StreamType type) : type_(type) {}
     54 
     55   virtual ~MockWebSocketHandshakeStream() {}
     56 
     57   StreamType type() const {
     58     return type_;
     59   }
     60 
     61   // HttpStreamBase methods
     62   virtual int InitializeStream(const HttpRequestInfo* request_info,
     63                                RequestPriority priority,
     64                                const BoundNetLog& net_log,
     65                                const CompletionCallback& callback) OVERRIDE {
     66     return ERR_IO_PENDING;
     67   }
     68   virtual int SendRequest(const HttpRequestHeaders& request_headers,
     69                           HttpResponseInfo* response,
     70                           const CompletionCallback& callback) OVERRIDE {
     71     return ERR_IO_PENDING;
     72   }
     73   virtual int ReadResponseHeaders(const CompletionCallback& callback) OVERRIDE {
     74     return ERR_IO_PENDING;
     75   }
     76   virtual int ReadResponseBody(IOBuffer* buf,
     77                                int buf_len,
     78                                const CompletionCallback& callback) OVERRIDE {
     79     return ERR_IO_PENDING;
     80   }
     81   virtual void Close(bool not_reusable) OVERRIDE {}
     82   virtual bool IsResponseBodyComplete() const OVERRIDE { return false; }
     83   virtual bool CanFindEndOfResponse() const OVERRIDE { return false; }
     84   virtual bool IsConnectionReused() const OVERRIDE { return false; }
     85   virtual void SetConnectionReused() OVERRIDE {}
     86   virtual bool IsConnectionReusable() const OVERRIDE { return false; }
     87   virtual int64 GetTotalReceivedBytes() const OVERRIDE { return 0; }
     88   virtual bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const
     89       OVERRIDE {
     90     return false;
     91   }
     92   virtual void GetSSLInfo(SSLInfo* ssl_info) OVERRIDE {}
     93   virtual void GetSSLCertRequestInfo(
     94       SSLCertRequestInfo* cert_request_info) OVERRIDE {}
     95   virtual bool IsSpdyHttpStream() const OVERRIDE { return false; }
     96   virtual void Drain(HttpNetworkSession* session) OVERRIDE {}
     97   virtual void SetPriority(RequestPriority priority) OVERRIDE {}
     98 
     99   virtual scoped_ptr<WebSocketStream> Upgrade() OVERRIDE {
    100     return scoped_ptr<WebSocketStream>();
    101   }
    102 
    103  private:
    104   const StreamType type_;
    105 };
    106 
    107 // HttpStreamFactoryImpl subclass that can wait until a preconnect is complete.
    108 class MockHttpStreamFactoryImplForPreconnect : public HttpStreamFactoryImpl {
    109  public:
    110   MockHttpStreamFactoryImplForPreconnect(HttpNetworkSession* session,
    111                                          bool for_websockets)
    112       : HttpStreamFactoryImpl(session, for_websockets),
    113         preconnect_done_(false),
    114         waiting_for_preconnect_(false) {}
    115 
    116 
    117   void WaitForPreconnects() {
    118     while (!preconnect_done_) {
    119       waiting_for_preconnect_ = true;
    120       base::MessageLoop::current()->Run();
    121       waiting_for_preconnect_ = false;
    122     }
    123   }
    124 
    125  private:
    126   // HttpStreamFactoryImpl methods.
    127   virtual void OnPreconnectsCompleteInternal() OVERRIDE {
    128     preconnect_done_ = true;
    129     if (waiting_for_preconnect_)
    130       base::MessageLoop::current()->Quit();
    131   }
    132 
    133   bool preconnect_done_;
    134   bool waiting_for_preconnect_;
    135 };
    136 
    137 class StreamRequestWaiter : public HttpStreamRequest::Delegate {
    138  public:
    139   StreamRequestWaiter()
    140       : waiting_for_stream_(false),
    141         stream_done_(false) {}
    142 
    143   // HttpStreamRequest::Delegate
    144 
    145   virtual void OnStreamReady(
    146       const SSLConfig& used_ssl_config,
    147       const ProxyInfo& used_proxy_info,
    148       HttpStreamBase* stream) OVERRIDE {
    149     stream_done_ = true;
    150     if (waiting_for_stream_)
    151       base::MessageLoop::current()->Quit();
    152     stream_.reset(stream);
    153     used_ssl_config_ = used_ssl_config;
    154     used_proxy_info_ = used_proxy_info;
    155   }
    156 
    157   virtual void OnWebSocketHandshakeStreamReady(
    158       const SSLConfig& used_ssl_config,
    159       const ProxyInfo& used_proxy_info,
    160       WebSocketHandshakeStreamBase* stream) OVERRIDE {
    161     stream_done_ = true;
    162     if (waiting_for_stream_)
    163       base::MessageLoop::current()->Quit();
    164     websocket_stream_.reset(stream);
    165     used_ssl_config_ = used_ssl_config;
    166     used_proxy_info_ = used_proxy_info;
    167   }
    168 
    169   virtual void OnStreamFailed(
    170       int status,
    171       const SSLConfig& used_ssl_config) OVERRIDE {}
    172 
    173   virtual void OnCertificateError(
    174       int status,
    175       const SSLConfig& used_ssl_config,
    176       const SSLInfo& ssl_info) OVERRIDE {}
    177 
    178   virtual void OnNeedsProxyAuth(const HttpResponseInfo& proxy_response,
    179                                 const SSLConfig& used_ssl_config,
    180                                 const ProxyInfo& used_proxy_info,
    181                                 HttpAuthController* auth_controller) OVERRIDE {}
    182 
    183   virtual void OnNeedsClientAuth(const SSLConfig& used_ssl_config,
    184                                  SSLCertRequestInfo* cert_info) OVERRIDE {}
    185 
    186   virtual void OnHttpsProxyTunnelResponse(const HttpResponseInfo& response_info,
    187                                           const SSLConfig& used_ssl_config,
    188                                           const ProxyInfo& used_proxy_info,
    189                                           HttpStreamBase* stream) OVERRIDE {}
    190 
    191   void WaitForStream() {
    192     while (!stream_done_) {
    193       waiting_for_stream_ = true;
    194       base::MessageLoop::current()->Run();
    195       waiting_for_stream_ = false;
    196     }
    197   }
    198 
    199   const SSLConfig& used_ssl_config() const {
    200     return used_ssl_config_;
    201   }
    202 
    203   const ProxyInfo& used_proxy_info() const {
    204     return used_proxy_info_;
    205   }
    206 
    207   HttpStreamBase* stream() {
    208     return stream_.get();
    209   }
    210 
    211   MockWebSocketHandshakeStream* websocket_stream() {
    212     return static_cast<MockWebSocketHandshakeStream*>(websocket_stream_.get());
    213   }
    214 
    215   bool stream_done() const { return stream_done_; }
    216 
    217  private:
    218   bool waiting_for_stream_;
    219   bool stream_done_;
    220   scoped_ptr<HttpStreamBase> stream_;
    221   scoped_ptr<WebSocketHandshakeStreamBase> websocket_stream_;
    222   SSLConfig used_ssl_config_;
    223   ProxyInfo used_proxy_info_;
    224 
    225   DISALLOW_COPY_AND_ASSIGN(StreamRequestWaiter);
    226 };
    227 
    228 class WebSocketSpdyHandshakeStream : public MockWebSocketHandshakeStream {
    229  public:
    230   explicit WebSocketSpdyHandshakeStream(
    231       const base::WeakPtr<SpdySession>& spdy_session)
    232       : MockWebSocketHandshakeStream(kStreamTypeSpdy),
    233         spdy_session_(spdy_session) {}
    234 
    235   virtual ~WebSocketSpdyHandshakeStream() {}
    236 
    237   SpdySession* spdy_session() { return spdy_session_.get(); }
    238 
    239  private:
    240   base::WeakPtr<SpdySession> spdy_session_;
    241 };
    242 
    243 class WebSocketBasicHandshakeStream : public MockWebSocketHandshakeStream {
    244  public:
    245   explicit WebSocketBasicHandshakeStream(
    246       scoped_ptr<ClientSocketHandle> connection)
    247       : MockWebSocketHandshakeStream(kStreamTypeBasic),
    248         connection_(connection.Pass()) {}
    249 
    250   virtual ~WebSocketBasicHandshakeStream() {
    251     connection_->socket()->Disconnect();
    252   }
    253 
    254   ClientSocketHandle* connection() { return connection_.get(); }
    255 
    256  private:
    257   scoped_ptr<ClientSocketHandle> connection_;
    258 };
    259 
    260 class WebSocketStreamCreateHelper
    261     : public WebSocketHandshakeStreamBase::CreateHelper {
    262  public:
    263   virtual ~WebSocketStreamCreateHelper() {}
    264 
    265   virtual WebSocketHandshakeStreamBase* CreateBasicStream(
    266       scoped_ptr<ClientSocketHandle> connection,
    267       bool using_proxy) OVERRIDE {
    268     return new WebSocketBasicHandshakeStream(connection.Pass());
    269   }
    270 
    271   virtual WebSocketHandshakeStreamBase* CreateSpdyStream(
    272       const base::WeakPtr<SpdySession>& spdy_session,
    273       bool use_relative_url) OVERRIDE {
    274     return new WebSocketSpdyHandshakeStream(spdy_session);
    275   }
    276 };
    277 
    278 struct TestCase {
    279   int num_streams;
    280   bool ssl;
    281 };
    282 
    283 TestCase kTests[] = {
    284   { 1, false },
    285   { 2, false },
    286   { 1, true},
    287   { 2, true},
    288 };
    289 
    290 void PreconnectHelperForURL(int num_streams,
    291                             const GURL& url,
    292                             HttpNetworkSession* session) {
    293   HttpNetworkSessionPeer peer(session);
    294   MockHttpStreamFactoryImplForPreconnect* mock_factory =
    295       new MockHttpStreamFactoryImplForPreconnect(session, false);
    296   peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(mock_factory));
    297   SSLConfig ssl_config;
    298   session->ssl_config_service()->GetSSLConfig(&ssl_config);
    299 
    300   HttpRequestInfo request;
    301   request.method = "GET";
    302   request.url = url;
    303   request.load_flags = 0;
    304 
    305   session->http_stream_factory()->PreconnectStreams(
    306       num_streams, request, DEFAULT_PRIORITY, ssl_config, ssl_config);
    307   mock_factory->WaitForPreconnects();
    308 };
    309 
    310 void PreconnectHelper(const TestCase& test,
    311                       HttpNetworkSession* session) {
    312   GURL url = test.ssl ? GURL("https://www.google.com") :
    313       GURL("http://www.google.com");
    314   PreconnectHelperForURL(test.num_streams, url, session);
    315 };
    316 
    317 template<typename ParentPool>
    318 class CapturePreconnectsSocketPool : public ParentPool {
    319  public:
    320   CapturePreconnectsSocketPool(HostResolver* host_resolver,
    321                                CertVerifier* cert_verifier);
    322 
    323   int last_num_streams() const {
    324     return last_num_streams_;
    325   }
    326 
    327   virtual int RequestSocket(const std::string& group_name,
    328                             const void* socket_params,
    329                             RequestPriority priority,
    330                             ClientSocketHandle* handle,
    331                             const CompletionCallback& callback,
    332                             const BoundNetLog& net_log) OVERRIDE {
    333     ADD_FAILURE();
    334     return ERR_UNEXPECTED;
    335   }
    336 
    337   virtual void RequestSockets(const std::string& group_name,
    338                               const void* socket_params,
    339                               int num_sockets,
    340                               const BoundNetLog& net_log) OVERRIDE {
    341     last_num_streams_ = num_sockets;
    342   }
    343 
    344   virtual void CancelRequest(const std::string& group_name,
    345                              ClientSocketHandle* handle) OVERRIDE {
    346     ADD_FAILURE();
    347   }
    348   virtual void ReleaseSocket(const std::string& group_name,
    349                              scoped_ptr<StreamSocket> socket,
    350                              int id) OVERRIDE {
    351     ADD_FAILURE();
    352   }
    353   virtual void CloseIdleSockets() OVERRIDE {
    354     ADD_FAILURE();
    355   }
    356   virtual int IdleSocketCount() const OVERRIDE {
    357     ADD_FAILURE();
    358     return 0;
    359   }
    360   virtual int IdleSocketCountInGroup(
    361       const std::string& group_name) const OVERRIDE {
    362     ADD_FAILURE();
    363     return 0;
    364   }
    365   virtual LoadState GetLoadState(
    366       const std::string& group_name,
    367       const ClientSocketHandle* handle) const OVERRIDE {
    368     ADD_FAILURE();
    369     return LOAD_STATE_IDLE;
    370   }
    371   virtual base::TimeDelta ConnectionTimeout() const OVERRIDE {
    372     return base::TimeDelta();
    373   }
    374 
    375  private:
    376   int last_num_streams_;
    377 };
    378 
    379 typedef CapturePreconnectsSocketPool<TransportClientSocketPool>
    380 CapturePreconnectsTransportSocketPool;
    381 typedef CapturePreconnectsSocketPool<HttpProxyClientSocketPool>
    382 CapturePreconnectsHttpProxySocketPool;
    383 typedef CapturePreconnectsSocketPool<SOCKSClientSocketPool>
    384 CapturePreconnectsSOCKSSocketPool;
    385 typedef CapturePreconnectsSocketPool<SSLClientSocketPool>
    386 CapturePreconnectsSSLSocketPool;
    387 
    388 template<typename ParentPool>
    389 CapturePreconnectsSocketPool<ParentPool>::CapturePreconnectsSocketPool(
    390     HostResolver* host_resolver, CertVerifier* /* cert_verifier */)
    391     : ParentPool(0, 0, NULL, host_resolver, NULL, NULL),
    392       last_num_streams_(-1) {}
    393 
    394 template<>
    395 CapturePreconnectsHttpProxySocketPool::CapturePreconnectsSocketPool(
    396     HostResolver* host_resolver, CertVerifier* /* cert_verifier */)
    397     : HttpProxyClientSocketPool(
    398           0, 0, NULL, host_resolver, NULL, NULL, NULL, NULL),
    399       last_num_streams_(-1) {}
    400 
    401 template <>
    402 CapturePreconnectsSSLSocketPool::CapturePreconnectsSocketPool(
    403     HostResolver* host_resolver,
    404     CertVerifier* cert_verifier)
    405     : SSLClientSocketPool(0,
    406                           0,
    407                           NULL,  // ssl_histograms
    408                           host_resolver,
    409                           cert_verifier,
    410                           NULL,           // channel_id_store
    411                           NULL,           // transport_security_state
    412                           NULL,           // cert_transparency_verifier
    413                           std::string(),  // ssl_session_cache_shard
    414                           NULL,           // deterministic_socket_factory
    415                           NULL,           // transport_socket_pool
    416                           NULL,
    417                           NULL,
    418                           NULL,   // ssl_config_service
    419                           false,  // enable_ssl_connect_job_waiting
    420                           NULL),  // net_log
    421       last_num_streams_(-1) {
    422 }
    423 
    424 class HttpStreamFactoryTest : public ::testing::Test,
    425                               public ::testing::WithParamInterface<NextProto> {
    426 };
    427 
    428 INSTANTIATE_TEST_CASE_P(
    429     NextProto,
    430     HttpStreamFactoryTest,
    431     testing::Values(kProtoDeprecatedSPDY2,
    432                     kProtoSPDY3, kProtoSPDY31, kProtoSPDY4));
    433 
    434 TEST_P(HttpStreamFactoryTest, PreconnectDirect) {
    435   for (size_t i = 0; i < arraysize(kTests); ++i) {
    436     SpdySessionDependencies session_deps(
    437         GetParam(), ProxyService::CreateDirect());
    438     scoped_refptr<HttpNetworkSession> session(
    439         SpdySessionDependencies::SpdyCreateSession(&session_deps));
    440     HttpNetworkSessionPeer peer(session);
    441     CapturePreconnectsTransportSocketPool* transport_conn_pool =
    442         new CapturePreconnectsTransportSocketPool(
    443             session_deps.host_resolver.get(),
    444             session_deps.cert_verifier.get());
    445     CapturePreconnectsSSLSocketPool* ssl_conn_pool =
    446         new CapturePreconnectsSSLSocketPool(
    447             session_deps.host_resolver.get(),
    448             session_deps.cert_verifier.get());
    449     scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
    450         new MockClientSocketPoolManager);
    451     mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
    452     mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
    453     peer.SetClientSocketPoolManager(
    454         mock_pool_manager.PassAs<ClientSocketPoolManager>());
    455     PreconnectHelper(kTests[i], session.get());
    456     if (kTests[i].ssl)
    457       EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams());
    458     else
    459       EXPECT_EQ(kTests[i].num_streams, transport_conn_pool->last_num_streams());
    460   }
    461 }
    462 
    463 TEST_P(HttpStreamFactoryTest, PreconnectHttpProxy) {
    464   for (size_t i = 0; i < arraysize(kTests); ++i) {
    465     SpdySessionDependencies session_deps(
    466         GetParam(), ProxyService::CreateFixed("http_proxy"));
    467     scoped_refptr<HttpNetworkSession> session(
    468         SpdySessionDependencies::SpdyCreateSession(&session_deps));
    469     HttpNetworkSessionPeer peer(session);
    470     HostPortPair proxy_host("http_proxy", 80);
    471     CapturePreconnectsHttpProxySocketPool* http_proxy_pool =
    472         new CapturePreconnectsHttpProxySocketPool(
    473             session_deps.host_resolver.get(),
    474             session_deps.cert_verifier.get());
    475     CapturePreconnectsSSLSocketPool* ssl_conn_pool =
    476         new CapturePreconnectsSSLSocketPool(
    477             session_deps.host_resolver.get(),
    478             session_deps.cert_verifier.get());
    479     scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
    480         new MockClientSocketPoolManager);
    481     mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
    482     mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
    483     peer.SetClientSocketPoolManager(
    484         mock_pool_manager.PassAs<ClientSocketPoolManager>());
    485     PreconnectHelper(kTests[i], session.get());
    486     if (kTests[i].ssl)
    487       EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams());
    488     else
    489       EXPECT_EQ(kTests[i].num_streams, http_proxy_pool->last_num_streams());
    490   }
    491 }
    492 
    493 TEST_P(HttpStreamFactoryTest, PreconnectSocksProxy) {
    494   for (size_t i = 0; i < arraysize(kTests); ++i) {
    495     SpdySessionDependencies session_deps(
    496         GetParam(), ProxyService::CreateFixed("socks4://socks_proxy:1080"));
    497     scoped_refptr<HttpNetworkSession> session(
    498         SpdySessionDependencies::SpdyCreateSession(&session_deps));
    499     HttpNetworkSessionPeer peer(session);
    500     HostPortPair proxy_host("socks_proxy", 1080);
    501     CapturePreconnectsSOCKSSocketPool* socks_proxy_pool =
    502         new CapturePreconnectsSOCKSSocketPool(
    503             session_deps.host_resolver.get(),
    504             session_deps.cert_verifier.get());
    505     CapturePreconnectsSSLSocketPool* ssl_conn_pool =
    506         new CapturePreconnectsSSLSocketPool(
    507             session_deps.host_resolver.get(),
    508             session_deps.cert_verifier.get());
    509     scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
    510         new MockClientSocketPoolManager);
    511     mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_proxy_pool);
    512     mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
    513     peer.SetClientSocketPoolManager(
    514         mock_pool_manager.PassAs<ClientSocketPoolManager>());
    515     PreconnectHelper(kTests[i], session.get());
    516     if (kTests[i].ssl)
    517       EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams());
    518     else
    519       EXPECT_EQ(kTests[i].num_streams, socks_proxy_pool->last_num_streams());
    520   }
    521 }
    522 
    523 TEST_P(HttpStreamFactoryTest, PreconnectDirectWithExistingSpdySession) {
    524   for (size_t i = 0; i < arraysize(kTests); ++i) {
    525     SpdySessionDependencies session_deps(
    526         GetParam(), ProxyService::CreateDirect());
    527     scoped_refptr<HttpNetworkSession> session(
    528         SpdySessionDependencies::SpdyCreateSession(&session_deps));
    529     HttpNetworkSessionPeer peer(session);
    530 
    531     // Put a SpdySession in the pool.
    532     HostPortPair host_port_pair("www.google.com", 443);
    533     SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
    534                        PRIVACY_MODE_DISABLED);
    535     ignore_result(CreateFakeSpdySession(session->spdy_session_pool(), key));
    536 
    537     CapturePreconnectsTransportSocketPool* transport_conn_pool =
    538         new CapturePreconnectsTransportSocketPool(
    539             session_deps.host_resolver.get(),
    540             session_deps.cert_verifier.get());
    541     CapturePreconnectsSSLSocketPool* ssl_conn_pool =
    542         new CapturePreconnectsSSLSocketPool(
    543             session_deps.host_resolver.get(),
    544             session_deps.cert_verifier.get());
    545     scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
    546         new MockClientSocketPoolManager);
    547     mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
    548     mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
    549     peer.SetClientSocketPoolManager(
    550         mock_pool_manager.PassAs<ClientSocketPoolManager>());
    551     PreconnectHelper(kTests[i], session.get());
    552     // We shouldn't be preconnecting if we have an existing session, which is
    553     // the case for https://www.google.com.
    554     if (kTests[i].ssl)
    555       EXPECT_EQ(-1, ssl_conn_pool->last_num_streams());
    556     else
    557       EXPECT_EQ(kTests[i].num_streams,
    558                 transport_conn_pool->last_num_streams());
    559   }
    560 }
    561 
    562 // Verify that preconnects to unsafe ports are cancelled before they reach
    563 // the SocketPool.
    564 TEST_P(HttpStreamFactoryTest, PreconnectUnsafePort) {
    565   ASSERT_FALSE(IsPortAllowedByDefault(7));
    566   ASSERT_FALSE(IsPortAllowedByOverride(7));
    567 
    568   SpdySessionDependencies session_deps(
    569       GetParam(), ProxyService::CreateDirect());
    570   scoped_refptr<HttpNetworkSession> session(
    571       SpdySessionDependencies::SpdyCreateSession(&session_deps));
    572   HttpNetworkSessionPeer peer(session);
    573   CapturePreconnectsTransportSocketPool* transport_conn_pool =
    574       new CapturePreconnectsTransportSocketPool(
    575           session_deps.host_resolver.get(),
    576           session_deps.cert_verifier.get());
    577   scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
    578       new MockClientSocketPoolManager);
    579   mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
    580   peer.SetClientSocketPoolManager(
    581       mock_pool_manager.PassAs<ClientSocketPoolManager>());
    582 
    583   PreconnectHelperForURL(1, GURL("http://www.google.com:7"), session.get());
    584 
    585   EXPECT_EQ(-1, transport_conn_pool->last_num_streams());
    586 }
    587 
    588 TEST_P(HttpStreamFactoryTest, JobNotifiesProxy) {
    589   const char* kProxyString = "PROXY bad:99; PROXY maybe:80; DIRECT";
    590   SpdySessionDependencies session_deps(
    591       GetParam(), ProxyService::CreateFixedFromPacResult(kProxyString));
    592 
    593   // First connection attempt fails
    594   StaticSocketDataProvider socket_data1;
    595   socket_data1.set_connect_data(MockConnect(ASYNC, ERR_ADDRESS_UNREACHABLE));
    596   session_deps.socket_factory->AddSocketDataProvider(&socket_data1);
    597 
    598   // Second connection attempt succeeds
    599   StaticSocketDataProvider socket_data2;
    600   socket_data2.set_connect_data(MockConnect(ASYNC, OK));
    601   session_deps.socket_factory->AddSocketDataProvider(&socket_data2);
    602 
    603   scoped_refptr<HttpNetworkSession> session(
    604       SpdySessionDependencies::SpdyCreateSession(&session_deps));
    605 
    606   // Now request a stream. It should succeed using the second proxy in the
    607   // list.
    608   HttpRequestInfo request_info;
    609   request_info.method = "GET";
    610   request_info.url = GURL("http://www.google.com");
    611 
    612   SSLConfig ssl_config;
    613   StreamRequestWaiter waiter;
    614   scoped_ptr<HttpStreamRequest> request(
    615       session->http_stream_factory()->RequestStream(
    616           request_info, DEFAULT_PRIORITY, ssl_config, ssl_config,
    617           &waiter, BoundNetLog()));
    618   waiter.WaitForStream();
    619 
    620   // The proxy that failed should now be known to the proxy_service as bad.
    621   const ProxyRetryInfoMap& retry_info =
    622       session->proxy_service()->proxy_retry_info();
    623   EXPECT_EQ(1u, retry_info.size());
    624   ProxyRetryInfoMap::const_iterator iter = retry_info.find("bad:99");
    625   EXPECT_TRUE(iter != retry_info.end());
    626 }
    627 
    628 TEST_P(HttpStreamFactoryTest, PrivacyModeDisablesChannelId) {
    629   SpdySessionDependencies session_deps(
    630       GetParam(), ProxyService::CreateDirect());
    631 
    632   StaticSocketDataProvider socket_data;
    633   socket_data.set_connect_data(MockConnect(ASYNC, OK));
    634   session_deps.socket_factory->AddSocketDataProvider(&socket_data);
    635 
    636   SSLSocketDataProvider ssl(ASYNC, OK);
    637   session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
    638 
    639   scoped_refptr<HttpNetworkSession> session(
    640       SpdySessionDependencies::SpdyCreateSession(&session_deps));
    641 
    642   // Set an existing SpdySession in the pool.
    643   HostPortPair host_port_pair("www.google.com", 443);
    644   SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
    645                      PRIVACY_MODE_ENABLED);
    646 
    647   HttpRequestInfo request_info;
    648   request_info.method = "GET";
    649   request_info.url = GURL("https://www.google.com");
    650   request_info.load_flags = 0;
    651   request_info.privacy_mode = PRIVACY_MODE_DISABLED;
    652 
    653   SSLConfig ssl_config;
    654   StreamRequestWaiter waiter;
    655   scoped_ptr<HttpStreamRequest> request(
    656       session->http_stream_factory()->RequestStream(
    657           request_info, DEFAULT_PRIORITY, ssl_config, ssl_config,
    658           &waiter, BoundNetLog()));
    659   waiter.WaitForStream();
    660 
    661   // The stream shouldn't come from spdy as we are using different privacy mode
    662   EXPECT_FALSE(request->using_spdy());
    663 
    664   SSLConfig used_ssl_config = waiter.used_ssl_config();
    665   EXPECT_EQ(used_ssl_config.channel_id_enabled, ssl_config.channel_id_enabled);
    666 }
    667 
    668 namespace {
    669 // Return count of distinct groups in given socket pool.
    670 int GetSocketPoolGroupCount(ClientSocketPool* pool) {
    671   int count = 0;
    672   scoped_ptr<base::DictionaryValue> dict(pool->GetInfoAsValue("", "", false));
    673   EXPECT_TRUE(dict != NULL);
    674   base::DictionaryValue* groups = NULL;
    675   if (dict->GetDictionary("groups", &groups) && (groups != NULL)) {
    676     count = static_cast<int>(groups->size());
    677   }
    678   return count;
    679 }
    680 }  // namespace
    681 
    682 TEST_P(HttpStreamFactoryTest, PrivacyModeUsesDifferentSocketPoolGroup) {
    683   SpdySessionDependencies session_deps(
    684       GetParam(), ProxyService::CreateDirect());
    685 
    686   StaticSocketDataProvider socket_data;
    687   socket_data.set_connect_data(MockConnect(ASYNC, OK));
    688   session_deps.socket_factory->AddSocketDataProvider(&socket_data);
    689 
    690   SSLSocketDataProvider ssl(ASYNC, OK);
    691   session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
    692 
    693   scoped_refptr<HttpNetworkSession> session(
    694       SpdySessionDependencies::SpdyCreateSession(&session_deps));
    695   SSLClientSocketPool* ssl_pool = session->GetSSLSocketPool(
    696       HttpNetworkSession::NORMAL_SOCKET_POOL);
    697 
    698   EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 0);
    699 
    700   HttpRequestInfo request_info;
    701   request_info.method = "GET";
    702   request_info.url = GURL("https://www.google.com");
    703   request_info.load_flags = 0;
    704   request_info.privacy_mode = PRIVACY_MODE_DISABLED;
    705 
    706   SSLConfig ssl_config;
    707   StreamRequestWaiter waiter;
    708 
    709   scoped_ptr<HttpStreamRequest> request1(
    710       session->http_stream_factory()->RequestStream(
    711           request_info, DEFAULT_PRIORITY, ssl_config, ssl_config,
    712           &waiter, BoundNetLog()));
    713   waiter.WaitForStream();
    714 
    715   EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 1);
    716 
    717   scoped_ptr<HttpStreamRequest> request2(
    718       session->http_stream_factory()->RequestStream(
    719           request_info, DEFAULT_PRIORITY, ssl_config, ssl_config,
    720           &waiter, BoundNetLog()));
    721   waiter.WaitForStream();
    722 
    723   EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 1);
    724 
    725   request_info.privacy_mode = PRIVACY_MODE_ENABLED;
    726   scoped_ptr<HttpStreamRequest> request3(
    727       session->http_stream_factory()->RequestStream(
    728           request_info, DEFAULT_PRIORITY, ssl_config, ssl_config,
    729           &waiter, BoundNetLog()));
    730   waiter.WaitForStream();
    731 
    732   EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 2);
    733 }
    734 
    735 TEST_P(HttpStreamFactoryTest, GetLoadState) {
    736   SpdySessionDependencies session_deps(
    737       GetParam(), ProxyService::CreateDirect());
    738 
    739   StaticSocketDataProvider socket_data;
    740   socket_data.set_connect_data(MockConnect(ASYNC, OK));
    741   session_deps.socket_factory->AddSocketDataProvider(&socket_data);
    742 
    743   scoped_refptr<HttpNetworkSession> session(
    744       SpdySessionDependencies::SpdyCreateSession(&session_deps));
    745 
    746   HttpRequestInfo request_info;
    747   request_info.method = "GET";
    748   request_info.url = GURL("http://www.google.com");
    749 
    750   SSLConfig ssl_config;
    751   StreamRequestWaiter waiter;
    752   scoped_ptr<HttpStreamRequest> request(
    753       session->http_stream_factory()->RequestStream(
    754           request_info, DEFAULT_PRIORITY, ssl_config, ssl_config,
    755           &waiter, BoundNetLog()));
    756 
    757   EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, request->GetLoadState());
    758 
    759   waiter.WaitForStream();
    760 }
    761 
    762 TEST_P(HttpStreamFactoryTest, RequestHttpStream) {
    763   SpdySessionDependencies session_deps(
    764       GetParam(), ProxyService::CreateDirect());
    765 
    766   StaticSocketDataProvider socket_data;
    767   socket_data.set_connect_data(MockConnect(ASYNC, OK));
    768   session_deps.socket_factory->AddSocketDataProvider(&socket_data);
    769 
    770   scoped_refptr<HttpNetworkSession> session(
    771       SpdySessionDependencies::SpdyCreateSession(&session_deps));
    772 
    773   // Now request a stream.  It should succeed using the second proxy in the
    774   // list.
    775   HttpRequestInfo request_info;
    776   request_info.method = "GET";
    777   request_info.url = GURL("http://www.google.com");
    778   request_info.load_flags = 0;
    779 
    780   SSLConfig ssl_config;
    781   StreamRequestWaiter waiter;
    782   scoped_ptr<HttpStreamRequest> request(
    783       session->http_stream_factory()->RequestStream(
    784           request_info,
    785           DEFAULT_PRIORITY,
    786           ssl_config,
    787           ssl_config,
    788           &waiter,
    789           BoundNetLog()));
    790   waiter.WaitForStream();
    791   EXPECT_TRUE(waiter.stream_done());
    792   ASSERT_TRUE(NULL != waiter.stream());
    793   EXPECT_TRUE(NULL == waiter.websocket_stream());
    794   EXPECT_FALSE(waiter.stream()->IsSpdyHttpStream());
    795 
    796   EXPECT_EQ(1, GetSocketPoolGroupCount(
    797       session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
    798   EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool(
    799       HttpNetworkSession::NORMAL_SOCKET_POOL)));
    800   EXPECT_EQ(0, GetSocketPoolGroupCount(
    801       session->GetTransportSocketPool(
    802           HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
    803   EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool(
    804       HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
    805   EXPECT_TRUE(waiter.used_proxy_info().is_direct());
    806 }
    807 
    808 TEST_P(HttpStreamFactoryTest, RequestHttpStreamOverSSL) {
    809   SpdySessionDependencies session_deps(
    810       GetParam(), ProxyService::CreateDirect());
    811 
    812   MockRead mock_read(ASYNC, OK);
    813   StaticSocketDataProvider socket_data(&mock_read, 1, NULL, 0);
    814   socket_data.set_connect_data(MockConnect(ASYNC, OK));
    815   session_deps.socket_factory->AddSocketDataProvider(&socket_data);
    816 
    817   SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
    818   session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
    819 
    820   scoped_refptr<HttpNetworkSession> session(
    821       SpdySessionDependencies::SpdyCreateSession(&session_deps));
    822 
    823   // Now request a stream.
    824   HttpRequestInfo request_info;
    825   request_info.method = "GET";
    826   request_info.url = GURL("https://www.google.com");
    827   request_info.load_flags = 0;
    828 
    829   SSLConfig ssl_config;
    830   StreamRequestWaiter waiter;
    831   scoped_ptr<HttpStreamRequest> request(
    832       session->http_stream_factory()->RequestStream(
    833           request_info,
    834           DEFAULT_PRIORITY,
    835           ssl_config,
    836           ssl_config,
    837           &waiter,
    838           BoundNetLog()));
    839   waiter.WaitForStream();
    840   EXPECT_TRUE(waiter.stream_done());
    841   ASSERT_TRUE(NULL != waiter.stream());
    842   EXPECT_TRUE(NULL == waiter.websocket_stream());
    843   EXPECT_FALSE(waiter.stream()->IsSpdyHttpStream());
    844   EXPECT_EQ(1, GetSocketPoolGroupCount(
    845       session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
    846   EXPECT_EQ(1, GetSocketPoolGroupCount(
    847       session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
    848   EXPECT_EQ(0, GetSocketPoolGroupCount(
    849       session->GetTransportSocketPool(
    850           HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
    851   EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool(
    852       HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
    853   EXPECT_TRUE(waiter.used_proxy_info().is_direct());
    854 }
    855 
    856 TEST_P(HttpStreamFactoryTest, RequestHttpStreamOverProxy) {
    857   SpdySessionDependencies session_deps(
    858       GetParam(), ProxyService::CreateFixed("myproxy:8888"));
    859 
    860   StaticSocketDataProvider socket_data;
    861   socket_data.set_connect_data(MockConnect(ASYNC, OK));
    862   session_deps.socket_factory->AddSocketDataProvider(&socket_data);
    863 
    864   scoped_refptr<HttpNetworkSession> session(
    865       SpdySessionDependencies::SpdyCreateSession(&session_deps));
    866 
    867   // Now request a stream.  It should succeed using the second proxy in the
    868   // list.
    869   HttpRequestInfo request_info;
    870   request_info.method = "GET";
    871   request_info.url = GURL("http://www.google.com");
    872   request_info.load_flags = 0;
    873 
    874   SSLConfig ssl_config;
    875   StreamRequestWaiter waiter;
    876   scoped_ptr<HttpStreamRequest> request(
    877       session->http_stream_factory()->RequestStream(
    878           request_info,
    879           DEFAULT_PRIORITY,
    880           ssl_config,
    881           ssl_config,
    882           &waiter,
    883           BoundNetLog()));
    884   waiter.WaitForStream();
    885   EXPECT_TRUE(waiter.stream_done());
    886   ASSERT_TRUE(NULL != waiter.stream());
    887   EXPECT_TRUE(NULL == waiter.websocket_stream());
    888   EXPECT_FALSE(waiter.stream()->IsSpdyHttpStream());
    889   EXPECT_EQ(0, GetSocketPoolGroupCount(
    890       session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
    891   EXPECT_EQ(0, GetSocketPoolGroupCount(
    892       session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
    893   EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSocketPoolForHTTPProxy(
    894       HttpNetworkSession::NORMAL_SOCKET_POOL,
    895       HostPortPair("myproxy", 8888))));
    896   EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForSSLWithProxy(
    897       HttpNetworkSession::NORMAL_SOCKET_POOL,
    898       HostPortPair("myproxy", 8888))));
    899   EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForHTTPProxy(
    900       HttpNetworkSession::WEBSOCKET_SOCKET_POOL,
    901       HostPortPair("myproxy", 8888))));
    902   EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForSSLWithProxy(
    903       HttpNetworkSession::WEBSOCKET_SOCKET_POOL,
    904       HostPortPair("myproxy", 8888))));
    905   EXPECT_FALSE(waiter.used_proxy_info().is_direct());
    906 }
    907 
    908 TEST_P(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStream) {
    909   SpdySessionDependencies session_deps(
    910       GetParam(), ProxyService::CreateDirect());
    911 
    912   StaticSocketDataProvider socket_data;
    913   socket_data.set_connect_data(MockConnect(ASYNC, OK));
    914   session_deps.socket_factory->AddSocketDataProvider(&socket_data);
    915 
    916   scoped_refptr<HttpNetworkSession> session(
    917       SpdySessionDependencies::SpdyCreateSession(&session_deps));
    918 
    919   // Now request a stream.
    920   HttpRequestInfo request_info;
    921   request_info.method = "GET";
    922   request_info.url = GURL("ws://www.google.com");
    923   request_info.load_flags = 0;
    924 
    925   SSLConfig ssl_config;
    926   StreamRequestWaiter waiter;
    927   WebSocketStreamCreateHelper create_helper;
    928   scoped_ptr<HttpStreamRequest> request(
    929       session->http_stream_factory_for_websocket()
    930           ->RequestWebSocketHandshakeStream(request_info,
    931                                             DEFAULT_PRIORITY,
    932                                             ssl_config,
    933                                             ssl_config,
    934                                             &waiter,
    935                                             &create_helper,
    936                                             BoundNetLog()));
    937   waiter.WaitForStream();
    938   EXPECT_TRUE(waiter.stream_done());
    939   EXPECT_TRUE(NULL == waiter.stream());
    940   ASSERT_TRUE(NULL != waiter.websocket_stream());
    941   EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic,
    942             waiter.websocket_stream()->type());
    943   EXPECT_EQ(0, GetSocketPoolGroupCount(
    944       session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
    945   EXPECT_EQ(0, GetSocketPoolGroupCount(
    946       session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
    947   EXPECT_EQ(0, GetSocketPoolGroupCount(
    948       session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
    949   EXPECT_TRUE(waiter.used_proxy_info().is_direct());
    950 }
    951 
    952 TEST_P(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStreamOverSSL) {
    953   SpdySessionDependencies session_deps(
    954       GetParam(), ProxyService::CreateDirect());
    955 
    956   MockRead mock_read(ASYNC, OK);
    957   StaticSocketDataProvider socket_data(&mock_read, 1, NULL, 0);
    958   socket_data.set_connect_data(MockConnect(ASYNC, OK));
    959   session_deps.socket_factory->AddSocketDataProvider(&socket_data);
    960 
    961   SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
    962   session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
    963 
    964   scoped_refptr<HttpNetworkSession> session(
    965       SpdySessionDependencies::SpdyCreateSession(&session_deps));
    966 
    967   // Now request a stream.
    968   HttpRequestInfo request_info;
    969   request_info.method = "GET";
    970   request_info.url = GURL("wss://www.google.com");
    971   request_info.load_flags = 0;
    972 
    973   SSLConfig ssl_config;
    974   StreamRequestWaiter waiter;
    975   WebSocketStreamCreateHelper create_helper;
    976   scoped_ptr<HttpStreamRequest> request(
    977       session->http_stream_factory_for_websocket()
    978           ->RequestWebSocketHandshakeStream(request_info,
    979                                             DEFAULT_PRIORITY,
    980                                             ssl_config,
    981                                             ssl_config,
    982                                             &waiter,
    983                                             &create_helper,
    984                                             BoundNetLog()));
    985   waiter.WaitForStream();
    986   EXPECT_TRUE(waiter.stream_done());
    987   EXPECT_TRUE(NULL == waiter.stream());
    988   ASSERT_TRUE(NULL != waiter.websocket_stream());
    989   EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic,
    990             waiter.websocket_stream()->type());
    991   EXPECT_EQ(0, GetSocketPoolGroupCount(
    992       session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
    993   EXPECT_EQ(0, GetSocketPoolGroupCount(
    994       session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
    995   EXPECT_EQ(1, GetSocketPoolGroupCount(
    996       session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
    997   EXPECT_TRUE(waiter.used_proxy_info().is_direct());
    998 }
    999 
   1000 TEST_P(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStreamOverProxy) {
   1001   SpdySessionDependencies session_deps(
   1002       GetParam(), ProxyService::CreateFixed("myproxy:8888"));
   1003 
   1004   MockRead read(SYNCHRONOUS, "HTTP/1.0 200 Connection established\r\n\r\n");
   1005   StaticSocketDataProvider socket_data(&read, 1, 0, 0);
   1006   socket_data.set_connect_data(MockConnect(ASYNC, OK));
   1007   session_deps.socket_factory->AddSocketDataProvider(&socket_data);
   1008 
   1009   scoped_refptr<HttpNetworkSession> session(
   1010       SpdySessionDependencies::SpdyCreateSession(&session_deps));
   1011 
   1012   // Now request a stream.
   1013   HttpRequestInfo request_info;
   1014   request_info.method = "GET";
   1015   request_info.url = GURL("ws://www.google.com");
   1016   request_info.load_flags = 0;
   1017 
   1018   SSLConfig ssl_config;
   1019   StreamRequestWaiter waiter;
   1020   WebSocketStreamCreateHelper create_helper;
   1021   scoped_ptr<HttpStreamRequest> request(
   1022       session->http_stream_factory_for_websocket()
   1023           ->RequestWebSocketHandshakeStream(request_info,
   1024                                             DEFAULT_PRIORITY,
   1025                                             ssl_config,
   1026                                             ssl_config,
   1027                                             &waiter,
   1028                                             &create_helper,
   1029                                             BoundNetLog()));
   1030   waiter.WaitForStream();
   1031   EXPECT_TRUE(waiter.stream_done());
   1032   EXPECT_TRUE(NULL == waiter.stream());
   1033   ASSERT_TRUE(NULL != waiter.websocket_stream());
   1034   EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic,
   1035             waiter.websocket_stream()->type());
   1036   EXPECT_EQ(0, GetSocketPoolGroupCount(
   1037       session->GetTransportSocketPool(
   1038           HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
   1039   EXPECT_EQ(0, GetSocketPoolGroupCount(
   1040       session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
   1041   EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForHTTPProxy(
   1042       HttpNetworkSession::NORMAL_SOCKET_POOL,
   1043       HostPortPair("myproxy", 8888))));
   1044   EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForSSLWithProxy(
   1045       HttpNetworkSession::NORMAL_SOCKET_POOL,
   1046       HostPortPair("myproxy", 8888))));
   1047   EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSocketPoolForHTTPProxy(
   1048       HttpNetworkSession::WEBSOCKET_SOCKET_POOL,
   1049       HostPortPair("myproxy", 8888))));
   1050   EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForSSLWithProxy(
   1051       HttpNetworkSession::WEBSOCKET_SOCKET_POOL,
   1052       HostPortPair("myproxy", 8888))));
   1053   EXPECT_FALSE(waiter.used_proxy_info().is_direct());
   1054 }
   1055 
   1056 TEST_P(HttpStreamFactoryTest, RequestSpdyHttpStream) {
   1057   SpdySessionDependencies session_deps(GetParam(),
   1058                                        ProxyService::CreateDirect());
   1059 
   1060   MockRead mock_read(ASYNC, OK);
   1061   DeterministicSocketData socket_data(&mock_read, 1, NULL, 0);
   1062   socket_data.set_connect_data(MockConnect(ASYNC, OK));
   1063   session_deps.deterministic_socket_factory->AddSocketDataProvider(
   1064       &socket_data);
   1065 
   1066   SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
   1067   ssl_socket_data.SetNextProto(GetParam());
   1068   session_deps.deterministic_socket_factory->AddSSLSocketDataProvider(
   1069       &ssl_socket_data);
   1070 
   1071   HostPortPair host_port_pair("www.google.com", 443);
   1072   scoped_refptr<HttpNetworkSession>
   1073       session(SpdySessionDependencies::SpdyCreateSessionDeterministic(
   1074           &session_deps));
   1075 
   1076   // Now request a stream.
   1077   HttpRequestInfo request_info;
   1078   request_info.method = "GET";
   1079   request_info.url = GURL("https://www.google.com");
   1080   request_info.load_flags = 0;
   1081 
   1082   SSLConfig ssl_config;
   1083   StreamRequestWaiter waiter;
   1084   scoped_ptr<HttpStreamRequest> request(
   1085       session->http_stream_factory()->RequestStream(
   1086           request_info,
   1087           DEFAULT_PRIORITY,
   1088           ssl_config,
   1089           ssl_config,
   1090           &waiter,
   1091           BoundNetLog()));
   1092   waiter.WaitForStream();
   1093   EXPECT_TRUE(waiter.stream_done());
   1094   EXPECT_TRUE(NULL == waiter.websocket_stream());
   1095   ASSERT_TRUE(NULL != waiter.stream());
   1096   EXPECT_TRUE(waiter.stream()->IsSpdyHttpStream());
   1097   EXPECT_EQ(1, GetSocketPoolGroupCount(
   1098       session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
   1099   EXPECT_EQ(1, GetSocketPoolGroupCount(
   1100       session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
   1101   EXPECT_EQ(0, GetSocketPoolGroupCount(
   1102       session->GetTransportSocketPool(
   1103           HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
   1104   EXPECT_EQ(0, GetSocketPoolGroupCount(
   1105       session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
   1106   EXPECT_TRUE(waiter.used_proxy_info().is_direct());
   1107 }
   1108 
   1109 // TODO(ricea): This test can be removed once the new WebSocket stack supports
   1110 // SPDY. Currently, even if we connect to a SPDY-supporting server, we need to
   1111 // use plain SSL.
   1112 TEST_P(HttpStreamFactoryTest, RequestWebSocketSpdyHandshakeStreamButGetSSL) {
   1113   SpdySessionDependencies session_deps(GetParam(),
   1114                                        ProxyService::CreateDirect());
   1115 
   1116   MockRead mock_read(SYNCHRONOUS, ERR_IO_PENDING);
   1117   StaticSocketDataProvider socket_data(&mock_read, 1, NULL, 0);
   1118   socket_data.set_connect_data(MockConnect(ASYNC, OK));
   1119   session_deps.socket_factory->AddSocketDataProvider(&socket_data);
   1120 
   1121   SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
   1122   session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
   1123 
   1124   HostPortPair host_port_pair("www.google.com", 80);
   1125   scoped_refptr<HttpNetworkSession>
   1126       session(SpdySessionDependencies::SpdyCreateSession(&session_deps));
   1127 
   1128   // Now request a stream.
   1129   HttpRequestInfo request_info;
   1130   request_info.method = "GET";
   1131   request_info.url = GURL("wss://www.google.com");
   1132   request_info.load_flags = 0;
   1133 
   1134   SSLConfig ssl_config;
   1135   StreamRequestWaiter waiter1;
   1136   WebSocketStreamCreateHelper create_helper;
   1137   scoped_ptr<HttpStreamRequest> request1(
   1138       session->http_stream_factory_for_websocket()
   1139           ->RequestWebSocketHandshakeStream(request_info,
   1140                                             DEFAULT_PRIORITY,
   1141                                             ssl_config,
   1142                                             ssl_config,
   1143                                             &waiter1,
   1144                                             &create_helper,
   1145                                             BoundNetLog()));
   1146   waiter1.WaitForStream();
   1147   EXPECT_TRUE(waiter1.stream_done());
   1148   ASSERT_TRUE(NULL != waiter1.websocket_stream());
   1149   EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic,
   1150             waiter1.websocket_stream()->type());
   1151   EXPECT_TRUE(NULL == waiter1.stream());
   1152 
   1153   EXPECT_EQ(0, GetSocketPoolGroupCount(
   1154       session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
   1155   EXPECT_EQ(0, GetSocketPoolGroupCount(
   1156       session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
   1157   EXPECT_EQ(1, GetSocketPoolGroupCount(
   1158       session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
   1159   EXPECT_TRUE(waiter1.used_proxy_info().is_direct());
   1160 }
   1161 
   1162 // TODO(ricea): Re-enable once WebSocket-over-SPDY is implemented.
   1163 TEST_P(HttpStreamFactoryTest, DISABLED_RequestWebSocketSpdyHandshakeStream) {
   1164   SpdySessionDependencies session_deps(GetParam(),
   1165                                        ProxyService::CreateDirect());
   1166 
   1167   MockRead mock_read(SYNCHRONOUS, ERR_IO_PENDING);
   1168   StaticSocketDataProvider socket_data(&mock_read, 1, NULL, 0);
   1169   socket_data.set_connect_data(MockConnect(ASYNC, OK));
   1170   session_deps.socket_factory->AddSocketDataProvider(&socket_data);
   1171 
   1172   SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
   1173   ssl_socket_data.SetNextProto(GetParam());
   1174   session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
   1175 
   1176   HostPortPair host_port_pair("www.google.com", 80);
   1177   scoped_refptr<HttpNetworkSession>
   1178       session(SpdySessionDependencies::SpdyCreateSession(&session_deps));
   1179 
   1180   // Now request a stream.
   1181   HttpRequestInfo request_info;
   1182   request_info.method = "GET";
   1183   request_info.url = GURL("wss://www.google.com");
   1184   request_info.load_flags = 0;
   1185 
   1186   SSLConfig ssl_config;
   1187   StreamRequestWaiter waiter1;
   1188   WebSocketStreamCreateHelper create_helper;
   1189   scoped_ptr<HttpStreamRequest> request1(
   1190       session->http_stream_factory_for_websocket()
   1191           ->RequestWebSocketHandshakeStream(request_info,
   1192                                             DEFAULT_PRIORITY,
   1193                                             ssl_config,
   1194                                             ssl_config,
   1195                                             &waiter1,
   1196                                             &create_helper,
   1197                                             BoundNetLog()));
   1198   waiter1.WaitForStream();
   1199   EXPECT_TRUE(waiter1.stream_done());
   1200   ASSERT_TRUE(NULL != waiter1.websocket_stream());
   1201   EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy,
   1202             waiter1.websocket_stream()->type());
   1203   EXPECT_TRUE(NULL == waiter1.stream());
   1204 
   1205   StreamRequestWaiter waiter2;
   1206   scoped_ptr<HttpStreamRequest> request2(
   1207       session->http_stream_factory_for_websocket()
   1208           ->RequestWebSocketHandshakeStream(request_info,
   1209                                             DEFAULT_PRIORITY,
   1210                                             ssl_config,
   1211                                             ssl_config,
   1212                                             &waiter2,
   1213                                             &create_helper,
   1214                                             BoundNetLog()));
   1215   waiter2.WaitForStream();
   1216   EXPECT_TRUE(waiter2.stream_done());
   1217   ASSERT_TRUE(NULL != waiter2.websocket_stream());
   1218   EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy,
   1219             waiter2.websocket_stream()->type());
   1220   EXPECT_TRUE(NULL == waiter2.stream());
   1221   EXPECT_NE(waiter2.websocket_stream(), waiter1.websocket_stream());
   1222   EXPECT_EQ(static_cast<WebSocketSpdyHandshakeStream*>(
   1223                 waiter2.websocket_stream())->spdy_session(),
   1224             static_cast<WebSocketSpdyHandshakeStream*>(
   1225                 waiter1.websocket_stream())->spdy_session());
   1226 
   1227   EXPECT_EQ(0, GetSocketPoolGroupCount(
   1228       session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
   1229   EXPECT_EQ(0, GetSocketPoolGroupCount(
   1230       session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
   1231   EXPECT_EQ(1, GetSocketPoolGroupCount(
   1232       session->GetTransportSocketPool(
   1233           HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
   1234   EXPECT_EQ(1, GetSocketPoolGroupCount(
   1235       session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
   1236   EXPECT_TRUE(waiter1.used_proxy_info().is_direct());
   1237 }
   1238 
   1239 // TODO(ricea): Re-enable once WebSocket over SPDY is implemented.
   1240 TEST_P(HttpStreamFactoryTest, DISABLED_OrphanedWebSocketStream) {
   1241   SpdySessionDependencies session_deps(GetParam(),
   1242                                        ProxyService::CreateDirect());
   1243   session_deps.use_alternate_protocols = true;
   1244 
   1245   MockRead mock_read(ASYNC, OK);
   1246   DeterministicSocketData socket_data(&mock_read, 1, NULL, 0);
   1247   socket_data.set_connect_data(MockConnect(ASYNC, OK));
   1248   session_deps.deterministic_socket_factory->AddSocketDataProvider(
   1249       &socket_data);
   1250 
   1251   MockRead mock_read2(ASYNC, OK);
   1252   DeterministicSocketData socket_data2(&mock_read2, 1, NULL, 0);
   1253   socket_data2.set_connect_data(MockConnect(ASYNC, ERR_IO_PENDING));
   1254   session_deps.deterministic_socket_factory->AddSocketDataProvider(
   1255       &socket_data2);
   1256 
   1257   SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
   1258   ssl_socket_data.SetNextProto(GetParam());
   1259   session_deps.deterministic_socket_factory->AddSSLSocketDataProvider(
   1260       &ssl_socket_data);
   1261 
   1262   scoped_refptr<HttpNetworkSession>
   1263       session(SpdySessionDependencies::SpdyCreateSessionDeterministic(
   1264           &session_deps));
   1265 
   1266   // Now request a stream.
   1267   HttpRequestInfo request_info;
   1268   request_info.method = "GET";
   1269   request_info.url = GURL("ws://www.google.com:8888");
   1270   request_info.load_flags = 0;
   1271 
   1272   session->http_server_properties()->SetAlternateProtocol(
   1273       HostPortPair("www.google.com", 8888),
   1274       9999,
   1275       NPN_SPDY_3,
   1276       1);
   1277 
   1278   SSLConfig ssl_config;
   1279   StreamRequestWaiter waiter;
   1280   WebSocketStreamCreateHelper create_helper;
   1281   scoped_ptr<HttpStreamRequest> request(
   1282       session->http_stream_factory_for_websocket()
   1283           ->RequestWebSocketHandshakeStream(request_info,
   1284                                             DEFAULT_PRIORITY,
   1285                                             ssl_config,
   1286                                             ssl_config,
   1287                                             &waiter,
   1288                                             &create_helper,
   1289                                             BoundNetLog()));
   1290   waiter.WaitForStream();
   1291   EXPECT_TRUE(waiter.stream_done());
   1292   EXPECT_TRUE(NULL == waiter.stream());
   1293   ASSERT_TRUE(NULL != waiter.websocket_stream());
   1294   EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy,
   1295             waiter.websocket_stream()->type());
   1296 
   1297   // Make sure that there was an alternative connection
   1298   // which consumes extra connections.
   1299   EXPECT_EQ(0, GetSocketPoolGroupCount(
   1300       session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
   1301   EXPECT_EQ(0, GetSocketPoolGroupCount(
   1302       session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
   1303   EXPECT_EQ(2, GetSocketPoolGroupCount(
   1304       session->GetTransportSocketPool(
   1305           HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
   1306   EXPECT_EQ(1, GetSocketPoolGroupCount(
   1307       session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
   1308   EXPECT_TRUE(waiter.used_proxy_info().is_direct());
   1309 
   1310   // Make sure there is no orphaned job. it is already canceled.
   1311   ASSERT_EQ(0u, static_cast<HttpStreamFactoryImpl*>(
   1312       session->http_stream_factory_for_websocket())->num_orphaned_jobs());
   1313 }
   1314 
   1315 }  // namespace
   1316 
   1317 }  // namespace net
   1318