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.
5 #include "net/http/http_stream_factory_impl.h"
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"
46 class MockWebSocketHandshakeStream
: public WebSocketHandshakeStreamBase
{
53 explicit MockWebSocketHandshakeStream(StreamType type
) : type_(type
) {}
55 virtual ~MockWebSocketHandshakeStream() {}
57 StreamType
type() const {
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
;
68 virtual int SendRequest(const HttpRequestHeaders
& request_headers
,
69 HttpResponseInfo
* response
,
70 const CompletionCallback
& callback
) OVERRIDE
{
71 return ERR_IO_PENDING
;
73 virtual int ReadResponseHeaders(const CompletionCallback
& callback
) OVERRIDE
{
74 return ERR_IO_PENDING
;
76 virtual int ReadResponseBody(IOBuffer
* buf
,
78 const CompletionCallback
& callback
) OVERRIDE
{
79 return ERR_IO_PENDING
;
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
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
{}
99 virtual scoped_ptr
<WebSocketStream
> Upgrade() OVERRIDE
{
100 return scoped_ptr
<WebSocketStream
>();
104 const StreamType type_
;
107 // HttpStreamFactoryImpl subclass that can wait until a preconnect is complete.
108 class MockHttpStreamFactoryImplForPreconnect
: public HttpStreamFactoryImpl
{
110 MockHttpStreamFactoryImplForPreconnect(HttpNetworkSession
* session
,
112 : HttpStreamFactoryImpl(session
, for_websockets
),
113 preconnect_done_(false),
114 waiting_for_preconnect_(false) {}
117 void WaitForPreconnects() {
118 while (!preconnect_done_
) {
119 waiting_for_preconnect_
= true;
120 base::MessageLoop::current()->Run();
121 waiting_for_preconnect_
= false;
126 // HttpStreamFactoryImpl methods.
127 virtual void OnPreconnectsCompleteInternal() OVERRIDE
{
128 preconnect_done_
= true;
129 if (waiting_for_preconnect_
)
130 base::MessageLoop::current()->Quit();
133 bool preconnect_done_
;
134 bool waiting_for_preconnect_
;
137 class StreamRequestWaiter
: public HttpStreamRequest::Delegate
{
139 StreamRequestWaiter()
140 : waiting_for_stream_(false),
141 stream_done_(false) {}
143 // HttpStreamRequest::Delegate
145 virtual void OnStreamReady(
146 const SSLConfig
& used_ssl_config
,
147 const ProxyInfo
& used_proxy_info
,
148 HttpStreamBase
* stream
) OVERRIDE
{
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
;
157 virtual void OnWebSocketHandshakeStreamReady(
158 const SSLConfig
& used_ssl_config
,
159 const ProxyInfo
& used_proxy_info
,
160 WebSocketHandshakeStreamBase
* stream
) OVERRIDE
{
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
;
169 virtual void OnStreamFailed(
171 const SSLConfig
& used_ssl_config
) OVERRIDE
{}
173 virtual void OnCertificateError(
175 const SSLConfig
& used_ssl_config
,
176 const SSLInfo
& ssl_info
) OVERRIDE
{}
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
{}
183 virtual void OnNeedsClientAuth(const SSLConfig
& used_ssl_config
,
184 SSLCertRequestInfo
* cert_info
) OVERRIDE
{}
186 virtual void OnHttpsProxyTunnelResponse(const HttpResponseInfo
& response_info
,
187 const SSLConfig
& used_ssl_config
,
188 const ProxyInfo
& used_proxy_info
,
189 HttpStreamBase
* stream
) OVERRIDE
{}
191 void WaitForStream() {
192 while (!stream_done_
) {
193 waiting_for_stream_
= true;
194 base::MessageLoop::current()->Run();
195 waiting_for_stream_
= false;
199 const SSLConfig
& used_ssl_config() const {
200 return used_ssl_config_
;
203 const ProxyInfo
& used_proxy_info() const {
204 return used_proxy_info_
;
207 HttpStreamBase
* stream() {
208 return stream_
.get();
211 MockWebSocketHandshakeStream
* websocket_stream() {
212 return static_cast<MockWebSocketHandshakeStream
*>(websocket_stream_
.get());
215 bool stream_done() const { return stream_done_
; }
218 bool waiting_for_stream_
;
220 scoped_ptr
<HttpStreamBase
> stream_
;
221 scoped_ptr
<WebSocketHandshakeStreamBase
> websocket_stream_
;
222 SSLConfig used_ssl_config_
;
223 ProxyInfo used_proxy_info_
;
225 DISALLOW_COPY_AND_ASSIGN(StreamRequestWaiter
);
228 class WebSocketSpdyHandshakeStream
: public MockWebSocketHandshakeStream
{
230 explicit WebSocketSpdyHandshakeStream(
231 const base::WeakPtr
<SpdySession
>& spdy_session
)
232 : MockWebSocketHandshakeStream(kStreamTypeSpdy
),
233 spdy_session_(spdy_session
) {}
235 virtual ~WebSocketSpdyHandshakeStream() {}
237 SpdySession
* spdy_session() { return spdy_session_
.get(); }
240 base::WeakPtr
<SpdySession
> spdy_session_
;
243 class WebSocketBasicHandshakeStream
: public MockWebSocketHandshakeStream
{
245 explicit WebSocketBasicHandshakeStream(
246 scoped_ptr
<ClientSocketHandle
> connection
)
247 : MockWebSocketHandshakeStream(kStreamTypeBasic
),
248 connection_(connection
.Pass()) {}
250 virtual ~WebSocketBasicHandshakeStream() {
251 connection_
->socket()->Disconnect();
254 ClientSocketHandle
* connection() { return connection_
.get(); }
257 scoped_ptr
<ClientSocketHandle
> connection_
;
260 class WebSocketStreamCreateHelper
261 : public WebSocketHandshakeStreamBase::CreateHelper
{
263 virtual ~WebSocketStreamCreateHelper() {}
265 virtual WebSocketHandshakeStreamBase
* CreateBasicStream(
266 scoped_ptr
<ClientSocketHandle
> connection
,
267 bool using_proxy
) OVERRIDE
{
268 return new WebSocketBasicHandshakeStream(connection
.Pass());
271 virtual WebSocketHandshakeStreamBase
* CreateSpdyStream(
272 const base::WeakPtr
<SpdySession
>& spdy_session
,
273 bool use_relative_url
) OVERRIDE
{
274 return new WebSocketSpdyHandshakeStream(spdy_session
);
283 TestCase kTests
[] = {
290 void PreconnectHelperForURL(int num_streams
,
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
);
300 HttpRequestInfo request
;
301 request
.method
= "GET";
303 request
.load_flags
= 0;
305 session
->http_stream_factory()->PreconnectStreams(
306 num_streams
, request
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
);
307 mock_factory
->WaitForPreconnects();
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
);
317 template<typename ParentPool
>
318 class CapturePreconnectsSocketPool
: public ParentPool
{
320 CapturePreconnectsSocketPool(HostResolver
* host_resolver
,
321 CertVerifier
* cert_verifier
);
323 int last_num_streams() const {
324 return last_num_streams_
;
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
{
334 return ERR_UNEXPECTED
;
337 virtual void RequestSockets(const std::string
& group_name
,
338 const void* socket_params
,
340 const BoundNetLog
& net_log
) OVERRIDE
{
341 last_num_streams_
= num_sockets
;
344 virtual void CancelRequest(const std::string
& group_name
,
345 ClientSocketHandle
* handle
) OVERRIDE
{
348 virtual void ReleaseSocket(const std::string
& group_name
,
349 scoped_ptr
<StreamSocket
> socket
,
353 virtual void CloseIdleSockets() OVERRIDE
{
356 virtual int IdleSocketCount() const OVERRIDE
{
360 virtual int IdleSocketCountInGroup(
361 const std::string
& group_name
) const OVERRIDE
{
365 virtual LoadState
GetLoadState(
366 const std::string
& group_name
,
367 const ClientSocketHandle
* handle
) const OVERRIDE
{
369 return LOAD_STATE_IDLE
;
371 virtual base::TimeDelta
ConnectionTimeout() const OVERRIDE
{
372 return base::TimeDelta();
376 int last_num_streams_
;
379 typedef CapturePreconnectsSocketPool
<TransportClientSocketPool
>
380 CapturePreconnectsTransportSocketPool
;
381 typedef CapturePreconnectsSocketPool
<HttpProxyClientSocketPool
>
382 CapturePreconnectsHttpProxySocketPool
;
383 typedef CapturePreconnectsSocketPool
<SOCKSClientSocketPool
>
384 CapturePreconnectsSOCKSSocketPool
;
385 typedef CapturePreconnectsSocketPool
<SSLClientSocketPool
>
386 CapturePreconnectsSSLSocketPool
;
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) {}
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) {}
401 CapturePreconnectsSSLSocketPool::CapturePreconnectsSocketPool(
402 HostResolver
* host_resolver
,
403 CertVerifier
* cert_verifier
)
404 : SSLClientSocketPool(0,
406 NULL
, // ssl_histograms
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
417 NULL
, // ssl_config_service
418 false, // enable_ssl_connect_job_waiting
420 last_num_streams_(-1) {
423 class HttpStreamFactoryTest
: public ::testing::Test
,
424 public ::testing::WithParamInterface
<NextProto
> {
427 INSTANTIATE_TEST_CASE_P(
429 HttpStreamFactoryTest
,
430 testing::Values(kProtoDeprecatedSPDY2
,
431 kProtoSPDY3
, kProtoSPDY31
, kProtoSPDY4
));
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());
456 EXPECT_EQ(kTests
[i
].num_streams
, ssl_conn_pool
->last_num_streams());
458 EXPECT_EQ(kTests
[i
].num_streams
, transport_conn_pool
->last_num_streams());
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());
486 EXPECT_EQ(kTests
[i
].num_streams
, ssl_conn_pool
->last_num_streams());
488 EXPECT_EQ(kTests
[i
].num_streams
, http_proxy_pool
->last_num_streams());
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());
516 EXPECT_EQ(kTests
[i
].num_streams
, ssl_conn_pool
->last_num_streams());
518 EXPECT_EQ(kTests
[i
].num_streams
, socks_proxy_pool
->last_num_streams());
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
);
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
));
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.
554 EXPECT_EQ(-1, ssl_conn_pool
->last_num_streams());
556 EXPECT_EQ(kTests
[i
].num_streams
,
557 transport_conn_pool
->last_num_streams());
561 // Verify that preconnects to unsafe ports are cancelled before they reach
563 TEST_P(HttpStreamFactoryTest
, PreconnectUnsafePort
) {
564 ASSERT_FALSE(IsPortAllowedByDefault(7));
565 ASSERT_FALSE(IsPortAllowedByOverride(7));
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
>());
582 PreconnectHelperForURL(1, GURL("http://www.google.com:7"), session
.get());
584 EXPECT_EQ(-1, transport_conn_pool
->last_num_streams());
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
));
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
);
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
);
602 scoped_refptr
<HttpNetworkSession
> session(
603 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
605 // Now request a stream. It should succeed using the second proxy in the
607 HttpRequestInfo request_info
;
608 request_info
.method
= "GET";
609 request_info
.url
= GURL("http://www.google.com");
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();
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());
627 TEST_P(HttpStreamFactoryTest
, PrivacyModeDisablesChannelId
) {
628 SpdySessionDependencies
session_deps(
629 GetParam(), ProxyService::CreateDirect());
631 StaticSocketDataProvider socket_data
;
632 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
633 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
635 SSLSocketDataProvider
ssl(ASYNC
, OK
);
636 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl
);
638 scoped_refptr
<HttpNetworkSession
> session(
639 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
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
);
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
;
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();
660 // The stream shouldn't come from spdy as we are using different privacy mode
661 EXPECT_FALSE(request
->using_spdy());
663 SSLConfig used_ssl_config
= waiter
.used_ssl_config();
664 EXPECT_EQ(used_ssl_config
.channel_id_enabled
, ssl_config
.channel_id_enabled
);
668 // Return count of distinct groups in given socket pool.
669 int GetSocketPoolGroupCount(ClientSocketPool
* pool
) {
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());
681 TEST_P(HttpStreamFactoryTest
, PrivacyModeUsesDifferentSocketPoolGroup
) {
682 SpdySessionDependencies
session_deps(
683 GetParam(), ProxyService::CreateDirect());
685 StaticSocketDataProvider socket_data
;
686 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
687 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
689 SSLSocketDataProvider
ssl(ASYNC
, OK
);
690 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl
);
692 scoped_refptr
<HttpNetworkSession
> session(
693 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
694 SSLClientSocketPool
* ssl_pool
= session
->GetSSLSocketPool(
695 HttpNetworkSession::NORMAL_SOCKET_POOL
);
697 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool
), 0);
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
;
705 SSLConfig ssl_config
;
706 StreamRequestWaiter waiter
;
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();
714 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool
), 1);
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();
722 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool
), 1);
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();
731 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool
), 2);
734 TEST_P(HttpStreamFactoryTest
, GetLoadState
) {
735 SpdySessionDependencies
session_deps(
736 GetParam(), ProxyService::CreateDirect());
738 StaticSocketDataProvider socket_data
;
739 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
740 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
742 scoped_refptr
<HttpNetworkSession
> session(
743 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
745 HttpRequestInfo request_info
;
746 request_info
.method
= "GET";
747 request_info
.url
= GURL("http://www.google.com");
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()));
756 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST
, request
->GetLoadState());
758 waiter
.WaitForStream();
761 TEST_P(HttpStreamFactoryTest
, RequestHttpStream
) {
762 SpdySessionDependencies
session_deps(
763 GetParam(), ProxyService::CreateDirect());
765 StaticSocketDataProvider socket_data
;
766 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
767 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
769 scoped_refptr
<HttpNetworkSession
> session(
770 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
772 // Now request a stream. It should succeed using the second proxy in the
774 HttpRequestInfo request_info
;
775 request_info
.method
= "GET";
776 request_info
.url
= GURL("http://www.google.com");
777 request_info
.load_flags
= 0;
779 SSLConfig ssl_config
;
780 StreamRequestWaiter waiter
;
781 scoped_ptr
<HttpStreamRequest
> request(
782 session
->http_stream_factory()->RequestStream(
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());
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());
807 TEST_P(HttpStreamFactoryTest
, RequestHttpStreamOverSSL
) {
808 SpdySessionDependencies
session_deps(
809 GetParam(), ProxyService::CreateDirect());
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
);
816 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
817 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl_socket_data
);
819 scoped_refptr
<HttpNetworkSession
> session(
820 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
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;
828 SSLConfig ssl_config
;
829 StreamRequestWaiter waiter
;
830 scoped_ptr
<HttpStreamRequest
> request(
831 session
->http_stream_factory()->RequestStream(
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());
855 TEST_P(HttpStreamFactoryTest
, RequestHttpStreamOverProxy
) {
856 SpdySessionDependencies
session_deps(
857 GetParam(), ProxyService::CreateFixed("myproxy:8888"));
859 StaticSocketDataProvider socket_data
;
860 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
861 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
863 scoped_refptr
<HttpNetworkSession
> session(
864 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
866 // Now request a stream. It should succeed using the second proxy in the
868 HttpRequestInfo request_info
;
869 request_info
.method
= "GET";
870 request_info
.url
= GURL("http://www.google.com");
871 request_info
.load_flags
= 0;
873 SSLConfig ssl_config
;
874 StreamRequestWaiter waiter
;
875 scoped_ptr
<HttpStreamRequest
> request(
876 session
->http_stream_factory()->RequestStream(
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());
907 TEST_P(HttpStreamFactoryTest
, RequestWebSocketBasicHandshakeStream
) {
908 SpdySessionDependencies
session_deps(
909 GetParam(), ProxyService::CreateDirect());
911 StaticSocketDataProvider socket_data
;
912 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
913 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
915 scoped_refptr
<HttpNetworkSession
> session(
916 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
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;
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
,
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());
951 TEST_P(HttpStreamFactoryTest
, RequestWebSocketBasicHandshakeStreamOverSSL
) {
952 SpdySessionDependencies
session_deps(
953 GetParam(), ProxyService::CreateDirect());
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
);
960 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
961 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl_socket_data
);
963 scoped_refptr
<HttpNetworkSession
> session(
964 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
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;
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
,
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());
999 TEST_P(HttpStreamFactoryTest
, RequestWebSocketBasicHandshakeStreamOverProxy
) {
1000 SpdySessionDependencies
session_deps(
1001 GetParam(), ProxyService::CreateFixed("myproxy:8888"));
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
);
1008 scoped_refptr
<HttpNetworkSession
> session(
1009 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
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;
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
,
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());
1055 TEST_P(HttpStreamFactoryTest
, RequestSpdyHttpStream
) {
1056 SpdySessionDependencies
session_deps(GetParam(),
1057 ProxyService::CreateDirect());
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(
1065 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
1066 ssl_socket_data
.SetNextProto(GetParam());
1067 session_deps
.deterministic_socket_factory
->AddSSLSocketDataProvider(
1070 HostPortPair
host_port_pair("www.google.com", 443);
1071 scoped_refptr
<HttpNetworkSession
>
1072 session(SpdySessionDependencies::SpdyCreateSessionDeterministic(
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;
1081 SSLConfig ssl_config
;
1082 StreamRequestWaiter waiter
;
1083 scoped_ptr
<HttpStreamRequest
> request(
1084 session
->http_stream_factory()->RequestStream(
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());
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
1111 TEST_P(HttpStreamFactoryTest
, RequestWebSocketSpdyHandshakeStreamButGetSSL
) {
1112 SpdySessionDependencies
session_deps(GetParam(),
1113 ProxyService::CreateDirect());
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
);
1120 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
1121 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl_socket_data
);
1123 HostPortPair
host_port_pair("www.google.com", 80);
1124 scoped_refptr
<HttpNetworkSession
>
1125 session(SpdySessionDependencies::SpdyCreateSession(&session_deps
));
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;
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
,
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());
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());
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());
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
);
1171 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
1172 ssl_socket_data
.SetNextProto(GetParam());
1173 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl_socket_data
);
1175 HostPortPair
host_port_pair("www.google.com", 80);
1176 scoped_refptr
<HttpNetworkSession
>
1177 session(SpdySessionDependencies::SpdyCreateSession(&session_deps
));
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;
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
,
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());
1204 StreamRequestWaiter waiter2
;
1205 scoped_ptr
<HttpStreamRequest
> request2(
1206 session
->http_stream_factory_for_websocket()
1207 ->RequestWebSocketHandshakeStream(request_info
,
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());
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());
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;
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(
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(
1256 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
1257 ssl_socket_data
.SetNextProto(GetParam());
1258 session_deps
.deterministic_socket_factory
->AddSSLSocketDataProvider(
1261 scoped_refptr
<HttpNetworkSession
>
1262 session(SpdySessionDependencies::SpdyCreateSessionDeterministic(
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;
1271 session
->http_server_properties()->SetAlternateProtocol(
1272 HostPortPair("www.google.com", 8888),
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
,
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());
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());
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());