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(0, 0, NULL, host_resolver, NULL, NULL, NULL),
    398       last_num_streams_(-1) {}
    399 
    400 template <>
    401 CapturePreconnectsSSLSocketPool::CapturePreconnectsSocketPool(
    402     HostResolver* host_resolver,
    403     CertVerifier* cert_verifier)
    404     : SSLClientSocketPool(0,
    405                           0,
    406                           NULL,           // ssl_histograms
    407                           host_resolver,
    408                           cert_verifier,
    409                           NULL,           // server_bound_cert_store
    410                           NULL,           // transport_security_state
    411                           NULL,           // cert_transparency_verifier
    412                           std::string(),  // ssl_session_cache_shard
    413                           NULL,           // deterministic_socket_factory
    414                           NULL,           // transport_socket_pool
    415                           NULL,
    416                           NULL,
    417                           NULL,           // ssl_config_service
    418                           NULL),          // net_log
    419       last_num_streams_(-1) {}
    420 
    421 class HttpStreamFactoryTest : public ::testing::Test,
    422                               public ::testing::WithParamInterface<NextProto> {
    423 };
    424 
    425 INSTANTIATE_TEST_CASE_P(
    426     NextProto,
    427     HttpStreamFactoryTest,
    428     testing::Values(kProtoDeprecatedSPDY2,
    429                     kProtoSPDY3, kProtoSPDY31, kProtoSPDY4));
    430 
    431 TEST_P(HttpStreamFactoryTest, PreconnectDirect) {
    432   for (size_t i = 0; i < arraysize(kTests); ++i) {
    433     SpdySessionDependencies session_deps(
    434         GetParam(), ProxyService::CreateDirect());
    435     scoped_refptr<HttpNetworkSession> session(
    436         SpdySessionDependencies::SpdyCreateSession(&session_deps));
    437     HttpNetworkSessionPeer peer(session);
    438     CapturePreconnectsTransportSocketPool* transport_conn_pool =
    439         new CapturePreconnectsTransportSocketPool(
    440             session_deps.host_resolver.get(),
    441             session_deps.cert_verifier.get());
    442     CapturePreconnectsSSLSocketPool* ssl_conn_pool =
    443         new CapturePreconnectsSSLSocketPool(
    444             session_deps.host_resolver.get(),
    445             session_deps.cert_verifier.get());
    446     scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
    447         new MockClientSocketPoolManager);
    448     mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
    449     mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
    450     peer.SetClientSocketPoolManager(
    451         mock_pool_manager.PassAs<ClientSocketPoolManager>());
    452     PreconnectHelper(kTests[i], session.get());
    453     if (kTests[i].ssl)
    454       EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams());
    455     else
    456       EXPECT_EQ(kTests[i].num_streams, transport_conn_pool->last_num_streams());
    457   }
    458 }
    459 
    460 TEST_P(HttpStreamFactoryTest, PreconnectHttpProxy) {
    461   for (size_t i = 0; i < arraysize(kTests); ++i) {
    462     SpdySessionDependencies session_deps(
    463         GetParam(), ProxyService::CreateFixed("http_proxy"));
    464     scoped_refptr<HttpNetworkSession> session(
    465         SpdySessionDependencies::SpdyCreateSession(&session_deps));
    466     HttpNetworkSessionPeer peer(session);
    467     HostPortPair proxy_host("http_proxy", 80);
    468     CapturePreconnectsHttpProxySocketPool* http_proxy_pool =
    469         new CapturePreconnectsHttpProxySocketPool(
    470             session_deps.host_resolver.get(),
    471             session_deps.cert_verifier.get());
    472     CapturePreconnectsSSLSocketPool* ssl_conn_pool =
    473         new CapturePreconnectsSSLSocketPool(
    474             session_deps.host_resolver.get(),
    475             session_deps.cert_verifier.get());
    476     scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
    477         new MockClientSocketPoolManager);
    478     mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
    479     mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
    480     peer.SetClientSocketPoolManager(
    481         mock_pool_manager.PassAs<ClientSocketPoolManager>());
    482     PreconnectHelper(kTests[i], session.get());
    483     if (kTests[i].ssl)
    484       EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams());
    485     else
    486       EXPECT_EQ(kTests[i].num_streams, http_proxy_pool->last_num_streams());
    487   }
    488 }
    489 
    490 TEST_P(HttpStreamFactoryTest, PreconnectSocksProxy) {
    491   for (size_t i = 0; i < arraysize(kTests); ++i) {
    492     SpdySessionDependencies session_deps(
    493         GetParam(), ProxyService::CreateFixed("socks4://socks_proxy:1080"));
    494     scoped_refptr<HttpNetworkSession> session(
    495         SpdySessionDependencies::SpdyCreateSession(&session_deps));
    496     HttpNetworkSessionPeer peer(session);
    497     HostPortPair proxy_host("socks_proxy", 1080);
    498     CapturePreconnectsSOCKSSocketPool* socks_proxy_pool =
    499         new CapturePreconnectsSOCKSSocketPool(
    500             session_deps.host_resolver.get(),
    501             session_deps.cert_verifier.get());
    502     CapturePreconnectsSSLSocketPool* ssl_conn_pool =
    503         new CapturePreconnectsSSLSocketPool(
    504             session_deps.host_resolver.get(),
    505             session_deps.cert_verifier.get());
    506     scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
    507         new MockClientSocketPoolManager);
    508     mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_proxy_pool);
    509     mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
    510     peer.SetClientSocketPoolManager(
    511         mock_pool_manager.PassAs<ClientSocketPoolManager>());
    512     PreconnectHelper(kTests[i], session.get());
    513     if (kTests[i].ssl)
    514       EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams());
    515     else
    516       EXPECT_EQ(kTests[i].num_streams, socks_proxy_pool->last_num_streams());
    517   }
    518 }
    519 
    520 TEST_P(HttpStreamFactoryTest, PreconnectDirectWithExistingSpdySession) {
    521   for (size_t i = 0; i < arraysize(kTests); ++i) {
    522     SpdySessionDependencies session_deps(
    523         GetParam(), ProxyService::CreateDirect());
    524     scoped_refptr<HttpNetworkSession> session(
    525         SpdySessionDependencies::SpdyCreateSession(&session_deps));
    526     HttpNetworkSessionPeer peer(session);
    527 
    528     // Put a SpdySession in the pool.
    529     HostPortPair host_port_pair("www.google.com", 443);
    530     SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
    531                        PRIVACY_MODE_DISABLED);
    532     ignore_result(CreateFakeSpdySession(session->spdy_session_pool(), key));
    533 
    534     CapturePreconnectsTransportSocketPool* transport_conn_pool =
    535         new CapturePreconnectsTransportSocketPool(
    536             session_deps.host_resolver.get(),
    537             session_deps.cert_verifier.get());
    538     CapturePreconnectsSSLSocketPool* ssl_conn_pool =
    539         new CapturePreconnectsSSLSocketPool(
    540             session_deps.host_resolver.get(),
    541             session_deps.cert_verifier.get());
    542     scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
    543         new MockClientSocketPoolManager);
    544     mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
    545     mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
    546     peer.SetClientSocketPoolManager(
    547         mock_pool_manager.PassAs<ClientSocketPoolManager>());
    548     PreconnectHelper(kTests[i], session.get());
    549     // We shouldn't be preconnecting if we have an existing session, which is
    550     // the case for https://www.google.com.
    551     if (kTests[i].ssl)
    552       EXPECT_EQ(-1, ssl_conn_pool->last_num_streams());
    553     else
    554       EXPECT_EQ(kTests[i].num_streams,
    555                 transport_conn_pool->last_num_streams());
    556   }
    557 }
    558 
    559 // Verify that preconnects to unsafe ports are cancelled before they reach
    560 // the SocketPool.
    561 TEST_P(HttpStreamFactoryTest, PreconnectUnsafePort) {
    562   ASSERT_FALSE(IsPortAllowedByDefault(7));
    563   ASSERT_FALSE(IsPortAllowedByOverride(7));
    564 
    565   SpdySessionDependencies session_deps(
    566       GetParam(), ProxyService::CreateDirect());
    567   scoped_refptr<HttpNetworkSession> session(
    568       SpdySessionDependencies::SpdyCreateSession(&session_deps));
    569   HttpNetworkSessionPeer peer(session);
    570   CapturePreconnectsTransportSocketPool* transport_conn_pool =
    571       new CapturePreconnectsTransportSocketPool(
    572           session_deps.host_resolver.get(),
    573           session_deps.cert_verifier.get());
    574   scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
    575       new MockClientSocketPoolManager);
    576   mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
    577   peer.SetClientSocketPoolManager(
    578       mock_pool_manager.PassAs<ClientSocketPoolManager>());
    579 
    580   PreconnectHelperForURL(1, GURL("http://www.google.com:7"), session.get());
    581 
    582   EXPECT_EQ(-1, transport_conn_pool->last_num_streams());
    583 }
    584 
    585 TEST_P(HttpStreamFactoryTest, JobNotifiesProxy) {
    586   const char* kProxyString = "PROXY bad:99; PROXY maybe:80; DIRECT";
    587   SpdySessionDependencies session_deps(
    588       GetParam(), ProxyService::CreateFixedFromPacResult(kProxyString));
    589 
    590   // First connection attempt fails
    591   StaticSocketDataProvider socket_data1;
    592   socket_data1.set_connect_data(MockConnect(ASYNC, ERR_ADDRESS_UNREACHABLE));
    593   session_deps.socket_factory->AddSocketDataProvider(&socket_data1);
    594 
    595   // Second connection attempt succeeds
    596   StaticSocketDataProvider socket_data2;
    597   socket_data2.set_connect_data(MockConnect(ASYNC, OK));
    598   session_deps.socket_factory->AddSocketDataProvider(&socket_data2);
    599 
    600   scoped_refptr<HttpNetworkSession> session(
    601       SpdySessionDependencies::SpdyCreateSession(&session_deps));
    602 
    603   // Now request a stream. It should succeed using the second proxy in the
    604   // list.
    605   HttpRequestInfo request_info;
    606   request_info.method = "GET";
    607   request_info.url = GURL("http://www.google.com");
    608 
    609   SSLConfig ssl_config;
    610   StreamRequestWaiter waiter;
    611   scoped_ptr<HttpStreamRequest> request(
    612       session->http_stream_factory()->RequestStream(
    613           request_info, DEFAULT_PRIORITY, ssl_config, ssl_config,
    614           &waiter, BoundNetLog()));
    615   waiter.WaitForStream();
    616 
    617   // The proxy that failed should now be known to the proxy_service as bad.
    618   const ProxyRetryInfoMap& retry_info =
    619       session->proxy_service()->proxy_retry_info();
    620   EXPECT_EQ(1u, retry_info.size());
    621   ProxyRetryInfoMap::const_iterator iter = retry_info.find("bad:99");
    622   EXPECT_TRUE(iter != retry_info.end());
    623 }
    624 
    625 TEST_P(HttpStreamFactoryTest, PrivacyModeDisablesChannelId) {
    626   SpdySessionDependencies session_deps(
    627       GetParam(), ProxyService::CreateDirect());
    628 
    629   StaticSocketDataProvider socket_data;
    630   socket_data.set_connect_data(MockConnect(ASYNC, OK));
    631   session_deps.socket_factory->AddSocketDataProvider(&socket_data);
    632 
    633   SSLSocketDataProvider ssl(ASYNC, OK);
    634   session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
    635 
    636   scoped_refptr<HttpNetworkSession> session(
    637       SpdySessionDependencies::SpdyCreateSession(&session_deps));
    638 
    639   // Set an existing SpdySession in the pool.
    640   HostPortPair host_port_pair("www.google.com", 443);
    641   SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
    642                      PRIVACY_MODE_ENABLED);
    643 
    644   HttpRequestInfo request_info;
    645   request_info.method = "GET";
    646   request_info.url = GURL("https://www.google.com");
    647   request_info.load_flags = 0;
    648   request_info.privacy_mode = PRIVACY_MODE_DISABLED;
    649 
    650   SSLConfig ssl_config;
    651   StreamRequestWaiter waiter;
    652   scoped_ptr<HttpStreamRequest> request(
    653       session->http_stream_factory()->RequestStream(
    654           request_info, DEFAULT_PRIORITY, ssl_config, ssl_config,
    655           &waiter, BoundNetLog()));
    656   waiter.WaitForStream();
    657 
    658   // The stream shouldn't come from spdy as we are using different privacy mode
    659   EXPECT_FALSE(request->using_spdy());
    660 
    661   SSLConfig used_ssl_config = waiter.used_ssl_config();
    662   EXPECT_EQ(used_ssl_config.channel_id_enabled, ssl_config.channel_id_enabled);
    663 }
    664 
    665 namespace {
    666 // Return count of distinct groups in given socket pool.
    667 int GetSocketPoolGroupCount(ClientSocketPool* pool) {
    668   int count = 0;
    669   scoped_ptr<base::DictionaryValue> dict(pool->GetInfoAsValue("", "", false));
    670   EXPECT_TRUE(dict != NULL);
    671   base::DictionaryValue* groups = NULL;
    672   if (dict->GetDictionary("groups", &groups) && (groups != NULL)) {
    673     count = static_cast<int>(groups->size());
    674   }
    675   return count;
    676 }
    677 }  // namespace
    678 
    679 TEST_P(HttpStreamFactoryTest, PrivacyModeUsesDifferentSocketPoolGroup) {
    680   SpdySessionDependencies session_deps(
    681       GetParam(), ProxyService::CreateDirect());
    682 
    683   StaticSocketDataProvider socket_data;
    684   socket_data.set_connect_data(MockConnect(ASYNC, OK));
    685   session_deps.socket_factory->AddSocketDataProvider(&socket_data);
    686 
    687   SSLSocketDataProvider ssl(ASYNC, OK);
    688   session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
    689 
    690   scoped_refptr<HttpNetworkSession> session(
    691       SpdySessionDependencies::SpdyCreateSession(&session_deps));
    692   SSLClientSocketPool* ssl_pool = session->GetSSLSocketPool(
    693       HttpNetworkSession::NORMAL_SOCKET_POOL);
    694 
    695   EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 0);
    696 
    697   HttpRequestInfo request_info;
    698   request_info.method = "GET";
    699   request_info.url = GURL("https://www.google.com");
    700   request_info.load_flags = 0;
    701   request_info.privacy_mode = PRIVACY_MODE_DISABLED;
    702 
    703   SSLConfig ssl_config;
    704   StreamRequestWaiter waiter;
    705 
    706   scoped_ptr<HttpStreamRequest> request1(
    707       session->http_stream_factory()->RequestStream(
    708           request_info, DEFAULT_PRIORITY, ssl_config, ssl_config,
    709           &waiter, BoundNetLog()));
    710   waiter.WaitForStream();
    711 
    712   EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 1);
    713 
    714   scoped_ptr<HttpStreamRequest> request2(
    715       session->http_stream_factory()->RequestStream(
    716           request_info, DEFAULT_PRIORITY, ssl_config, ssl_config,
    717           &waiter, BoundNetLog()));
    718   waiter.WaitForStream();
    719 
    720   EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 1);
    721 
    722   request_info.privacy_mode = PRIVACY_MODE_ENABLED;
    723   scoped_ptr<HttpStreamRequest> request3(
    724       session->http_stream_factory()->RequestStream(
    725           request_info, DEFAULT_PRIORITY, ssl_config, ssl_config,
    726           &waiter, BoundNetLog()));
    727   waiter.WaitForStream();
    728 
    729   EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 2);
    730 }
    731 
    732 TEST_P(HttpStreamFactoryTest, GetLoadState) {
    733   SpdySessionDependencies session_deps(
    734       GetParam(), ProxyService::CreateDirect());
    735 
    736   StaticSocketDataProvider socket_data;
    737   socket_data.set_connect_data(MockConnect(ASYNC, OK));
    738   session_deps.socket_factory->AddSocketDataProvider(&socket_data);
    739 
    740   scoped_refptr<HttpNetworkSession> session(
    741       SpdySessionDependencies::SpdyCreateSession(&session_deps));
    742 
    743   HttpRequestInfo request_info;
    744   request_info.method = "GET";
    745   request_info.url = GURL("http://www.google.com");
    746 
    747   SSLConfig ssl_config;
    748   StreamRequestWaiter waiter;
    749   scoped_ptr<HttpStreamRequest> request(
    750       session->http_stream_factory()->RequestStream(
    751           request_info, DEFAULT_PRIORITY, ssl_config, ssl_config,
    752           &waiter, BoundNetLog()));
    753 
    754   EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, request->GetLoadState());
    755 
    756   waiter.WaitForStream();
    757 }
    758 
    759 TEST_P(HttpStreamFactoryTest, RequestHttpStream) {
    760   SpdySessionDependencies session_deps(
    761       GetParam(), ProxyService::CreateDirect());
    762 
    763   StaticSocketDataProvider socket_data;
    764   socket_data.set_connect_data(MockConnect(ASYNC, OK));
    765   session_deps.socket_factory->AddSocketDataProvider(&socket_data);
    766 
    767   scoped_refptr<HttpNetworkSession> session(
    768       SpdySessionDependencies::SpdyCreateSession(&session_deps));
    769 
    770   // Now request a stream.  It should succeed using the second proxy in the
    771   // list.
    772   HttpRequestInfo request_info;
    773   request_info.method = "GET";
    774   request_info.url = GURL("http://www.google.com");
    775   request_info.load_flags = 0;
    776 
    777   SSLConfig ssl_config;
    778   StreamRequestWaiter waiter;
    779   scoped_ptr<HttpStreamRequest> request(
    780       session->http_stream_factory()->RequestStream(
    781           request_info,
    782           DEFAULT_PRIORITY,
    783           ssl_config,
    784           ssl_config,
    785           &waiter,
    786           BoundNetLog()));
    787   waiter.WaitForStream();
    788   EXPECT_TRUE(waiter.stream_done());
    789   ASSERT_TRUE(NULL != waiter.stream());
    790   EXPECT_TRUE(NULL == waiter.websocket_stream());
    791   EXPECT_FALSE(waiter.stream()->IsSpdyHttpStream());
    792 
    793   EXPECT_EQ(1, GetSocketPoolGroupCount(
    794       session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
    795   EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool(
    796       HttpNetworkSession::NORMAL_SOCKET_POOL)));
    797   EXPECT_EQ(0, GetSocketPoolGroupCount(
    798       session->GetTransportSocketPool(
    799           HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
    800   EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool(
    801       HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
    802   EXPECT_TRUE(waiter.used_proxy_info().is_direct());
    803 }
    804 
    805 TEST_P(HttpStreamFactoryTest, RequestHttpStreamOverSSL) {
    806   SpdySessionDependencies session_deps(
    807       GetParam(), ProxyService::CreateDirect());
    808 
    809   MockRead mock_read(ASYNC, OK);
    810   StaticSocketDataProvider socket_data(&mock_read, 1, NULL, 0);
    811   socket_data.set_connect_data(MockConnect(ASYNC, OK));
    812   session_deps.socket_factory->AddSocketDataProvider(&socket_data);
    813 
    814   SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
    815   session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
    816 
    817   scoped_refptr<HttpNetworkSession> session(
    818       SpdySessionDependencies::SpdyCreateSession(&session_deps));
    819 
    820   // Now request a stream.
    821   HttpRequestInfo request_info;
    822   request_info.method = "GET";
    823   request_info.url = GURL("https://www.google.com");
    824   request_info.load_flags = 0;
    825 
    826   SSLConfig ssl_config;
    827   StreamRequestWaiter waiter;
    828   scoped_ptr<HttpStreamRequest> request(
    829       session->http_stream_factory()->RequestStream(
    830           request_info,
    831           DEFAULT_PRIORITY,
    832           ssl_config,
    833           ssl_config,
    834           &waiter,
    835           BoundNetLog()));
    836   waiter.WaitForStream();
    837   EXPECT_TRUE(waiter.stream_done());
    838   ASSERT_TRUE(NULL != waiter.stream());
    839   EXPECT_TRUE(NULL == waiter.websocket_stream());
    840   EXPECT_FALSE(waiter.stream()->IsSpdyHttpStream());
    841   EXPECT_EQ(1, GetSocketPoolGroupCount(
    842       session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
    843   EXPECT_EQ(1, GetSocketPoolGroupCount(
    844       session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
    845   EXPECT_EQ(0, GetSocketPoolGroupCount(
    846       session->GetTransportSocketPool(
    847           HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
    848   EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool(
    849       HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
    850   EXPECT_TRUE(waiter.used_proxy_info().is_direct());
    851 }
    852 
    853 TEST_P(HttpStreamFactoryTest, RequestHttpStreamOverProxy) {
    854   SpdySessionDependencies session_deps(
    855       GetParam(), ProxyService::CreateFixed("myproxy:8888"));
    856 
    857   StaticSocketDataProvider socket_data;
    858   socket_data.set_connect_data(MockConnect(ASYNC, OK));
    859   session_deps.socket_factory->AddSocketDataProvider(&socket_data);
    860 
    861   scoped_refptr<HttpNetworkSession> session(
    862       SpdySessionDependencies::SpdyCreateSession(&session_deps));
    863 
    864   // Now request a stream.  It should succeed using the second proxy in the
    865   // list.
    866   HttpRequestInfo request_info;
    867   request_info.method = "GET";
    868   request_info.url = GURL("http://www.google.com");
    869   request_info.load_flags = 0;
    870 
    871   SSLConfig ssl_config;
    872   StreamRequestWaiter waiter;
    873   scoped_ptr<HttpStreamRequest> request(
    874       session->http_stream_factory()->RequestStream(
    875           request_info,
    876           DEFAULT_PRIORITY,
    877           ssl_config,
    878           ssl_config,
    879           &waiter,
    880           BoundNetLog()));
    881   waiter.WaitForStream();
    882   EXPECT_TRUE(waiter.stream_done());
    883   ASSERT_TRUE(NULL != waiter.stream());
    884   EXPECT_TRUE(NULL == waiter.websocket_stream());
    885   EXPECT_FALSE(waiter.stream()->IsSpdyHttpStream());
    886   EXPECT_EQ(0, GetSocketPoolGroupCount(
    887       session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
    888   EXPECT_EQ(0, GetSocketPoolGroupCount(
    889       session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
    890   EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSocketPoolForHTTPProxy(
    891       HttpNetworkSession::NORMAL_SOCKET_POOL,
    892       HostPortPair("myproxy", 8888))));
    893   EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForSSLWithProxy(
    894       HttpNetworkSession::NORMAL_SOCKET_POOL,
    895       HostPortPair("myproxy", 8888))));
    896   EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForHTTPProxy(
    897       HttpNetworkSession::WEBSOCKET_SOCKET_POOL,
    898       HostPortPair("myproxy", 8888))));
    899   EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForSSLWithProxy(
    900       HttpNetworkSession::WEBSOCKET_SOCKET_POOL,
    901       HostPortPair("myproxy", 8888))));
    902   EXPECT_FALSE(waiter.used_proxy_info().is_direct());
    903 }
    904 
    905 TEST_P(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStream) {
    906   SpdySessionDependencies session_deps(
    907       GetParam(), ProxyService::CreateDirect());
    908 
    909   StaticSocketDataProvider socket_data;
    910   socket_data.set_connect_data(MockConnect(ASYNC, OK));
    911   session_deps.socket_factory->AddSocketDataProvider(&socket_data);
    912 
    913   scoped_refptr<HttpNetworkSession> session(
    914       SpdySessionDependencies::SpdyCreateSession(&session_deps));
    915 
    916   // Now request a stream.
    917   HttpRequestInfo request_info;
    918   request_info.method = "GET";
    919   request_info.url = GURL("ws://www.google.com");
    920   request_info.load_flags = 0;
    921 
    922   SSLConfig ssl_config;
    923   StreamRequestWaiter waiter;
    924   WebSocketStreamCreateHelper create_helper;
    925   scoped_ptr<HttpStreamRequest> request(
    926       session->http_stream_factory_for_websocket()
    927           ->RequestWebSocketHandshakeStream(request_info,
    928                                             DEFAULT_PRIORITY,
    929                                             ssl_config,
    930                                             ssl_config,
    931                                             &waiter,
    932                                             &create_helper,
    933                                             BoundNetLog()));
    934   waiter.WaitForStream();
    935   EXPECT_TRUE(waiter.stream_done());
    936   EXPECT_TRUE(NULL == waiter.stream());
    937   ASSERT_TRUE(NULL != waiter.websocket_stream());
    938   EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic,
    939             waiter.websocket_stream()->type());
    940   EXPECT_EQ(0, GetSocketPoolGroupCount(
    941       session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
    942   EXPECT_EQ(0, GetSocketPoolGroupCount(
    943       session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
    944   EXPECT_EQ(1, GetSocketPoolGroupCount(
    945       session->GetTransportSocketPool(
    946           HttpNetworkSession::WEBSOCKET_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->GetTransportSocketPool(
    997           HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
    998   EXPECT_EQ(1, GetSocketPoolGroupCount(
    999       session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
   1000   EXPECT_TRUE(waiter.used_proxy_info().is_direct());
   1001 }
   1002 
   1003 TEST_P(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStreamOverProxy) {
   1004   SpdySessionDependencies session_deps(
   1005       GetParam(), ProxyService::CreateFixed("myproxy:8888"));
   1006 
   1007   MockRead read(SYNCHRONOUS, "HTTP/1.0 200 Connection established\r\n\r\n");
   1008   StaticSocketDataProvider socket_data(&read, 1, 0, 0);
   1009   socket_data.set_connect_data(MockConnect(ASYNC, OK));
   1010   session_deps.socket_factory->AddSocketDataProvider(&socket_data);
   1011 
   1012   scoped_refptr<HttpNetworkSession> session(
   1013       SpdySessionDependencies::SpdyCreateSession(&session_deps));
   1014 
   1015   // Now request a stream.
   1016   HttpRequestInfo request_info;
   1017   request_info.method = "GET";
   1018   request_info.url = GURL("ws://www.google.com");
   1019   request_info.load_flags = 0;
   1020 
   1021   SSLConfig ssl_config;
   1022   StreamRequestWaiter waiter;
   1023   WebSocketStreamCreateHelper create_helper;
   1024   scoped_ptr<HttpStreamRequest> request(
   1025       session->http_stream_factory_for_websocket()
   1026           ->RequestWebSocketHandshakeStream(request_info,
   1027                                             DEFAULT_PRIORITY,
   1028                                             ssl_config,
   1029                                             ssl_config,
   1030                                             &waiter,
   1031                                             &create_helper,
   1032                                             BoundNetLog()));
   1033   waiter.WaitForStream();
   1034   EXPECT_TRUE(waiter.stream_done());
   1035   EXPECT_TRUE(NULL == waiter.stream());
   1036   ASSERT_TRUE(NULL != waiter.websocket_stream());
   1037   EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic,
   1038             waiter.websocket_stream()->type());
   1039   EXPECT_EQ(0, GetSocketPoolGroupCount(
   1040       session->GetTransportSocketPool(
   1041           HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
   1042   EXPECT_EQ(0, GetSocketPoolGroupCount(
   1043       session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
   1044   EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForHTTPProxy(
   1045       HttpNetworkSession::NORMAL_SOCKET_POOL,
   1046       HostPortPair("myproxy", 8888))));
   1047   EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForSSLWithProxy(
   1048       HttpNetworkSession::NORMAL_SOCKET_POOL,
   1049       HostPortPair("myproxy", 8888))));
   1050   EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSocketPoolForHTTPProxy(
   1051       HttpNetworkSession::WEBSOCKET_SOCKET_POOL,
   1052       HostPortPair("myproxy", 8888))));
   1053   EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForSSLWithProxy(
   1054       HttpNetworkSession::WEBSOCKET_SOCKET_POOL,
   1055       HostPortPair("myproxy", 8888))));
   1056   EXPECT_FALSE(waiter.used_proxy_info().is_direct());
   1057 }
   1058 
   1059 TEST_P(HttpStreamFactoryTest, RequestSpdyHttpStream) {
   1060   SpdySessionDependencies session_deps(GetParam(),
   1061                                        ProxyService::CreateDirect());
   1062 
   1063   MockRead mock_read(ASYNC, OK);
   1064   DeterministicSocketData socket_data(&mock_read, 1, NULL, 0);
   1065   socket_data.set_connect_data(MockConnect(ASYNC, OK));
   1066   session_deps.deterministic_socket_factory->AddSocketDataProvider(
   1067       &socket_data);
   1068 
   1069   SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
   1070   ssl_socket_data.SetNextProto(GetParam());
   1071   session_deps.deterministic_socket_factory->AddSSLSocketDataProvider(
   1072       &ssl_socket_data);
   1073 
   1074   HostPortPair host_port_pair("www.google.com", 443);
   1075   scoped_refptr<HttpNetworkSession>
   1076       session(SpdySessionDependencies::SpdyCreateSessionDeterministic(
   1077           &session_deps));
   1078 
   1079   // Now request a stream.
   1080   HttpRequestInfo request_info;
   1081   request_info.method = "GET";
   1082   request_info.url = GURL("https://www.google.com");
   1083   request_info.load_flags = 0;
   1084 
   1085   SSLConfig ssl_config;
   1086   StreamRequestWaiter waiter;
   1087   scoped_ptr<HttpStreamRequest> request(
   1088       session->http_stream_factory()->RequestStream(
   1089           request_info,
   1090           DEFAULT_PRIORITY,
   1091           ssl_config,
   1092           ssl_config,
   1093           &waiter,
   1094           BoundNetLog()));
   1095   waiter.WaitForStream();
   1096   EXPECT_TRUE(waiter.stream_done());
   1097   EXPECT_TRUE(NULL == waiter.websocket_stream());
   1098   ASSERT_TRUE(NULL != waiter.stream());
   1099   EXPECT_TRUE(waiter.stream()->IsSpdyHttpStream());
   1100   EXPECT_EQ(1, GetSocketPoolGroupCount(
   1101       session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
   1102   EXPECT_EQ(1, GetSocketPoolGroupCount(
   1103       session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
   1104   EXPECT_EQ(0, GetSocketPoolGroupCount(
   1105       session->GetTransportSocketPool(
   1106           HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
   1107   EXPECT_EQ(0, GetSocketPoolGroupCount(
   1108       session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
   1109   EXPECT_TRUE(waiter.used_proxy_info().is_direct());
   1110 }
   1111 
   1112 // TODO(ricea): This test can be removed once the new WebSocket stack supports
   1113 // SPDY. Currently, even if we connect to a SPDY-supporting server, we need to
   1114 // use plain SSL.
   1115 TEST_P(HttpStreamFactoryTest, RequestWebSocketSpdyHandshakeStreamButGetSSL) {
   1116   SpdySessionDependencies session_deps(GetParam(),
   1117                                        ProxyService::CreateDirect());
   1118 
   1119   MockRead mock_read(SYNCHRONOUS, ERR_IO_PENDING);
   1120   StaticSocketDataProvider socket_data(&mock_read, 1, NULL, 0);
   1121   socket_data.set_connect_data(MockConnect(ASYNC, OK));
   1122   session_deps.socket_factory->AddSocketDataProvider(&socket_data);
   1123 
   1124   SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
   1125   session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
   1126 
   1127   HostPortPair host_port_pair("www.google.com", 80);
   1128   scoped_refptr<HttpNetworkSession>
   1129       session(SpdySessionDependencies::SpdyCreateSession(&session_deps));
   1130 
   1131   // Now request a stream.
   1132   HttpRequestInfo request_info;
   1133   request_info.method = "GET";
   1134   request_info.url = GURL("wss://www.google.com");
   1135   request_info.load_flags = 0;
   1136 
   1137   SSLConfig ssl_config;
   1138   StreamRequestWaiter waiter1;
   1139   WebSocketStreamCreateHelper create_helper;
   1140   scoped_ptr<HttpStreamRequest> request1(
   1141       session->http_stream_factory_for_websocket()
   1142           ->RequestWebSocketHandshakeStream(request_info,
   1143                                             DEFAULT_PRIORITY,
   1144                                             ssl_config,
   1145                                             ssl_config,
   1146                                             &waiter1,
   1147                                             &create_helper,
   1148                                             BoundNetLog()));
   1149   waiter1.WaitForStream();
   1150   EXPECT_TRUE(waiter1.stream_done());
   1151   ASSERT_TRUE(NULL != waiter1.websocket_stream());
   1152   EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic,
   1153             waiter1.websocket_stream()->type());
   1154   EXPECT_TRUE(NULL == waiter1.stream());
   1155 
   1156   EXPECT_EQ(0, GetSocketPoolGroupCount(
   1157       session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
   1158   EXPECT_EQ(0, GetSocketPoolGroupCount(
   1159       session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
   1160   EXPECT_EQ(1, GetSocketPoolGroupCount(
   1161       session->GetTransportSocketPool(
   1162                 HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
   1163   EXPECT_EQ(1, GetSocketPoolGroupCount(
   1164       session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
   1165   EXPECT_TRUE(waiter1.used_proxy_info().is_direct());
   1166 }
   1167 
   1168 // TODO(ricea): Re-enable once WebSocket-over-SPDY is implemented.
   1169 TEST_P(HttpStreamFactoryTest, DISABLED_RequestWebSocketSpdyHandshakeStream) {
   1170   SpdySessionDependencies session_deps(GetParam(),
   1171                                        ProxyService::CreateDirect());
   1172 
   1173   MockRead mock_read(SYNCHRONOUS, ERR_IO_PENDING);
   1174   StaticSocketDataProvider socket_data(&mock_read, 1, NULL, 0);
   1175   socket_data.set_connect_data(MockConnect(ASYNC, OK));
   1176   session_deps.socket_factory->AddSocketDataProvider(&socket_data);
   1177 
   1178   SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
   1179   ssl_socket_data.SetNextProto(GetParam());
   1180   session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
   1181 
   1182   HostPortPair host_port_pair("www.google.com", 80);
   1183   scoped_refptr<HttpNetworkSession>
   1184       session(SpdySessionDependencies::SpdyCreateSession(&session_deps));
   1185 
   1186   // Now request a stream.
   1187   HttpRequestInfo request_info;
   1188   request_info.method = "GET";
   1189   request_info.url = GURL("wss://www.google.com");
   1190   request_info.load_flags = 0;
   1191 
   1192   SSLConfig ssl_config;
   1193   StreamRequestWaiter waiter1;
   1194   WebSocketStreamCreateHelper create_helper;
   1195   scoped_ptr<HttpStreamRequest> request1(
   1196       session->http_stream_factory_for_websocket()
   1197           ->RequestWebSocketHandshakeStream(request_info,
   1198                                             DEFAULT_PRIORITY,
   1199                                             ssl_config,
   1200                                             ssl_config,
   1201                                             &waiter1,
   1202                                             &create_helper,
   1203                                             BoundNetLog()));
   1204   waiter1.WaitForStream();
   1205   EXPECT_TRUE(waiter1.stream_done());
   1206   ASSERT_TRUE(NULL != waiter1.websocket_stream());
   1207   EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy,
   1208             waiter1.websocket_stream()->type());
   1209   EXPECT_TRUE(NULL == waiter1.stream());
   1210 
   1211   StreamRequestWaiter waiter2;
   1212   scoped_ptr<HttpStreamRequest> request2(
   1213       session->http_stream_factory_for_websocket()
   1214           ->RequestWebSocketHandshakeStream(request_info,
   1215                                             DEFAULT_PRIORITY,
   1216                                             ssl_config,
   1217                                             ssl_config,
   1218                                             &waiter2,
   1219                                             &create_helper,
   1220                                             BoundNetLog()));
   1221   waiter2.WaitForStream();
   1222   EXPECT_TRUE(waiter2.stream_done());
   1223   ASSERT_TRUE(NULL != waiter2.websocket_stream());
   1224   EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy,
   1225             waiter2.websocket_stream()->type());
   1226   EXPECT_TRUE(NULL == waiter2.stream());
   1227   EXPECT_NE(waiter2.websocket_stream(), waiter1.websocket_stream());
   1228   EXPECT_EQ(static_cast<WebSocketSpdyHandshakeStream*>(
   1229                 waiter2.websocket_stream())->spdy_session(),
   1230             static_cast<WebSocketSpdyHandshakeStream*>(
   1231                 waiter1.websocket_stream())->spdy_session());
   1232 
   1233   EXPECT_EQ(0, GetSocketPoolGroupCount(
   1234       session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
   1235   EXPECT_EQ(0, GetSocketPoolGroupCount(
   1236       session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
   1237   EXPECT_EQ(1, GetSocketPoolGroupCount(
   1238       session->GetTransportSocketPool(
   1239           HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
   1240   EXPECT_EQ(1, GetSocketPoolGroupCount(
   1241       session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
   1242   EXPECT_TRUE(waiter1.used_proxy_info().is_direct());
   1243 }
   1244 
   1245 // TODO(ricea): Re-enable once WebSocket over SPDY is implemented.
   1246 TEST_P(HttpStreamFactoryTest, DISABLED_OrphanedWebSocketStream) {
   1247   SpdySessionDependencies session_deps(GetParam(),
   1248                                        ProxyService::CreateDirect());
   1249   session_deps.use_alternate_protocols = true;
   1250 
   1251   MockRead mock_read(ASYNC, OK);
   1252   DeterministicSocketData socket_data(&mock_read, 1, NULL, 0);
   1253   socket_data.set_connect_data(MockConnect(ASYNC, OK));
   1254   session_deps.deterministic_socket_factory->AddSocketDataProvider(
   1255       &socket_data);
   1256 
   1257   MockRead mock_read2(ASYNC, OK);
   1258   DeterministicSocketData socket_data2(&mock_read2, 1, NULL, 0);
   1259   socket_data2.set_connect_data(MockConnect(ASYNC, ERR_IO_PENDING));
   1260   session_deps.deterministic_socket_factory->AddSocketDataProvider(
   1261       &socket_data2);
   1262 
   1263   SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
   1264   ssl_socket_data.SetNextProto(GetParam());
   1265   session_deps.deterministic_socket_factory->AddSSLSocketDataProvider(
   1266       &ssl_socket_data);
   1267 
   1268   scoped_refptr<HttpNetworkSession>
   1269       session(SpdySessionDependencies::SpdyCreateSessionDeterministic(
   1270           &session_deps));
   1271 
   1272   // Now request a stream.
   1273   HttpRequestInfo request_info;
   1274   request_info.method = "GET";
   1275   request_info.url = GURL("ws://www.google.com:8888");
   1276   request_info.load_flags = 0;
   1277 
   1278   session->http_server_properties()->SetAlternateProtocol(
   1279       HostPortPair("www.google.com", 8888),
   1280       9999,
   1281       NPN_SPDY_3);
   1282 
   1283   SSLConfig ssl_config;
   1284   StreamRequestWaiter waiter;
   1285   WebSocketStreamCreateHelper create_helper;
   1286   scoped_ptr<HttpStreamRequest> request(
   1287       session->http_stream_factory_for_websocket()
   1288           ->RequestWebSocketHandshakeStream(request_info,
   1289                                             DEFAULT_PRIORITY,
   1290                                             ssl_config,
   1291                                             ssl_config,
   1292                                             &waiter,
   1293                                             &create_helper,
   1294                                             BoundNetLog()));
   1295   waiter.WaitForStream();
   1296   EXPECT_TRUE(waiter.stream_done());
   1297   EXPECT_TRUE(NULL == waiter.stream());
   1298   ASSERT_TRUE(NULL != waiter.websocket_stream());
   1299   EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy,
   1300             waiter.websocket_stream()->type());
   1301 
   1302   // Make sure that there was an alternative connection
   1303   // which consumes extra connections.
   1304   EXPECT_EQ(0, GetSocketPoolGroupCount(
   1305       session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
   1306   EXPECT_EQ(0, GetSocketPoolGroupCount(
   1307       session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
   1308   EXPECT_EQ(2, GetSocketPoolGroupCount(
   1309       session->GetTransportSocketPool(
   1310           HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
   1311   EXPECT_EQ(1, GetSocketPoolGroupCount(
   1312       session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
   1313   EXPECT_TRUE(waiter.used_proxy_info().is_direct());
   1314 
   1315   // Make sure there is no orphaned job. it is already canceled.
   1316   ASSERT_EQ(0u, static_cast<HttpStreamFactoryImpl*>(
   1317       session->http_stream_factory_for_websocket())->num_orphaned_jobs());
   1318 }
   1319 
   1320 }  // namespace
   1321 
   1322 }  // namespace net
   1323