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 UseAlternateProtocolsScopedSetter
{
48 explicit UseAlternateProtocolsScopedSetter(bool use_alternate_protocols
)
49 : use_alternate_protocols_(HttpStreamFactory::use_alternate_protocols()) {
50 HttpStreamFactory::set_use_alternate_protocols(use_alternate_protocols
);
52 ~UseAlternateProtocolsScopedSetter() {
53 HttpStreamFactory::set_use_alternate_protocols(use_alternate_protocols_
);
57 bool use_alternate_protocols_
;
60 class MockWebSocketHandshakeStream
: public WebSocketHandshakeStreamBase
{
67 explicit MockWebSocketHandshakeStream(StreamType type
) : type_(type
) {}
69 virtual ~MockWebSocketHandshakeStream() {}
71 StreamType
type() const {
75 // HttpStreamBase methods
76 virtual int InitializeStream(const HttpRequestInfo
* request_info
,
77 RequestPriority priority
,
78 const BoundNetLog
& net_log
,
79 const CompletionCallback
& callback
) OVERRIDE
{
80 return ERR_IO_PENDING
;
82 virtual int SendRequest(const HttpRequestHeaders
& request_headers
,
83 HttpResponseInfo
* response
,
84 const CompletionCallback
& callback
) OVERRIDE
{
85 return ERR_IO_PENDING
;
87 virtual int ReadResponseHeaders(const CompletionCallback
& callback
) OVERRIDE
{
88 return ERR_IO_PENDING
;
90 virtual const HttpResponseInfo
* GetResponseInfo() const OVERRIDE
{
93 virtual int ReadResponseBody(IOBuffer
* buf
,
95 const CompletionCallback
& callback
) OVERRIDE
{
96 return ERR_IO_PENDING
;
98 virtual void Close(bool not_reusable
) OVERRIDE
{}
99 virtual bool IsResponseBodyComplete() const OVERRIDE
{ return false; }
100 virtual bool CanFindEndOfResponse() const OVERRIDE
{ return false; }
101 virtual bool IsConnectionReused() const OVERRIDE
{ return false; }
102 virtual void SetConnectionReused() OVERRIDE
{}
103 virtual bool IsConnectionReusable() const OVERRIDE
{ return false; }
104 virtual int64
GetTotalReceivedBytes() const OVERRIDE
{ return 0; }
105 virtual bool GetLoadTimingInfo(LoadTimingInfo
* load_timing_info
) const
109 virtual void GetSSLInfo(SSLInfo
* ssl_info
) OVERRIDE
{}
110 virtual void GetSSLCertRequestInfo(
111 SSLCertRequestInfo
* cert_request_info
) OVERRIDE
{}
112 virtual bool IsSpdyHttpStream() const OVERRIDE
{ return false; }
113 virtual void Drain(HttpNetworkSession
* session
) OVERRIDE
{}
114 virtual void SetPriority(RequestPriority priority
) OVERRIDE
{}
116 virtual scoped_ptr
<WebSocketStream
> Upgrade() OVERRIDE
{
117 return scoped_ptr
<WebSocketStream
>();
120 virtual std::string
GetFailureMessage() const OVERRIDE
{
121 return std::string();
125 const StreamType type_
;
128 // HttpStreamFactoryImpl subclass that can wait until a preconnect is complete.
129 class MockHttpStreamFactoryImplForPreconnect
: public HttpStreamFactoryImpl
{
131 MockHttpStreamFactoryImplForPreconnect(HttpNetworkSession
* session
,
133 : HttpStreamFactoryImpl(session
, for_websockets
),
134 preconnect_done_(false),
135 waiting_for_preconnect_(false) {}
138 void WaitForPreconnects() {
139 while (!preconnect_done_
) {
140 waiting_for_preconnect_
= true;
141 base::MessageLoop::current()->Run();
142 waiting_for_preconnect_
= false;
147 // HttpStreamFactoryImpl methods.
148 virtual void OnPreconnectsCompleteInternal() OVERRIDE
{
149 preconnect_done_
= true;
150 if (waiting_for_preconnect_
)
151 base::MessageLoop::current()->Quit();
154 bool preconnect_done_
;
155 bool waiting_for_preconnect_
;
158 class StreamRequestWaiter
: public HttpStreamRequest::Delegate
{
160 StreamRequestWaiter()
161 : waiting_for_stream_(false),
162 stream_done_(false) {}
164 // HttpStreamRequest::Delegate
166 virtual void OnStreamReady(
167 const SSLConfig
& used_ssl_config
,
168 const ProxyInfo
& used_proxy_info
,
169 HttpStreamBase
* stream
) OVERRIDE
{
171 if (waiting_for_stream_
)
172 base::MessageLoop::current()->Quit();
173 stream_
.reset(stream
);
174 used_ssl_config_
= used_ssl_config
;
175 used_proxy_info_
= used_proxy_info
;
178 virtual void OnWebSocketHandshakeStreamReady(
179 const SSLConfig
& used_ssl_config
,
180 const ProxyInfo
& used_proxy_info
,
181 WebSocketHandshakeStreamBase
* stream
) OVERRIDE
{
183 if (waiting_for_stream_
)
184 base::MessageLoop::current()->Quit();
185 websocket_stream_
.reset(stream
);
186 used_ssl_config_
= used_ssl_config
;
187 used_proxy_info_
= used_proxy_info
;
190 virtual void OnStreamFailed(
192 const SSLConfig
& used_ssl_config
) OVERRIDE
{}
194 virtual void OnCertificateError(
196 const SSLConfig
& used_ssl_config
,
197 const SSLInfo
& ssl_info
) OVERRIDE
{}
199 virtual void OnNeedsProxyAuth(const HttpResponseInfo
& proxy_response
,
200 const SSLConfig
& used_ssl_config
,
201 const ProxyInfo
& used_proxy_info
,
202 HttpAuthController
* auth_controller
) OVERRIDE
{}
204 virtual void OnNeedsClientAuth(const SSLConfig
& used_ssl_config
,
205 SSLCertRequestInfo
* cert_info
) OVERRIDE
{}
207 virtual void OnHttpsProxyTunnelResponse(const HttpResponseInfo
& response_info
,
208 const SSLConfig
& used_ssl_config
,
209 const ProxyInfo
& used_proxy_info
,
210 HttpStreamBase
* stream
) OVERRIDE
{}
212 void WaitForStream() {
213 while (!stream_done_
) {
214 waiting_for_stream_
= true;
215 base::MessageLoop::current()->Run();
216 waiting_for_stream_
= false;
220 const SSLConfig
& used_ssl_config() const {
221 return used_ssl_config_
;
224 const ProxyInfo
& used_proxy_info() const {
225 return used_proxy_info_
;
228 HttpStreamBase
* stream() {
229 return stream_
.get();
232 MockWebSocketHandshakeStream
* websocket_stream() {
233 return static_cast<MockWebSocketHandshakeStream
*>(websocket_stream_
.get());
236 bool stream_done() const { return stream_done_
; }
239 bool waiting_for_stream_
;
241 scoped_ptr
<HttpStreamBase
> stream_
;
242 scoped_ptr
<WebSocketHandshakeStreamBase
> websocket_stream_
;
243 SSLConfig used_ssl_config_
;
244 ProxyInfo used_proxy_info_
;
246 DISALLOW_COPY_AND_ASSIGN(StreamRequestWaiter
);
249 class WebSocketSpdyHandshakeStream
: public MockWebSocketHandshakeStream
{
251 explicit WebSocketSpdyHandshakeStream(
252 const base::WeakPtr
<SpdySession
>& spdy_session
)
253 : MockWebSocketHandshakeStream(kStreamTypeSpdy
),
254 spdy_session_(spdy_session
) {}
256 virtual ~WebSocketSpdyHandshakeStream() {}
258 SpdySession
* spdy_session() { return spdy_session_
.get(); }
261 base::WeakPtr
<SpdySession
> spdy_session_
;
264 class WebSocketBasicHandshakeStream
: public MockWebSocketHandshakeStream
{
266 explicit WebSocketBasicHandshakeStream(
267 scoped_ptr
<ClientSocketHandle
> connection
)
268 : MockWebSocketHandshakeStream(kStreamTypeBasic
),
269 connection_(connection
.Pass()) {}
271 virtual ~WebSocketBasicHandshakeStream() {
272 connection_
->socket()->Disconnect();
275 ClientSocketHandle
* connection() { return connection_
.get(); }
278 scoped_ptr
<ClientSocketHandle
> connection_
;
281 class WebSocketStreamCreateHelper
282 : public WebSocketHandshakeStreamBase::CreateHelper
{
284 virtual ~WebSocketStreamCreateHelper() {}
286 virtual WebSocketHandshakeStreamBase
* CreateBasicStream(
287 scoped_ptr
<ClientSocketHandle
> connection
,
288 bool using_proxy
) OVERRIDE
{
289 return new WebSocketBasicHandshakeStream(connection
.Pass());
292 virtual WebSocketHandshakeStreamBase
* CreateSpdyStream(
293 const base::WeakPtr
<SpdySession
>& spdy_session
,
294 bool use_relative_url
) OVERRIDE
{
295 return new WebSocketSpdyHandshakeStream(spdy_session
);
304 TestCase kTests
[] = {
311 void PreconnectHelperForURL(int num_streams
,
313 HttpNetworkSession
* session
) {
314 HttpNetworkSessionPeer
peer(session
);
315 MockHttpStreamFactoryImplForPreconnect
* mock_factory
=
316 new MockHttpStreamFactoryImplForPreconnect(session
, false);
317 peer
.SetHttpStreamFactory(scoped_ptr
<HttpStreamFactory
>(mock_factory
));
318 SSLConfig ssl_config
;
319 session
->ssl_config_service()->GetSSLConfig(&ssl_config
);
321 HttpRequestInfo request
;
322 request
.method
= "GET";
324 request
.load_flags
= 0;
326 session
->http_stream_factory()->PreconnectStreams(
327 num_streams
, request
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
);
328 mock_factory
->WaitForPreconnects();
331 void PreconnectHelper(const TestCase
& test
,
332 HttpNetworkSession
* session
) {
333 GURL url
= test
.ssl
? GURL("https://www.google.com") :
334 GURL("http://www.google.com");
335 PreconnectHelperForURL(test
.num_streams
, url
, session
);
338 template<typename ParentPool
>
339 class CapturePreconnectsSocketPool
: public ParentPool
{
341 CapturePreconnectsSocketPool(HostResolver
* host_resolver
,
342 CertVerifier
* cert_verifier
);
344 int last_num_streams() const {
345 return last_num_streams_
;
348 virtual int RequestSocket(const std::string
& group_name
,
349 const void* socket_params
,
350 RequestPriority priority
,
351 ClientSocketHandle
* handle
,
352 const CompletionCallback
& callback
,
353 const BoundNetLog
& net_log
) OVERRIDE
{
355 return ERR_UNEXPECTED
;
358 virtual void RequestSockets(const std::string
& group_name
,
359 const void* socket_params
,
361 const BoundNetLog
& net_log
) OVERRIDE
{
362 last_num_streams_
= num_sockets
;
365 virtual void CancelRequest(const std::string
& group_name
,
366 ClientSocketHandle
* handle
) OVERRIDE
{
369 virtual void ReleaseSocket(const std::string
& group_name
,
370 scoped_ptr
<StreamSocket
> socket
,
374 virtual void CloseIdleSockets() OVERRIDE
{
377 virtual int IdleSocketCount() const OVERRIDE
{
381 virtual int IdleSocketCountInGroup(
382 const std::string
& group_name
) const OVERRIDE
{
386 virtual LoadState
GetLoadState(
387 const std::string
& group_name
,
388 const ClientSocketHandle
* handle
) const OVERRIDE
{
390 return LOAD_STATE_IDLE
;
392 virtual base::TimeDelta
ConnectionTimeout() const OVERRIDE
{
393 return base::TimeDelta();
397 int last_num_streams_
;
400 typedef CapturePreconnectsSocketPool
<TransportClientSocketPool
>
401 CapturePreconnectsTransportSocketPool
;
402 typedef CapturePreconnectsSocketPool
<HttpProxyClientSocketPool
>
403 CapturePreconnectsHttpProxySocketPool
;
404 typedef CapturePreconnectsSocketPool
<SOCKSClientSocketPool
>
405 CapturePreconnectsSOCKSSocketPool
;
406 typedef CapturePreconnectsSocketPool
<SSLClientSocketPool
>
407 CapturePreconnectsSSLSocketPool
;
409 template<typename ParentPool
>
410 CapturePreconnectsSocketPool
<ParentPool
>::CapturePreconnectsSocketPool(
411 HostResolver
* host_resolver
, CertVerifier
* /* cert_verifier */)
412 : ParentPool(0, 0, NULL
, host_resolver
, NULL
, NULL
),
413 last_num_streams_(-1) {}
416 CapturePreconnectsHttpProxySocketPool::CapturePreconnectsSocketPool(
417 HostResolver
* host_resolver
, CertVerifier
* /* cert_verifier */)
418 : HttpProxyClientSocketPool(0, 0, NULL
, host_resolver
, NULL
, NULL
, NULL
),
419 last_num_streams_(-1) {}
422 CapturePreconnectsSSLSocketPool::CapturePreconnectsSocketPool(
423 HostResolver
* host_resolver
,
424 CertVerifier
* cert_verifier
)
425 : SSLClientSocketPool(0,
427 NULL
, // ssl_histograms
430 NULL
, // server_bound_cert_store
431 NULL
, // transport_security_state
432 NULL
, // cert_transparency_verifier
433 std::string(), // ssl_session_cache_shard
434 NULL
, // deterministic_socket_factory
435 NULL
, // transport_socket_pool
438 NULL
, // ssl_config_service
440 last_num_streams_(-1) {}
442 class HttpStreamFactoryTest
: public ::testing::Test
,
443 public ::testing::WithParamInterface
<NextProto
> {
446 INSTANTIATE_TEST_CASE_P(
448 HttpStreamFactoryTest
,
449 testing::Values(kProtoDeprecatedSPDY2
,
450 kProtoSPDY3
, kProtoSPDY31
, kProtoSPDY4a2
,
451 kProtoHTTP2Draft04
));
453 TEST_P(HttpStreamFactoryTest
, PreconnectDirect
) {
454 for (size_t i
= 0; i
< arraysize(kTests
); ++i
) {
455 SpdySessionDependencies
session_deps(
456 GetParam(), ProxyService::CreateDirect());
457 scoped_refptr
<HttpNetworkSession
> session(
458 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
459 HttpNetworkSessionPeer
peer(session
);
460 CapturePreconnectsTransportSocketPool
* transport_conn_pool
=
461 new CapturePreconnectsTransportSocketPool(
462 session_deps
.host_resolver
.get(),
463 session_deps
.cert_verifier
.get());
464 CapturePreconnectsSSLSocketPool
* ssl_conn_pool
=
465 new CapturePreconnectsSSLSocketPool(
466 session_deps
.host_resolver
.get(),
467 session_deps
.cert_verifier
.get());
468 scoped_ptr
<MockClientSocketPoolManager
> mock_pool_manager(
469 new MockClientSocketPoolManager
);
470 mock_pool_manager
->SetTransportSocketPool(transport_conn_pool
);
471 mock_pool_manager
->SetSSLSocketPool(ssl_conn_pool
);
472 peer
.SetClientSocketPoolManager(
473 mock_pool_manager
.PassAs
<ClientSocketPoolManager
>());
474 PreconnectHelper(kTests
[i
], session
.get());
476 EXPECT_EQ(kTests
[i
].num_streams
, ssl_conn_pool
->last_num_streams());
478 EXPECT_EQ(kTests
[i
].num_streams
, transport_conn_pool
->last_num_streams());
482 TEST_P(HttpStreamFactoryTest
, PreconnectHttpProxy
) {
483 for (size_t i
= 0; i
< arraysize(kTests
); ++i
) {
484 SpdySessionDependencies
session_deps(
485 GetParam(), ProxyService::CreateFixed("http_proxy"));
486 scoped_refptr
<HttpNetworkSession
> session(
487 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
488 HttpNetworkSessionPeer
peer(session
);
489 HostPortPair
proxy_host("http_proxy", 80);
490 CapturePreconnectsHttpProxySocketPool
* http_proxy_pool
=
491 new CapturePreconnectsHttpProxySocketPool(
492 session_deps
.host_resolver
.get(),
493 session_deps
.cert_verifier
.get());
494 CapturePreconnectsSSLSocketPool
* ssl_conn_pool
=
495 new CapturePreconnectsSSLSocketPool(
496 session_deps
.host_resolver
.get(),
497 session_deps
.cert_verifier
.get());
498 scoped_ptr
<MockClientSocketPoolManager
> mock_pool_manager(
499 new MockClientSocketPoolManager
);
500 mock_pool_manager
->SetSocketPoolForHTTPProxy(proxy_host
, http_proxy_pool
);
501 mock_pool_manager
->SetSocketPoolForSSLWithProxy(proxy_host
, ssl_conn_pool
);
502 peer
.SetClientSocketPoolManager(
503 mock_pool_manager
.PassAs
<ClientSocketPoolManager
>());
504 PreconnectHelper(kTests
[i
], session
.get());
506 EXPECT_EQ(kTests
[i
].num_streams
, ssl_conn_pool
->last_num_streams());
508 EXPECT_EQ(kTests
[i
].num_streams
, http_proxy_pool
->last_num_streams());
512 TEST_P(HttpStreamFactoryTest
, PreconnectSocksProxy
) {
513 for (size_t i
= 0; i
< arraysize(kTests
); ++i
) {
514 SpdySessionDependencies
session_deps(
515 GetParam(), ProxyService::CreateFixed("socks4://socks_proxy:1080"));
516 scoped_refptr
<HttpNetworkSession
> session(
517 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
518 HttpNetworkSessionPeer
peer(session
);
519 HostPortPair
proxy_host("socks_proxy", 1080);
520 CapturePreconnectsSOCKSSocketPool
* socks_proxy_pool
=
521 new CapturePreconnectsSOCKSSocketPool(
522 session_deps
.host_resolver
.get(),
523 session_deps
.cert_verifier
.get());
524 CapturePreconnectsSSLSocketPool
* ssl_conn_pool
=
525 new CapturePreconnectsSSLSocketPool(
526 session_deps
.host_resolver
.get(),
527 session_deps
.cert_verifier
.get());
528 scoped_ptr
<MockClientSocketPoolManager
> mock_pool_manager(
529 new MockClientSocketPoolManager
);
530 mock_pool_manager
->SetSocketPoolForSOCKSProxy(proxy_host
, socks_proxy_pool
);
531 mock_pool_manager
->SetSocketPoolForSSLWithProxy(proxy_host
, ssl_conn_pool
);
532 peer
.SetClientSocketPoolManager(
533 mock_pool_manager
.PassAs
<ClientSocketPoolManager
>());
534 PreconnectHelper(kTests
[i
], session
.get());
536 EXPECT_EQ(kTests
[i
].num_streams
, ssl_conn_pool
->last_num_streams());
538 EXPECT_EQ(kTests
[i
].num_streams
, socks_proxy_pool
->last_num_streams());
542 TEST_P(HttpStreamFactoryTest
, PreconnectDirectWithExistingSpdySession
) {
543 for (size_t i
= 0; i
< arraysize(kTests
); ++i
) {
544 SpdySessionDependencies
session_deps(
545 GetParam(), ProxyService::CreateDirect());
546 scoped_refptr
<HttpNetworkSession
> session(
547 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
548 HttpNetworkSessionPeer
peer(session
);
550 // Put a SpdySession in the pool.
551 HostPortPair
host_port_pair("www.google.com", 443);
552 SpdySessionKey
key(host_port_pair
, ProxyServer::Direct(),
553 kPrivacyModeDisabled
);
554 ignore_result(CreateFakeSpdySession(session
->spdy_session_pool(), key
));
556 CapturePreconnectsTransportSocketPool
* transport_conn_pool
=
557 new CapturePreconnectsTransportSocketPool(
558 session_deps
.host_resolver
.get(),
559 session_deps
.cert_verifier
.get());
560 CapturePreconnectsSSLSocketPool
* ssl_conn_pool
=
561 new CapturePreconnectsSSLSocketPool(
562 session_deps
.host_resolver
.get(),
563 session_deps
.cert_verifier
.get());
564 scoped_ptr
<MockClientSocketPoolManager
> mock_pool_manager(
565 new MockClientSocketPoolManager
);
566 mock_pool_manager
->SetTransportSocketPool(transport_conn_pool
);
567 mock_pool_manager
->SetSSLSocketPool(ssl_conn_pool
);
568 peer
.SetClientSocketPoolManager(
569 mock_pool_manager
.PassAs
<ClientSocketPoolManager
>());
570 PreconnectHelper(kTests
[i
], session
.get());
571 // We shouldn't be preconnecting if we have an existing session, which is
572 // the case for https://www.google.com.
574 EXPECT_EQ(-1, ssl_conn_pool
->last_num_streams());
576 EXPECT_EQ(kTests
[i
].num_streams
,
577 transport_conn_pool
->last_num_streams());
581 // Verify that preconnects to unsafe ports are cancelled before they reach
583 TEST_P(HttpStreamFactoryTest
, PreconnectUnsafePort
) {
584 ASSERT_FALSE(IsPortAllowedByDefault(7));
585 ASSERT_FALSE(IsPortAllowedByOverride(7));
587 SpdySessionDependencies
session_deps(
588 GetParam(), ProxyService::CreateDirect());
589 scoped_refptr
<HttpNetworkSession
> session(
590 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
591 HttpNetworkSessionPeer
peer(session
);
592 CapturePreconnectsTransportSocketPool
* transport_conn_pool
=
593 new CapturePreconnectsTransportSocketPool(
594 session_deps
.host_resolver
.get(),
595 session_deps
.cert_verifier
.get());
596 scoped_ptr
<MockClientSocketPoolManager
> mock_pool_manager(
597 new MockClientSocketPoolManager
);
598 mock_pool_manager
->SetTransportSocketPool(transport_conn_pool
);
599 peer
.SetClientSocketPoolManager(
600 mock_pool_manager
.PassAs
<ClientSocketPoolManager
>());
602 PreconnectHelperForURL(1, GURL("http://www.google.com:7"), session
.get());
604 EXPECT_EQ(-1, transport_conn_pool
->last_num_streams());
607 TEST_P(HttpStreamFactoryTest
, JobNotifiesProxy
) {
608 const char* kProxyString
= "PROXY bad:99; PROXY maybe:80; DIRECT";
609 SpdySessionDependencies
session_deps(
610 GetParam(), ProxyService::CreateFixedFromPacResult(kProxyString
));
612 // First connection attempt fails
613 StaticSocketDataProvider socket_data1
;
614 socket_data1
.set_connect_data(MockConnect(ASYNC
, ERR_ADDRESS_UNREACHABLE
));
615 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data1
);
617 // Second connection attempt succeeds
618 StaticSocketDataProvider socket_data2
;
619 socket_data2
.set_connect_data(MockConnect(ASYNC
, OK
));
620 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data2
);
622 scoped_refptr
<HttpNetworkSession
> session(
623 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
625 // Now request a stream. It should succeed using the second proxy in the
627 HttpRequestInfo request_info
;
628 request_info
.method
= "GET";
629 request_info
.url
= GURL("http://www.google.com");
631 SSLConfig ssl_config
;
632 StreamRequestWaiter waiter
;
633 scoped_ptr
<HttpStreamRequest
> request(
634 session
->http_stream_factory()->RequestStream(
635 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
,
636 &waiter
, BoundNetLog()));
637 waiter
.WaitForStream();
639 // The proxy that failed should now be known to the proxy_service as bad.
640 const ProxyRetryInfoMap
& retry_info
=
641 session
->proxy_service()->proxy_retry_info();
642 EXPECT_EQ(1u, retry_info
.size());
643 ProxyRetryInfoMap::const_iterator iter
= retry_info
.find("bad:99");
644 EXPECT_TRUE(iter
!= retry_info
.end());
647 TEST_P(HttpStreamFactoryTest
, PrivacyModeDisablesChannelId
) {
648 SpdySessionDependencies
session_deps(
649 GetParam(), ProxyService::CreateDirect());
651 StaticSocketDataProvider socket_data
;
652 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
653 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
655 SSLSocketDataProvider
ssl(ASYNC
, OK
);
656 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl
);
658 scoped_refptr
<HttpNetworkSession
> session(
659 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
661 // Set an existing SpdySession in the pool.
662 HostPortPair
host_port_pair("www.google.com", 443);
663 SpdySessionKey
key(host_port_pair
, ProxyServer::Direct(),
664 kPrivacyModeEnabled
);
666 HttpRequestInfo request_info
;
667 request_info
.method
= "GET";
668 request_info
.url
= GURL("https://www.google.com");
669 request_info
.load_flags
= 0;
670 request_info
.privacy_mode
= kPrivacyModeDisabled
;
672 SSLConfig ssl_config
;
673 StreamRequestWaiter waiter
;
674 scoped_ptr
<HttpStreamRequest
> request(
675 session
->http_stream_factory()->RequestStream(
676 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
,
677 &waiter
, BoundNetLog()));
678 waiter
.WaitForStream();
680 // The stream shouldn't come from spdy as we are using different privacy mode
681 EXPECT_FALSE(request
->using_spdy());
683 SSLConfig used_ssl_config
= waiter
.used_ssl_config();
684 EXPECT_EQ(used_ssl_config
.channel_id_enabled
, ssl_config
.channel_id_enabled
);
688 // Return count of distinct groups in given socket pool.
689 int GetSocketPoolGroupCount(ClientSocketPool
* pool
) {
691 scoped_ptr
<base::DictionaryValue
> dict(pool
->GetInfoAsValue("", "", false));
692 EXPECT_TRUE(dict
!= NULL
);
693 base::DictionaryValue
* groups
= NULL
;
694 if (dict
->GetDictionary("groups", &groups
) && (groups
!= NULL
)) {
695 count
= static_cast<int>(groups
->size());
701 TEST_P(HttpStreamFactoryTest
, PrivacyModeUsesDifferentSocketPoolGroup
) {
702 SpdySessionDependencies
session_deps(
703 GetParam(), ProxyService::CreateDirect());
705 StaticSocketDataProvider socket_data
;
706 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
707 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
709 SSLSocketDataProvider
ssl(ASYNC
, OK
);
710 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl
);
712 scoped_refptr
<HttpNetworkSession
> session(
713 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
714 SSLClientSocketPool
* ssl_pool
= session
->GetSSLSocketPool(
715 HttpNetworkSession::NORMAL_SOCKET_POOL
);
717 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool
), 0);
719 HttpRequestInfo request_info
;
720 request_info
.method
= "GET";
721 request_info
.url
= GURL("https://www.google.com");
722 request_info
.load_flags
= 0;
723 request_info
.privacy_mode
= kPrivacyModeDisabled
;
725 SSLConfig ssl_config
;
726 StreamRequestWaiter waiter
;
728 scoped_ptr
<HttpStreamRequest
> request1(
729 session
->http_stream_factory()->RequestStream(
730 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
,
731 &waiter
, BoundNetLog()));
732 waiter
.WaitForStream();
734 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool
), 1);
736 scoped_ptr
<HttpStreamRequest
> request2(
737 session
->http_stream_factory()->RequestStream(
738 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
,
739 &waiter
, BoundNetLog()));
740 waiter
.WaitForStream();
742 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool
), 1);
744 request_info
.privacy_mode
= kPrivacyModeEnabled
;
745 scoped_ptr
<HttpStreamRequest
> request3(
746 session
->http_stream_factory()->RequestStream(
747 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
,
748 &waiter
, BoundNetLog()));
749 waiter
.WaitForStream();
751 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool
), 2);
754 TEST_P(HttpStreamFactoryTest
, GetLoadState
) {
755 SpdySessionDependencies
session_deps(
756 GetParam(), ProxyService::CreateDirect());
758 StaticSocketDataProvider socket_data
;
759 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
760 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
762 scoped_refptr
<HttpNetworkSession
> session(
763 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
765 HttpRequestInfo request_info
;
766 request_info
.method
= "GET";
767 request_info
.url
= GURL("http://www.google.com");
769 SSLConfig ssl_config
;
770 StreamRequestWaiter waiter
;
771 scoped_ptr
<HttpStreamRequest
> request(
772 session
->http_stream_factory()->RequestStream(
773 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
,
774 &waiter
, BoundNetLog()));
776 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST
, request
->GetLoadState());
778 waiter
.WaitForStream();
781 TEST_P(HttpStreamFactoryTest
, RequestHttpStream
) {
782 SpdySessionDependencies
session_deps(
783 GetParam(), ProxyService::CreateDirect());
785 StaticSocketDataProvider socket_data
;
786 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
787 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
789 scoped_refptr
<HttpNetworkSession
> session(
790 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
792 // Now request a stream. It should succeed using the second proxy in the
794 HttpRequestInfo request_info
;
795 request_info
.method
= "GET";
796 request_info
.url
= GURL("http://www.google.com");
797 request_info
.load_flags
= 0;
799 SSLConfig ssl_config
;
800 StreamRequestWaiter waiter
;
801 scoped_ptr
<HttpStreamRequest
> request(
802 session
->http_stream_factory()->RequestStream(
809 waiter
.WaitForStream();
810 EXPECT_TRUE(waiter
.stream_done());
811 ASSERT_TRUE(NULL
!= waiter
.stream());
812 EXPECT_TRUE(NULL
== waiter
.websocket_stream());
813 EXPECT_FALSE(waiter
.stream()->IsSpdyHttpStream());
815 EXPECT_EQ(1, GetSocketPoolGroupCount(
816 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
817 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSSLSocketPool(
818 HttpNetworkSession::NORMAL_SOCKET_POOL
)));
819 EXPECT_EQ(0, GetSocketPoolGroupCount(
820 session
->GetTransportSocketPool(
821 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
822 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSSLSocketPool(
823 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
824 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
827 TEST_P(HttpStreamFactoryTest
, RequestHttpStreamOverSSL
) {
828 SpdySessionDependencies
session_deps(
829 GetParam(), ProxyService::CreateDirect());
831 MockRead
mock_read(ASYNC
, OK
);
832 StaticSocketDataProvider
socket_data(&mock_read
, 1, NULL
, 0);
833 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
834 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
836 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
837 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl_socket_data
);
839 scoped_refptr
<HttpNetworkSession
> session(
840 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
842 // Now request a stream.
843 HttpRequestInfo request_info
;
844 request_info
.method
= "GET";
845 request_info
.url
= GURL("https://www.google.com");
846 request_info
.load_flags
= 0;
848 SSLConfig ssl_config
;
849 StreamRequestWaiter waiter
;
850 scoped_ptr
<HttpStreamRequest
> request(
851 session
->http_stream_factory()->RequestStream(
858 waiter
.WaitForStream();
859 EXPECT_TRUE(waiter
.stream_done());
860 ASSERT_TRUE(NULL
!= waiter
.stream());
861 EXPECT_TRUE(NULL
== waiter
.websocket_stream());
862 EXPECT_FALSE(waiter
.stream()->IsSpdyHttpStream());
863 EXPECT_EQ(1, GetSocketPoolGroupCount(
864 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
865 EXPECT_EQ(1, GetSocketPoolGroupCount(
866 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
867 EXPECT_EQ(0, GetSocketPoolGroupCount(
868 session
->GetTransportSocketPool(
869 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
870 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSSLSocketPool(
871 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
872 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
875 TEST_P(HttpStreamFactoryTest
, RequestHttpStreamOverProxy
) {
876 SpdySessionDependencies
session_deps(
877 GetParam(), ProxyService::CreateFixed("myproxy:8888"));
879 StaticSocketDataProvider socket_data
;
880 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
881 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
883 scoped_refptr
<HttpNetworkSession
> session(
884 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
886 // Now request a stream. It should succeed using the second proxy in the
888 HttpRequestInfo request_info
;
889 request_info
.method
= "GET";
890 request_info
.url
= GURL("http://www.google.com");
891 request_info
.load_flags
= 0;
893 SSLConfig ssl_config
;
894 StreamRequestWaiter waiter
;
895 scoped_ptr
<HttpStreamRequest
> request(
896 session
->http_stream_factory()->RequestStream(
903 waiter
.WaitForStream();
904 EXPECT_TRUE(waiter
.stream_done());
905 ASSERT_TRUE(NULL
!= waiter
.stream());
906 EXPECT_TRUE(NULL
== waiter
.websocket_stream());
907 EXPECT_FALSE(waiter
.stream()->IsSpdyHttpStream());
908 EXPECT_EQ(0, GetSocketPoolGroupCount(
909 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
910 EXPECT_EQ(0, GetSocketPoolGroupCount(
911 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
912 EXPECT_EQ(1, GetSocketPoolGroupCount(session
->GetSocketPoolForHTTPProxy(
913 HttpNetworkSession::NORMAL_SOCKET_POOL
,
914 HostPortPair("myproxy", 8888))));
915 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSocketPoolForSSLWithProxy(
916 HttpNetworkSession::NORMAL_SOCKET_POOL
,
917 HostPortPair("myproxy", 8888))));
918 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSocketPoolForHTTPProxy(
919 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
,
920 HostPortPair("myproxy", 8888))));
921 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSocketPoolForSSLWithProxy(
922 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
,
923 HostPortPair("myproxy", 8888))));
924 EXPECT_FALSE(waiter
.used_proxy_info().is_direct());
927 TEST_P(HttpStreamFactoryTest
, RequestWebSocketBasicHandshakeStream
) {
928 SpdySessionDependencies
session_deps(
929 GetParam(), ProxyService::CreateDirect());
931 StaticSocketDataProvider socket_data
;
932 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
933 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
935 scoped_refptr
<HttpNetworkSession
> session(
936 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
938 // Now request a stream.
939 HttpRequestInfo request_info
;
940 request_info
.method
= "GET";
941 request_info
.url
= GURL("ws://www.google.com");
942 request_info
.load_flags
= 0;
944 SSLConfig ssl_config
;
945 StreamRequestWaiter waiter
;
946 WebSocketStreamCreateHelper create_helper
;
947 scoped_ptr
<HttpStreamRequest
> request(
948 session
->http_stream_factory_for_websocket()
949 ->RequestWebSocketHandshakeStream(request_info
,
956 waiter
.WaitForStream();
957 EXPECT_TRUE(waiter
.stream_done());
958 EXPECT_TRUE(NULL
== waiter
.stream());
959 ASSERT_TRUE(NULL
!= waiter
.websocket_stream());
960 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic
,
961 waiter
.websocket_stream()->type());
962 EXPECT_EQ(0, GetSocketPoolGroupCount(
963 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
964 EXPECT_EQ(0, GetSocketPoolGroupCount(
965 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
966 EXPECT_EQ(1, GetSocketPoolGroupCount(
967 session
->GetTransportSocketPool(
968 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
969 EXPECT_EQ(0, GetSocketPoolGroupCount(
970 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
971 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
974 TEST_P(HttpStreamFactoryTest
, RequestWebSocketBasicHandshakeStreamOverSSL
) {
975 SpdySessionDependencies
session_deps(
976 GetParam(), ProxyService::CreateDirect());
978 MockRead
mock_read(ASYNC
, OK
);
979 StaticSocketDataProvider
socket_data(&mock_read
, 1, NULL
, 0);
980 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
981 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
983 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
984 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl_socket_data
);
986 scoped_refptr
<HttpNetworkSession
> session(
987 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
989 // Now request a stream.
990 HttpRequestInfo request_info
;
991 request_info
.method
= "GET";
992 request_info
.url
= GURL("wss://www.google.com");
993 request_info
.load_flags
= 0;
995 SSLConfig ssl_config
;
996 StreamRequestWaiter waiter
;
997 WebSocketStreamCreateHelper create_helper
;
998 scoped_ptr
<HttpStreamRequest
> request(
999 session
->http_stream_factory_for_websocket()
1000 ->RequestWebSocketHandshakeStream(request_info
,
1007 waiter
.WaitForStream();
1008 EXPECT_TRUE(waiter
.stream_done());
1009 EXPECT_TRUE(NULL
== waiter
.stream());
1010 ASSERT_TRUE(NULL
!= waiter
.websocket_stream());
1011 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic
,
1012 waiter
.websocket_stream()->type());
1013 EXPECT_EQ(0, GetSocketPoolGroupCount(
1014 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1015 EXPECT_EQ(0, GetSocketPoolGroupCount(
1016 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1017 EXPECT_EQ(1, GetSocketPoolGroupCount(
1018 session
->GetTransportSocketPool(
1019 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1020 EXPECT_EQ(1, GetSocketPoolGroupCount(
1021 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1022 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
1025 TEST_P(HttpStreamFactoryTest
, RequestWebSocketBasicHandshakeStreamOverProxy
) {
1026 SpdySessionDependencies
session_deps(
1027 GetParam(), ProxyService::CreateFixed("myproxy:8888"));
1029 MockRead
read(SYNCHRONOUS
, "HTTP/1.0 200 Connection established\r\n\r\n");
1030 StaticSocketDataProvider
socket_data(&read
, 1, 0, 0);
1031 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
1032 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
1034 scoped_refptr
<HttpNetworkSession
> session(
1035 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
1037 // Now request a stream.
1038 HttpRequestInfo request_info
;
1039 request_info
.method
= "GET";
1040 request_info
.url
= GURL("ws://www.google.com");
1041 request_info
.load_flags
= 0;
1043 SSLConfig ssl_config
;
1044 StreamRequestWaiter waiter
;
1045 WebSocketStreamCreateHelper create_helper
;
1046 scoped_ptr
<HttpStreamRequest
> request(
1047 session
->http_stream_factory_for_websocket()
1048 ->RequestWebSocketHandshakeStream(request_info
,
1055 waiter
.WaitForStream();
1056 EXPECT_TRUE(waiter
.stream_done());
1057 EXPECT_TRUE(NULL
== waiter
.stream());
1058 ASSERT_TRUE(NULL
!= waiter
.websocket_stream());
1059 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic
,
1060 waiter
.websocket_stream()->type());
1061 EXPECT_EQ(0, GetSocketPoolGroupCount(
1062 session
->GetTransportSocketPool(
1063 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1064 EXPECT_EQ(0, GetSocketPoolGroupCount(
1065 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1066 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSocketPoolForHTTPProxy(
1067 HttpNetworkSession::NORMAL_SOCKET_POOL
,
1068 HostPortPair("myproxy", 8888))));
1069 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSocketPoolForSSLWithProxy(
1070 HttpNetworkSession::NORMAL_SOCKET_POOL
,
1071 HostPortPair("myproxy", 8888))));
1072 EXPECT_EQ(1, GetSocketPoolGroupCount(session
->GetSocketPoolForHTTPProxy(
1073 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
,
1074 HostPortPair("myproxy", 8888))));
1075 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSocketPoolForSSLWithProxy(
1076 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
,
1077 HostPortPair("myproxy", 8888))));
1078 EXPECT_FALSE(waiter
.used_proxy_info().is_direct());
1081 TEST_P(HttpStreamFactoryTest
, RequestSpdyHttpStream
) {
1082 SpdySessionDependencies
session_deps(GetParam(),
1083 ProxyService::CreateDirect());
1085 MockRead
mock_read(ASYNC
, OK
);
1086 DeterministicSocketData
socket_data(&mock_read
, 1, NULL
, 0);
1087 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
1088 session_deps
.deterministic_socket_factory
->AddSocketDataProvider(
1091 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
1092 ssl_socket_data
.SetNextProto(GetParam());
1093 session_deps
.deterministic_socket_factory
->AddSSLSocketDataProvider(
1096 HostPortPair
host_port_pair("www.google.com", 443);
1097 scoped_refptr
<HttpNetworkSession
>
1098 session(SpdySessionDependencies::SpdyCreateSessionDeterministic(
1101 // Now request a stream.
1102 HttpRequestInfo request_info
;
1103 request_info
.method
= "GET";
1104 request_info
.url
= GURL("https://www.google.com");
1105 request_info
.load_flags
= 0;
1107 SSLConfig ssl_config
;
1108 StreamRequestWaiter waiter
;
1109 scoped_ptr
<HttpStreamRequest
> request(
1110 session
->http_stream_factory()->RequestStream(
1117 waiter
.WaitForStream();
1118 EXPECT_TRUE(waiter
.stream_done());
1119 EXPECT_TRUE(NULL
== waiter
.websocket_stream());
1120 ASSERT_TRUE(NULL
!= waiter
.stream());
1121 EXPECT_TRUE(waiter
.stream()->IsSpdyHttpStream());
1122 EXPECT_EQ(1, GetSocketPoolGroupCount(
1123 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1124 EXPECT_EQ(1, GetSocketPoolGroupCount(
1125 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1126 EXPECT_EQ(0, GetSocketPoolGroupCount(
1127 session
->GetTransportSocketPool(
1128 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1129 EXPECT_EQ(0, GetSocketPoolGroupCount(
1130 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1131 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
1134 // TODO(ricea): This test can be removed once the new WebSocket stack supports
1135 // SPDY. Currently, even if we connect to a SPDY-supporting server, we need to
1137 TEST_P(HttpStreamFactoryTest
, RequestWebSocketSpdyHandshakeStreamButGetSSL
) {
1138 SpdySessionDependencies
session_deps(GetParam(),
1139 ProxyService::CreateDirect());
1141 MockRead
mock_read(SYNCHRONOUS
, ERR_IO_PENDING
);
1142 StaticSocketDataProvider
socket_data(&mock_read
, 1, NULL
, 0);
1143 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
1144 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
1146 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
1147 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl_socket_data
);
1149 HostPortPair
host_port_pair("www.google.com", 80);
1150 scoped_refptr
<HttpNetworkSession
>
1151 session(SpdySessionDependencies::SpdyCreateSession(&session_deps
));
1153 // Now request a stream.
1154 HttpRequestInfo request_info
;
1155 request_info
.method
= "GET";
1156 request_info
.url
= GURL("wss://www.google.com");
1157 request_info
.load_flags
= 0;
1159 SSLConfig ssl_config
;
1160 StreamRequestWaiter waiter1
;
1161 WebSocketStreamCreateHelper create_helper
;
1162 scoped_ptr
<HttpStreamRequest
> request1(
1163 session
->http_stream_factory_for_websocket()
1164 ->RequestWebSocketHandshakeStream(request_info
,
1171 waiter1
.WaitForStream();
1172 EXPECT_TRUE(waiter1
.stream_done());
1173 ASSERT_TRUE(NULL
!= waiter1
.websocket_stream());
1174 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic
,
1175 waiter1
.websocket_stream()->type());
1176 EXPECT_TRUE(NULL
== waiter1
.stream());
1178 EXPECT_EQ(0, GetSocketPoolGroupCount(
1179 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1180 EXPECT_EQ(0, GetSocketPoolGroupCount(
1181 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1182 EXPECT_EQ(1, GetSocketPoolGroupCount(
1183 session
->GetTransportSocketPool(
1184 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1185 EXPECT_EQ(1, GetSocketPoolGroupCount(
1186 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1187 EXPECT_TRUE(waiter1
.used_proxy_info().is_direct());
1190 // TODO(ricea): Re-enable once WebSocket-over-SPDY is implemented.
1191 TEST_P(HttpStreamFactoryTest
, DISABLED_RequestWebSocketSpdyHandshakeStream
) {
1192 SpdySessionDependencies
session_deps(GetParam(),
1193 ProxyService::CreateDirect());
1195 MockRead
mock_read(SYNCHRONOUS
, ERR_IO_PENDING
);
1196 StaticSocketDataProvider
socket_data(&mock_read
, 1, NULL
, 0);
1197 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
1198 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
1200 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
1201 ssl_socket_data
.SetNextProto(GetParam());
1202 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl_socket_data
);
1204 HostPortPair
host_port_pair("www.google.com", 80);
1205 scoped_refptr
<HttpNetworkSession
>
1206 session(SpdySessionDependencies::SpdyCreateSession(&session_deps
));
1208 // Now request a stream.
1209 HttpRequestInfo request_info
;
1210 request_info
.method
= "GET";
1211 request_info
.url
= GURL("wss://www.google.com");
1212 request_info
.load_flags
= 0;
1214 SSLConfig ssl_config
;
1215 StreamRequestWaiter waiter1
;
1216 WebSocketStreamCreateHelper create_helper
;
1217 scoped_ptr
<HttpStreamRequest
> request1(
1218 session
->http_stream_factory_for_websocket()
1219 ->RequestWebSocketHandshakeStream(request_info
,
1226 waiter1
.WaitForStream();
1227 EXPECT_TRUE(waiter1
.stream_done());
1228 ASSERT_TRUE(NULL
!= waiter1
.websocket_stream());
1229 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy
,
1230 waiter1
.websocket_stream()->type());
1231 EXPECT_TRUE(NULL
== waiter1
.stream());
1233 StreamRequestWaiter waiter2
;
1234 scoped_ptr
<HttpStreamRequest
> request2(
1235 session
->http_stream_factory_for_websocket()
1236 ->RequestWebSocketHandshakeStream(request_info
,
1243 waiter2
.WaitForStream();
1244 EXPECT_TRUE(waiter2
.stream_done());
1245 ASSERT_TRUE(NULL
!= waiter2
.websocket_stream());
1246 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy
,
1247 waiter2
.websocket_stream()->type());
1248 EXPECT_TRUE(NULL
== waiter2
.stream());
1249 EXPECT_NE(waiter2
.websocket_stream(), waiter1
.websocket_stream());
1250 EXPECT_EQ(static_cast<WebSocketSpdyHandshakeStream
*>(
1251 waiter2
.websocket_stream())->spdy_session(),
1252 static_cast<WebSocketSpdyHandshakeStream
*>(
1253 waiter1
.websocket_stream())->spdy_session());
1255 EXPECT_EQ(0, GetSocketPoolGroupCount(
1256 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1257 EXPECT_EQ(0, GetSocketPoolGroupCount(
1258 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1259 EXPECT_EQ(1, GetSocketPoolGroupCount(
1260 session
->GetTransportSocketPool(
1261 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1262 EXPECT_EQ(1, GetSocketPoolGroupCount(
1263 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1264 EXPECT_TRUE(waiter1
.used_proxy_info().is_direct());
1267 // TODO(ricea): Re-enable once WebSocket over SPDY is implemented.
1268 TEST_P(HttpStreamFactoryTest
, DISABLED_OrphanedWebSocketStream
) {
1269 UseAlternateProtocolsScopedSetter
use_alternate_protocols(true);
1270 SpdySessionDependencies
session_deps(GetParam(),
1271 ProxyService::CreateDirect());
1273 MockRead
mock_read(ASYNC
, OK
);
1274 DeterministicSocketData
socket_data(&mock_read
, 1, NULL
, 0);
1275 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
1276 session_deps
.deterministic_socket_factory
->AddSocketDataProvider(
1279 MockRead
mock_read2(ASYNC
, OK
);
1280 DeterministicSocketData
socket_data2(&mock_read2
, 1, NULL
, 0);
1281 socket_data2
.set_connect_data(MockConnect(ASYNC
, ERR_IO_PENDING
));
1282 session_deps
.deterministic_socket_factory
->AddSocketDataProvider(
1285 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
1286 ssl_socket_data
.SetNextProto(GetParam());
1287 session_deps
.deterministic_socket_factory
->AddSSLSocketDataProvider(
1290 scoped_refptr
<HttpNetworkSession
>
1291 session(SpdySessionDependencies::SpdyCreateSessionDeterministic(
1294 // Now request a stream.
1295 HttpRequestInfo request_info
;
1296 request_info
.method
= "GET";
1297 request_info
.url
= GURL("ws://www.google.com:8888");
1298 request_info
.load_flags
= 0;
1300 session
->http_server_properties()->SetAlternateProtocol(
1301 HostPortPair("www.google.com", 8888),
1305 SSLConfig ssl_config
;
1306 StreamRequestWaiter waiter
;
1307 WebSocketStreamCreateHelper create_helper
;
1308 scoped_ptr
<HttpStreamRequest
> request(
1309 session
->http_stream_factory_for_websocket()
1310 ->RequestWebSocketHandshakeStream(request_info
,
1317 waiter
.WaitForStream();
1318 EXPECT_TRUE(waiter
.stream_done());
1319 EXPECT_TRUE(NULL
== waiter
.stream());
1320 ASSERT_TRUE(NULL
!= waiter
.websocket_stream());
1321 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy
,
1322 waiter
.websocket_stream()->type());
1324 // Make sure that there was an alternative connection
1325 // which consumes extra connections.
1326 EXPECT_EQ(0, GetSocketPoolGroupCount(
1327 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1328 EXPECT_EQ(0, GetSocketPoolGroupCount(
1329 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1330 EXPECT_EQ(2, GetSocketPoolGroupCount(
1331 session
->GetTransportSocketPool(
1332 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1333 EXPECT_EQ(1, GetSocketPoolGroupCount(
1334 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1335 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
1337 // Make sure there is no orphaned job. it is already canceled.
1338 ASSERT_EQ(0u, static_cast<HttpStreamFactoryImpl
*>(
1339 session
->http_stream_factory_for_websocket())->num_orphaned_jobs());