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