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