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