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
, // server_bound_cert_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
419 last_num_streams_(-1) {}
421 class HttpStreamFactoryTest
: public ::testing::Test
,
422 public ::testing::WithParamInterface
<NextProto
> {
425 INSTANTIATE_TEST_CASE_P(
427 HttpStreamFactoryTest
,
428 testing::Values(kProtoDeprecatedSPDY2
,
429 kProtoSPDY3
, kProtoSPDY31
, kProtoSPDY4
));
431 TEST_P(HttpStreamFactoryTest
, PreconnectDirect
) {
432 for (size_t i
= 0; i
< arraysize(kTests
); ++i
) {
433 SpdySessionDependencies
session_deps(
434 GetParam(), ProxyService::CreateDirect());
435 scoped_refptr
<HttpNetworkSession
> session(
436 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
437 HttpNetworkSessionPeer
peer(session
);
438 CapturePreconnectsTransportSocketPool
* transport_conn_pool
=
439 new CapturePreconnectsTransportSocketPool(
440 session_deps
.host_resolver
.get(),
441 session_deps
.cert_verifier
.get());
442 CapturePreconnectsSSLSocketPool
* ssl_conn_pool
=
443 new CapturePreconnectsSSLSocketPool(
444 session_deps
.host_resolver
.get(),
445 session_deps
.cert_verifier
.get());
446 scoped_ptr
<MockClientSocketPoolManager
> mock_pool_manager(
447 new MockClientSocketPoolManager
);
448 mock_pool_manager
->SetTransportSocketPool(transport_conn_pool
);
449 mock_pool_manager
->SetSSLSocketPool(ssl_conn_pool
);
450 peer
.SetClientSocketPoolManager(
451 mock_pool_manager
.PassAs
<ClientSocketPoolManager
>());
452 PreconnectHelper(kTests
[i
], session
.get());
454 EXPECT_EQ(kTests
[i
].num_streams
, ssl_conn_pool
->last_num_streams());
456 EXPECT_EQ(kTests
[i
].num_streams
, transport_conn_pool
->last_num_streams());
460 TEST_P(HttpStreamFactoryTest
, PreconnectHttpProxy
) {
461 for (size_t i
= 0; i
< arraysize(kTests
); ++i
) {
462 SpdySessionDependencies
session_deps(
463 GetParam(), ProxyService::CreateFixed("http_proxy"));
464 scoped_refptr
<HttpNetworkSession
> session(
465 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
466 HttpNetworkSessionPeer
peer(session
);
467 HostPortPair
proxy_host("http_proxy", 80);
468 CapturePreconnectsHttpProxySocketPool
* http_proxy_pool
=
469 new CapturePreconnectsHttpProxySocketPool(
470 session_deps
.host_resolver
.get(),
471 session_deps
.cert_verifier
.get());
472 CapturePreconnectsSSLSocketPool
* ssl_conn_pool
=
473 new CapturePreconnectsSSLSocketPool(
474 session_deps
.host_resolver
.get(),
475 session_deps
.cert_verifier
.get());
476 scoped_ptr
<MockClientSocketPoolManager
> mock_pool_manager(
477 new MockClientSocketPoolManager
);
478 mock_pool_manager
->SetSocketPoolForHTTPProxy(proxy_host
, http_proxy_pool
);
479 mock_pool_manager
->SetSocketPoolForSSLWithProxy(proxy_host
, ssl_conn_pool
);
480 peer
.SetClientSocketPoolManager(
481 mock_pool_manager
.PassAs
<ClientSocketPoolManager
>());
482 PreconnectHelper(kTests
[i
], session
.get());
484 EXPECT_EQ(kTests
[i
].num_streams
, ssl_conn_pool
->last_num_streams());
486 EXPECT_EQ(kTests
[i
].num_streams
, http_proxy_pool
->last_num_streams());
490 TEST_P(HttpStreamFactoryTest
, PreconnectSocksProxy
) {
491 for (size_t i
= 0; i
< arraysize(kTests
); ++i
) {
492 SpdySessionDependencies
session_deps(
493 GetParam(), ProxyService::CreateFixed("socks4://socks_proxy:1080"));
494 scoped_refptr
<HttpNetworkSession
> session(
495 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
496 HttpNetworkSessionPeer
peer(session
);
497 HostPortPair
proxy_host("socks_proxy", 1080);
498 CapturePreconnectsSOCKSSocketPool
* socks_proxy_pool
=
499 new CapturePreconnectsSOCKSSocketPool(
500 session_deps
.host_resolver
.get(),
501 session_deps
.cert_verifier
.get());
502 CapturePreconnectsSSLSocketPool
* ssl_conn_pool
=
503 new CapturePreconnectsSSLSocketPool(
504 session_deps
.host_resolver
.get(),
505 session_deps
.cert_verifier
.get());
506 scoped_ptr
<MockClientSocketPoolManager
> mock_pool_manager(
507 new MockClientSocketPoolManager
);
508 mock_pool_manager
->SetSocketPoolForSOCKSProxy(proxy_host
, socks_proxy_pool
);
509 mock_pool_manager
->SetSocketPoolForSSLWithProxy(proxy_host
, ssl_conn_pool
);
510 peer
.SetClientSocketPoolManager(
511 mock_pool_manager
.PassAs
<ClientSocketPoolManager
>());
512 PreconnectHelper(kTests
[i
], session
.get());
514 EXPECT_EQ(kTests
[i
].num_streams
, ssl_conn_pool
->last_num_streams());
516 EXPECT_EQ(kTests
[i
].num_streams
, socks_proxy_pool
->last_num_streams());
520 TEST_P(HttpStreamFactoryTest
, PreconnectDirectWithExistingSpdySession
) {
521 for (size_t i
= 0; i
< arraysize(kTests
); ++i
) {
522 SpdySessionDependencies
session_deps(
523 GetParam(), ProxyService::CreateDirect());
524 scoped_refptr
<HttpNetworkSession
> session(
525 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
526 HttpNetworkSessionPeer
peer(session
);
528 // Put a SpdySession in the pool.
529 HostPortPair
host_port_pair("www.google.com", 443);
530 SpdySessionKey
key(host_port_pair
, ProxyServer::Direct(),
531 PRIVACY_MODE_DISABLED
);
532 ignore_result(CreateFakeSpdySession(session
->spdy_session_pool(), key
));
534 CapturePreconnectsTransportSocketPool
* transport_conn_pool
=
535 new CapturePreconnectsTransportSocketPool(
536 session_deps
.host_resolver
.get(),
537 session_deps
.cert_verifier
.get());
538 CapturePreconnectsSSLSocketPool
* ssl_conn_pool
=
539 new CapturePreconnectsSSLSocketPool(
540 session_deps
.host_resolver
.get(),
541 session_deps
.cert_verifier
.get());
542 scoped_ptr
<MockClientSocketPoolManager
> mock_pool_manager(
543 new MockClientSocketPoolManager
);
544 mock_pool_manager
->SetTransportSocketPool(transport_conn_pool
);
545 mock_pool_manager
->SetSSLSocketPool(ssl_conn_pool
);
546 peer
.SetClientSocketPoolManager(
547 mock_pool_manager
.PassAs
<ClientSocketPoolManager
>());
548 PreconnectHelper(kTests
[i
], session
.get());
549 // We shouldn't be preconnecting if we have an existing session, which is
550 // the case for https://www.google.com.
552 EXPECT_EQ(-1, ssl_conn_pool
->last_num_streams());
554 EXPECT_EQ(kTests
[i
].num_streams
,
555 transport_conn_pool
->last_num_streams());
559 // Verify that preconnects to unsafe ports are cancelled before they reach
561 TEST_P(HttpStreamFactoryTest
, PreconnectUnsafePort
) {
562 ASSERT_FALSE(IsPortAllowedByDefault(7));
563 ASSERT_FALSE(IsPortAllowedByOverride(7));
565 SpdySessionDependencies
session_deps(
566 GetParam(), ProxyService::CreateDirect());
567 scoped_refptr
<HttpNetworkSession
> session(
568 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
569 HttpNetworkSessionPeer
peer(session
);
570 CapturePreconnectsTransportSocketPool
* transport_conn_pool
=
571 new CapturePreconnectsTransportSocketPool(
572 session_deps
.host_resolver
.get(),
573 session_deps
.cert_verifier
.get());
574 scoped_ptr
<MockClientSocketPoolManager
> mock_pool_manager(
575 new MockClientSocketPoolManager
);
576 mock_pool_manager
->SetTransportSocketPool(transport_conn_pool
);
577 peer
.SetClientSocketPoolManager(
578 mock_pool_manager
.PassAs
<ClientSocketPoolManager
>());
580 PreconnectHelperForURL(1, GURL("http://www.google.com:7"), session
.get());
582 EXPECT_EQ(-1, transport_conn_pool
->last_num_streams());
585 TEST_P(HttpStreamFactoryTest
, JobNotifiesProxy
) {
586 const char* kProxyString
= "PROXY bad:99; PROXY maybe:80; DIRECT";
587 SpdySessionDependencies
session_deps(
588 GetParam(), ProxyService::CreateFixedFromPacResult(kProxyString
));
590 // First connection attempt fails
591 StaticSocketDataProvider socket_data1
;
592 socket_data1
.set_connect_data(MockConnect(ASYNC
, ERR_ADDRESS_UNREACHABLE
));
593 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data1
);
595 // Second connection attempt succeeds
596 StaticSocketDataProvider socket_data2
;
597 socket_data2
.set_connect_data(MockConnect(ASYNC
, OK
));
598 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data2
);
600 scoped_refptr
<HttpNetworkSession
> session(
601 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
603 // Now request a stream. It should succeed using the second proxy in the
605 HttpRequestInfo request_info
;
606 request_info
.method
= "GET";
607 request_info
.url
= GURL("http://www.google.com");
609 SSLConfig ssl_config
;
610 StreamRequestWaiter waiter
;
611 scoped_ptr
<HttpStreamRequest
> request(
612 session
->http_stream_factory()->RequestStream(
613 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
,
614 &waiter
, BoundNetLog()));
615 waiter
.WaitForStream();
617 // The proxy that failed should now be known to the proxy_service as bad.
618 const ProxyRetryInfoMap
& retry_info
=
619 session
->proxy_service()->proxy_retry_info();
620 EXPECT_EQ(1u, retry_info
.size());
621 ProxyRetryInfoMap::const_iterator iter
= retry_info
.find("bad:99");
622 EXPECT_TRUE(iter
!= retry_info
.end());
625 TEST_P(HttpStreamFactoryTest
, PrivacyModeDisablesChannelId
) {
626 SpdySessionDependencies
session_deps(
627 GetParam(), ProxyService::CreateDirect());
629 StaticSocketDataProvider socket_data
;
630 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
631 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
633 SSLSocketDataProvider
ssl(ASYNC
, OK
);
634 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl
);
636 scoped_refptr
<HttpNetworkSession
> session(
637 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
639 // Set an existing SpdySession in the pool.
640 HostPortPair
host_port_pair("www.google.com", 443);
641 SpdySessionKey
key(host_port_pair
, ProxyServer::Direct(),
642 PRIVACY_MODE_ENABLED
);
644 HttpRequestInfo request_info
;
645 request_info
.method
= "GET";
646 request_info
.url
= GURL("https://www.google.com");
647 request_info
.load_flags
= 0;
648 request_info
.privacy_mode
= PRIVACY_MODE_DISABLED
;
650 SSLConfig ssl_config
;
651 StreamRequestWaiter waiter
;
652 scoped_ptr
<HttpStreamRequest
> request(
653 session
->http_stream_factory()->RequestStream(
654 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
,
655 &waiter
, BoundNetLog()));
656 waiter
.WaitForStream();
658 // The stream shouldn't come from spdy as we are using different privacy mode
659 EXPECT_FALSE(request
->using_spdy());
661 SSLConfig used_ssl_config
= waiter
.used_ssl_config();
662 EXPECT_EQ(used_ssl_config
.channel_id_enabled
, ssl_config
.channel_id_enabled
);
666 // Return count of distinct groups in given socket pool.
667 int GetSocketPoolGroupCount(ClientSocketPool
* pool
) {
669 scoped_ptr
<base::DictionaryValue
> dict(pool
->GetInfoAsValue("", "", false));
670 EXPECT_TRUE(dict
!= NULL
);
671 base::DictionaryValue
* groups
= NULL
;
672 if (dict
->GetDictionary("groups", &groups
) && (groups
!= NULL
)) {
673 count
= static_cast<int>(groups
->size());
679 TEST_P(HttpStreamFactoryTest
, PrivacyModeUsesDifferentSocketPoolGroup
) {
680 SpdySessionDependencies
session_deps(
681 GetParam(), ProxyService::CreateDirect());
683 StaticSocketDataProvider socket_data
;
684 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
685 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
687 SSLSocketDataProvider
ssl(ASYNC
, OK
);
688 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl
);
690 scoped_refptr
<HttpNetworkSession
> session(
691 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
692 SSLClientSocketPool
* ssl_pool
= session
->GetSSLSocketPool(
693 HttpNetworkSession::NORMAL_SOCKET_POOL
);
695 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool
), 0);
697 HttpRequestInfo request_info
;
698 request_info
.method
= "GET";
699 request_info
.url
= GURL("https://www.google.com");
700 request_info
.load_flags
= 0;
701 request_info
.privacy_mode
= PRIVACY_MODE_DISABLED
;
703 SSLConfig ssl_config
;
704 StreamRequestWaiter waiter
;
706 scoped_ptr
<HttpStreamRequest
> request1(
707 session
->http_stream_factory()->RequestStream(
708 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
,
709 &waiter
, BoundNetLog()));
710 waiter
.WaitForStream();
712 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool
), 1);
714 scoped_ptr
<HttpStreamRequest
> request2(
715 session
->http_stream_factory()->RequestStream(
716 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
,
717 &waiter
, BoundNetLog()));
718 waiter
.WaitForStream();
720 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool
), 1);
722 request_info
.privacy_mode
= PRIVACY_MODE_ENABLED
;
723 scoped_ptr
<HttpStreamRequest
> request3(
724 session
->http_stream_factory()->RequestStream(
725 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
,
726 &waiter
, BoundNetLog()));
727 waiter
.WaitForStream();
729 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool
), 2);
732 TEST_P(HttpStreamFactoryTest
, GetLoadState
) {
733 SpdySessionDependencies
session_deps(
734 GetParam(), ProxyService::CreateDirect());
736 StaticSocketDataProvider socket_data
;
737 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
738 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
740 scoped_refptr
<HttpNetworkSession
> session(
741 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
743 HttpRequestInfo request_info
;
744 request_info
.method
= "GET";
745 request_info
.url
= GURL("http://www.google.com");
747 SSLConfig ssl_config
;
748 StreamRequestWaiter waiter
;
749 scoped_ptr
<HttpStreamRequest
> request(
750 session
->http_stream_factory()->RequestStream(
751 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
,
752 &waiter
, BoundNetLog()));
754 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST
, request
->GetLoadState());
756 waiter
.WaitForStream();
759 TEST_P(HttpStreamFactoryTest
, RequestHttpStream
) {
760 SpdySessionDependencies
session_deps(
761 GetParam(), ProxyService::CreateDirect());
763 StaticSocketDataProvider socket_data
;
764 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
765 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
767 scoped_refptr
<HttpNetworkSession
> session(
768 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
770 // Now request a stream. It should succeed using the second proxy in the
772 HttpRequestInfo request_info
;
773 request_info
.method
= "GET";
774 request_info
.url
= GURL("http://www.google.com");
775 request_info
.load_flags
= 0;
777 SSLConfig ssl_config
;
778 StreamRequestWaiter waiter
;
779 scoped_ptr
<HttpStreamRequest
> request(
780 session
->http_stream_factory()->RequestStream(
787 waiter
.WaitForStream();
788 EXPECT_TRUE(waiter
.stream_done());
789 ASSERT_TRUE(NULL
!= waiter
.stream());
790 EXPECT_TRUE(NULL
== waiter
.websocket_stream());
791 EXPECT_FALSE(waiter
.stream()->IsSpdyHttpStream());
793 EXPECT_EQ(1, GetSocketPoolGroupCount(
794 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
795 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSSLSocketPool(
796 HttpNetworkSession::NORMAL_SOCKET_POOL
)));
797 EXPECT_EQ(0, GetSocketPoolGroupCount(
798 session
->GetTransportSocketPool(
799 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
800 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSSLSocketPool(
801 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
802 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
805 TEST_P(HttpStreamFactoryTest
, RequestHttpStreamOverSSL
) {
806 SpdySessionDependencies
session_deps(
807 GetParam(), ProxyService::CreateDirect());
809 MockRead
mock_read(ASYNC
, OK
);
810 StaticSocketDataProvider
socket_data(&mock_read
, 1, NULL
, 0);
811 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
812 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
814 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
815 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl_socket_data
);
817 scoped_refptr
<HttpNetworkSession
> session(
818 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
820 // Now request a stream.
821 HttpRequestInfo request_info
;
822 request_info
.method
= "GET";
823 request_info
.url
= GURL("https://www.google.com");
824 request_info
.load_flags
= 0;
826 SSLConfig ssl_config
;
827 StreamRequestWaiter waiter
;
828 scoped_ptr
<HttpStreamRequest
> request(
829 session
->http_stream_factory()->RequestStream(
836 waiter
.WaitForStream();
837 EXPECT_TRUE(waiter
.stream_done());
838 ASSERT_TRUE(NULL
!= waiter
.stream());
839 EXPECT_TRUE(NULL
== waiter
.websocket_stream());
840 EXPECT_FALSE(waiter
.stream()->IsSpdyHttpStream());
841 EXPECT_EQ(1, GetSocketPoolGroupCount(
842 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
843 EXPECT_EQ(1, GetSocketPoolGroupCount(
844 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
845 EXPECT_EQ(0, GetSocketPoolGroupCount(
846 session
->GetTransportSocketPool(
847 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
848 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSSLSocketPool(
849 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
850 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
853 TEST_P(HttpStreamFactoryTest
, RequestHttpStreamOverProxy
) {
854 SpdySessionDependencies
session_deps(
855 GetParam(), ProxyService::CreateFixed("myproxy:8888"));
857 StaticSocketDataProvider socket_data
;
858 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
859 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
861 scoped_refptr
<HttpNetworkSession
> session(
862 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
864 // Now request a stream. It should succeed using the second proxy in the
866 HttpRequestInfo request_info
;
867 request_info
.method
= "GET";
868 request_info
.url
= GURL("http://www.google.com");
869 request_info
.load_flags
= 0;
871 SSLConfig ssl_config
;
872 StreamRequestWaiter waiter
;
873 scoped_ptr
<HttpStreamRequest
> request(
874 session
->http_stream_factory()->RequestStream(
881 waiter
.WaitForStream();
882 EXPECT_TRUE(waiter
.stream_done());
883 ASSERT_TRUE(NULL
!= waiter
.stream());
884 EXPECT_TRUE(NULL
== waiter
.websocket_stream());
885 EXPECT_FALSE(waiter
.stream()->IsSpdyHttpStream());
886 EXPECT_EQ(0, GetSocketPoolGroupCount(
887 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
888 EXPECT_EQ(0, GetSocketPoolGroupCount(
889 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
890 EXPECT_EQ(1, GetSocketPoolGroupCount(session
->GetSocketPoolForHTTPProxy(
891 HttpNetworkSession::NORMAL_SOCKET_POOL
,
892 HostPortPair("myproxy", 8888))));
893 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSocketPoolForSSLWithProxy(
894 HttpNetworkSession::NORMAL_SOCKET_POOL
,
895 HostPortPair("myproxy", 8888))));
896 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSocketPoolForHTTPProxy(
897 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
,
898 HostPortPair("myproxy", 8888))));
899 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSocketPoolForSSLWithProxy(
900 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
,
901 HostPortPair("myproxy", 8888))));
902 EXPECT_FALSE(waiter
.used_proxy_info().is_direct());
905 TEST_P(HttpStreamFactoryTest
, RequestWebSocketBasicHandshakeStream
) {
906 SpdySessionDependencies
session_deps(
907 GetParam(), ProxyService::CreateDirect());
909 StaticSocketDataProvider socket_data
;
910 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
911 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
913 scoped_refptr
<HttpNetworkSession
> session(
914 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
916 // Now request a stream.
917 HttpRequestInfo request_info
;
918 request_info
.method
= "GET";
919 request_info
.url
= GURL("ws://www.google.com");
920 request_info
.load_flags
= 0;
922 SSLConfig ssl_config
;
923 StreamRequestWaiter waiter
;
924 WebSocketStreamCreateHelper create_helper
;
925 scoped_ptr
<HttpStreamRequest
> request(
926 session
->http_stream_factory_for_websocket()
927 ->RequestWebSocketHandshakeStream(request_info
,
934 waiter
.WaitForStream();
935 EXPECT_TRUE(waiter
.stream_done());
936 EXPECT_TRUE(NULL
== waiter
.stream());
937 ASSERT_TRUE(NULL
!= waiter
.websocket_stream());
938 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic
,
939 waiter
.websocket_stream()->type());
940 EXPECT_EQ(0, GetSocketPoolGroupCount(
941 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
942 EXPECT_EQ(0, GetSocketPoolGroupCount(
943 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
944 EXPECT_EQ(0, GetSocketPoolGroupCount(
945 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
946 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
949 TEST_P(HttpStreamFactoryTest
, RequestWebSocketBasicHandshakeStreamOverSSL
) {
950 SpdySessionDependencies
session_deps(
951 GetParam(), ProxyService::CreateDirect());
953 MockRead
mock_read(ASYNC
, OK
);
954 StaticSocketDataProvider
socket_data(&mock_read
, 1, NULL
, 0);
955 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
956 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
958 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
959 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl_socket_data
);
961 scoped_refptr
<HttpNetworkSession
> session(
962 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
964 // Now request a stream.
965 HttpRequestInfo request_info
;
966 request_info
.method
= "GET";
967 request_info
.url
= GURL("wss://www.google.com");
968 request_info
.load_flags
= 0;
970 SSLConfig ssl_config
;
971 StreamRequestWaiter waiter
;
972 WebSocketStreamCreateHelper create_helper
;
973 scoped_ptr
<HttpStreamRequest
> request(
974 session
->http_stream_factory_for_websocket()
975 ->RequestWebSocketHandshakeStream(request_info
,
982 waiter
.WaitForStream();
983 EXPECT_TRUE(waiter
.stream_done());
984 EXPECT_TRUE(NULL
== waiter
.stream());
985 ASSERT_TRUE(NULL
!= waiter
.websocket_stream());
986 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic
,
987 waiter
.websocket_stream()->type());
988 EXPECT_EQ(0, GetSocketPoolGroupCount(
989 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
990 EXPECT_EQ(0, GetSocketPoolGroupCount(
991 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
992 EXPECT_EQ(1, GetSocketPoolGroupCount(
993 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
994 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
997 TEST_P(HttpStreamFactoryTest
, RequestWebSocketBasicHandshakeStreamOverProxy
) {
998 SpdySessionDependencies
session_deps(
999 GetParam(), ProxyService::CreateFixed("myproxy:8888"));
1001 MockRead
read(SYNCHRONOUS
, "HTTP/1.0 200 Connection established\r\n\r\n");
1002 StaticSocketDataProvider
socket_data(&read
, 1, 0, 0);
1003 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
1004 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
1006 scoped_refptr
<HttpNetworkSession
> session(
1007 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
1009 // Now request a stream.
1010 HttpRequestInfo request_info
;
1011 request_info
.method
= "GET";
1012 request_info
.url
= GURL("ws://www.google.com");
1013 request_info
.load_flags
= 0;
1015 SSLConfig ssl_config
;
1016 StreamRequestWaiter waiter
;
1017 WebSocketStreamCreateHelper create_helper
;
1018 scoped_ptr
<HttpStreamRequest
> request(
1019 session
->http_stream_factory_for_websocket()
1020 ->RequestWebSocketHandshakeStream(request_info
,
1027 waiter
.WaitForStream();
1028 EXPECT_TRUE(waiter
.stream_done());
1029 EXPECT_TRUE(NULL
== waiter
.stream());
1030 ASSERT_TRUE(NULL
!= waiter
.websocket_stream());
1031 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic
,
1032 waiter
.websocket_stream()->type());
1033 EXPECT_EQ(0, GetSocketPoolGroupCount(
1034 session
->GetTransportSocketPool(
1035 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1036 EXPECT_EQ(0, GetSocketPoolGroupCount(
1037 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1038 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSocketPoolForHTTPProxy(
1039 HttpNetworkSession::NORMAL_SOCKET_POOL
,
1040 HostPortPair("myproxy", 8888))));
1041 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSocketPoolForSSLWithProxy(
1042 HttpNetworkSession::NORMAL_SOCKET_POOL
,
1043 HostPortPair("myproxy", 8888))));
1044 EXPECT_EQ(1, GetSocketPoolGroupCount(session
->GetSocketPoolForHTTPProxy(
1045 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
,
1046 HostPortPair("myproxy", 8888))));
1047 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSocketPoolForSSLWithProxy(
1048 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
,
1049 HostPortPair("myproxy", 8888))));
1050 EXPECT_FALSE(waiter
.used_proxy_info().is_direct());
1053 TEST_P(HttpStreamFactoryTest
, RequestSpdyHttpStream
) {
1054 SpdySessionDependencies
session_deps(GetParam(),
1055 ProxyService::CreateDirect());
1057 MockRead
mock_read(ASYNC
, OK
);
1058 DeterministicSocketData
socket_data(&mock_read
, 1, NULL
, 0);
1059 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
1060 session_deps
.deterministic_socket_factory
->AddSocketDataProvider(
1063 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
1064 ssl_socket_data
.SetNextProto(GetParam());
1065 session_deps
.deterministic_socket_factory
->AddSSLSocketDataProvider(
1068 HostPortPair
host_port_pair("www.google.com", 443);
1069 scoped_refptr
<HttpNetworkSession
>
1070 session(SpdySessionDependencies::SpdyCreateSessionDeterministic(
1073 // Now request a stream.
1074 HttpRequestInfo request_info
;
1075 request_info
.method
= "GET";
1076 request_info
.url
= GURL("https://www.google.com");
1077 request_info
.load_flags
= 0;
1079 SSLConfig ssl_config
;
1080 StreamRequestWaiter waiter
;
1081 scoped_ptr
<HttpStreamRequest
> request(
1082 session
->http_stream_factory()->RequestStream(
1089 waiter
.WaitForStream();
1090 EXPECT_TRUE(waiter
.stream_done());
1091 EXPECT_TRUE(NULL
== waiter
.websocket_stream());
1092 ASSERT_TRUE(NULL
!= waiter
.stream());
1093 EXPECT_TRUE(waiter
.stream()->IsSpdyHttpStream());
1094 EXPECT_EQ(1, GetSocketPoolGroupCount(
1095 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1096 EXPECT_EQ(1, GetSocketPoolGroupCount(
1097 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1098 EXPECT_EQ(0, GetSocketPoolGroupCount(
1099 session
->GetTransportSocketPool(
1100 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1101 EXPECT_EQ(0, GetSocketPoolGroupCount(
1102 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1103 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
1106 // TODO(ricea): This test can be removed once the new WebSocket stack supports
1107 // SPDY. Currently, even if we connect to a SPDY-supporting server, we need to
1109 TEST_P(HttpStreamFactoryTest
, RequestWebSocketSpdyHandshakeStreamButGetSSL
) {
1110 SpdySessionDependencies
session_deps(GetParam(),
1111 ProxyService::CreateDirect());
1113 MockRead
mock_read(SYNCHRONOUS
, ERR_IO_PENDING
);
1114 StaticSocketDataProvider
socket_data(&mock_read
, 1, NULL
, 0);
1115 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
1116 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
1118 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
1119 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl_socket_data
);
1121 HostPortPair
host_port_pair("www.google.com", 80);
1122 scoped_refptr
<HttpNetworkSession
>
1123 session(SpdySessionDependencies::SpdyCreateSession(&session_deps
));
1125 // Now request a stream.
1126 HttpRequestInfo request_info
;
1127 request_info
.method
= "GET";
1128 request_info
.url
= GURL("wss://www.google.com");
1129 request_info
.load_flags
= 0;
1131 SSLConfig ssl_config
;
1132 StreamRequestWaiter waiter1
;
1133 WebSocketStreamCreateHelper create_helper
;
1134 scoped_ptr
<HttpStreamRequest
> request1(
1135 session
->http_stream_factory_for_websocket()
1136 ->RequestWebSocketHandshakeStream(request_info
,
1143 waiter1
.WaitForStream();
1144 EXPECT_TRUE(waiter1
.stream_done());
1145 ASSERT_TRUE(NULL
!= waiter1
.websocket_stream());
1146 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic
,
1147 waiter1
.websocket_stream()->type());
1148 EXPECT_TRUE(NULL
== waiter1
.stream());
1150 EXPECT_EQ(0, GetSocketPoolGroupCount(
1151 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1152 EXPECT_EQ(0, GetSocketPoolGroupCount(
1153 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1154 EXPECT_EQ(1, GetSocketPoolGroupCount(
1155 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1156 EXPECT_TRUE(waiter1
.used_proxy_info().is_direct());
1159 // TODO(ricea): Re-enable once WebSocket-over-SPDY is implemented.
1160 TEST_P(HttpStreamFactoryTest
, DISABLED_RequestWebSocketSpdyHandshakeStream
) {
1161 SpdySessionDependencies
session_deps(GetParam(),
1162 ProxyService::CreateDirect());
1164 MockRead
mock_read(SYNCHRONOUS
, ERR_IO_PENDING
);
1165 StaticSocketDataProvider
socket_data(&mock_read
, 1, NULL
, 0);
1166 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
1167 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
1169 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
1170 ssl_socket_data
.SetNextProto(GetParam());
1171 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl_socket_data
);
1173 HostPortPair
host_port_pair("www.google.com", 80);
1174 scoped_refptr
<HttpNetworkSession
>
1175 session(SpdySessionDependencies::SpdyCreateSession(&session_deps
));
1177 // Now request a stream.
1178 HttpRequestInfo request_info
;
1179 request_info
.method
= "GET";
1180 request_info
.url
= GURL("wss://www.google.com");
1181 request_info
.load_flags
= 0;
1183 SSLConfig ssl_config
;
1184 StreamRequestWaiter waiter1
;
1185 WebSocketStreamCreateHelper create_helper
;
1186 scoped_ptr
<HttpStreamRequest
> request1(
1187 session
->http_stream_factory_for_websocket()
1188 ->RequestWebSocketHandshakeStream(request_info
,
1195 waiter1
.WaitForStream();
1196 EXPECT_TRUE(waiter1
.stream_done());
1197 ASSERT_TRUE(NULL
!= waiter1
.websocket_stream());
1198 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy
,
1199 waiter1
.websocket_stream()->type());
1200 EXPECT_TRUE(NULL
== waiter1
.stream());
1202 StreamRequestWaiter waiter2
;
1203 scoped_ptr
<HttpStreamRequest
> request2(
1204 session
->http_stream_factory_for_websocket()
1205 ->RequestWebSocketHandshakeStream(request_info
,
1212 waiter2
.WaitForStream();
1213 EXPECT_TRUE(waiter2
.stream_done());
1214 ASSERT_TRUE(NULL
!= waiter2
.websocket_stream());
1215 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy
,
1216 waiter2
.websocket_stream()->type());
1217 EXPECT_TRUE(NULL
== waiter2
.stream());
1218 EXPECT_NE(waiter2
.websocket_stream(), waiter1
.websocket_stream());
1219 EXPECT_EQ(static_cast<WebSocketSpdyHandshakeStream
*>(
1220 waiter2
.websocket_stream())->spdy_session(),
1221 static_cast<WebSocketSpdyHandshakeStream
*>(
1222 waiter1
.websocket_stream())->spdy_session());
1224 EXPECT_EQ(0, GetSocketPoolGroupCount(
1225 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1226 EXPECT_EQ(0, GetSocketPoolGroupCount(
1227 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1228 EXPECT_EQ(1, GetSocketPoolGroupCount(
1229 session
->GetTransportSocketPool(
1230 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1231 EXPECT_EQ(1, GetSocketPoolGroupCount(
1232 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1233 EXPECT_TRUE(waiter1
.used_proxy_info().is_direct());
1236 // TODO(ricea): Re-enable once WebSocket over SPDY is implemented.
1237 TEST_P(HttpStreamFactoryTest
, DISABLED_OrphanedWebSocketStream
) {
1238 SpdySessionDependencies
session_deps(GetParam(),
1239 ProxyService::CreateDirect());
1240 session_deps
.use_alternate_protocols
= true;
1242 MockRead
mock_read(ASYNC
, OK
);
1243 DeterministicSocketData
socket_data(&mock_read
, 1, NULL
, 0);
1244 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
1245 session_deps
.deterministic_socket_factory
->AddSocketDataProvider(
1248 MockRead
mock_read2(ASYNC
, OK
);
1249 DeterministicSocketData
socket_data2(&mock_read2
, 1, NULL
, 0);
1250 socket_data2
.set_connect_data(MockConnect(ASYNC
, ERR_IO_PENDING
));
1251 session_deps
.deterministic_socket_factory
->AddSocketDataProvider(
1254 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
1255 ssl_socket_data
.SetNextProto(GetParam());
1256 session_deps
.deterministic_socket_factory
->AddSSLSocketDataProvider(
1259 scoped_refptr
<HttpNetworkSession
>
1260 session(SpdySessionDependencies::SpdyCreateSessionDeterministic(
1263 // Now request a stream.
1264 HttpRequestInfo request_info
;
1265 request_info
.method
= "GET";
1266 request_info
.url
= GURL("ws://www.google.com:8888");
1267 request_info
.load_flags
= 0;
1269 session
->http_server_properties()->SetAlternateProtocol(
1270 HostPortPair("www.google.com", 8888),
1275 SSLConfig ssl_config
;
1276 StreamRequestWaiter waiter
;
1277 WebSocketStreamCreateHelper create_helper
;
1278 scoped_ptr
<HttpStreamRequest
> request(
1279 session
->http_stream_factory_for_websocket()
1280 ->RequestWebSocketHandshakeStream(request_info
,
1287 waiter
.WaitForStream();
1288 EXPECT_TRUE(waiter
.stream_done());
1289 EXPECT_TRUE(NULL
== waiter
.stream());
1290 ASSERT_TRUE(NULL
!= waiter
.websocket_stream());
1291 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy
,
1292 waiter
.websocket_stream()->type());
1294 // Make sure that there was an alternative connection
1295 // which consumes extra connections.
1296 EXPECT_EQ(0, GetSocketPoolGroupCount(
1297 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1298 EXPECT_EQ(0, GetSocketPoolGroupCount(
1299 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1300 EXPECT_EQ(2, GetSocketPoolGroupCount(
1301 session
->GetTransportSocketPool(
1302 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1303 EXPECT_EQ(1, GetSocketPoolGroupCount(
1304 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1305 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
1307 // Make sure there is no orphaned job. it is already canceled.
1308 ASSERT_EQ(0u, static_cast<HttpStreamFactoryImpl
*>(
1309 session
->http_stream_factory_for_websocket())->num_orphaned_jobs());