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"
12 #include "base/basictypes.h"
13 #include "base/compiler_specific.h"
14 #include "net/base/port_util.h"
15 #include "net/base/test_completion_callback.h"
16 #include "net/cert/mock_cert_verifier.h"
17 #include "net/dns/mock_host_resolver.h"
18 #include "net/http/http_auth_handler_factory.h"
19 #include "net/http/http_network_session.h"
20 #include "net/http/http_network_session_peer.h"
21 #include "net/http/http_network_transaction.h"
22 #include "net/http/http_request_info.h"
23 #include "net/http/http_server_properties.h"
24 #include "net/http/http_server_properties_impl.h"
25 #include "net/http/http_stream.h"
26 #include "net/http/transport_security_state.h"
27 #include "net/log/net_log.h"
28 #include "net/proxy/proxy_info.h"
29 #include "net/proxy/proxy_service.h"
30 #include "net/socket/client_socket_handle.h"
31 #include "net/socket/mock_client_socket_pool_manager.h"
32 #include "net/socket/next_proto.h"
33 #include "net/socket/socket_test_util.h"
34 #include "net/spdy/spdy_session.h"
35 #include "net/spdy/spdy_session_pool.h"
36 #include "net/spdy/spdy_test_util_common.h"
37 #include "net/ssl/ssl_config_service.h"
38 #include "net/ssl/ssl_config_service_defaults.h"
39 // This file can be included from net/http even though
40 // it is in net/websockets because it doesn't
41 // introduce any link dependency to net/websockets.
42 #include "net/websockets/websocket_handshake_stream_base.h"
43 #include "testing/gtest/include/gtest/gtest.h"
49 class MockWebSocketHandshakeStream
: public WebSocketHandshakeStreamBase
{
56 explicit MockWebSocketHandshakeStream(StreamType type
) : type_(type
) {}
58 ~MockWebSocketHandshakeStream() override
{}
60 StreamType
type() const {
65 int InitializeStream(const HttpRequestInfo
* request_info
,
66 RequestPriority priority
,
67 const BoundNetLog
& net_log
,
68 const CompletionCallback
& callback
) override
{
69 return ERR_IO_PENDING
;
71 int SendRequest(const HttpRequestHeaders
& request_headers
,
72 HttpResponseInfo
* response
,
73 const CompletionCallback
& callback
) override
{
74 return ERR_IO_PENDING
;
76 int ReadResponseHeaders(const CompletionCallback
& callback
) override
{
77 return ERR_IO_PENDING
;
79 int ReadResponseBody(IOBuffer
* buf
,
81 const CompletionCallback
& callback
) override
{
82 return ERR_IO_PENDING
;
84 void Close(bool not_reusable
) override
{}
85 bool IsResponseBodyComplete() const override
{ return false; }
86 bool IsConnectionReused() const override
{ return false; }
87 void SetConnectionReused() override
{}
88 bool CanReuseConnection() const override
{ return false; }
89 int64
GetTotalReceivedBytes() const override
{ return 0; }
90 int64_t GetTotalSentBytes() const override
{ return 0; }
91 bool GetLoadTimingInfo(LoadTimingInfo
* load_timing_info
) const override
{
94 void GetSSLInfo(SSLInfo
* ssl_info
) override
{}
95 void GetSSLCertRequestInfo(SSLCertRequestInfo
* cert_request_info
) override
{}
96 void Drain(HttpNetworkSession
* session
) override
{}
97 void SetPriority(RequestPriority priority
) override
{}
98 UploadProgress
GetUploadProgress() const override
{ return UploadProgress(); }
99 HttpStream
* RenewStreamForAuth() override
{ return nullptr; }
101 scoped_ptr
<WebSocketStream
> Upgrade() override
{
102 return scoped_ptr
<WebSocketStream
>();
106 const StreamType type_
;
109 // HttpStreamFactoryImpl subclass that can wait until a preconnect is complete.
110 class MockHttpStreamFactoryImplForPreconnect
: public HttpStreamFactoryImpl
{
112 MockHttpStreamFactoryImplForPreconnect(HttpNetworkSession
* session
,
114 : HttpStreamFactoryImpl(session
, for_websockets
),
115 preconnect_done_(false),
116 waiting_for_preconnect_(false) {}
119 void WaitForPreconnects() {
120 while (!preconnect_done_
) {
121 waiting_for_preconnect_
= true;
122 base::MessageLoop::current()->Run();
123 waiting_for_preconnect_
= false;
128 // HttpStreamFactoryImpl methods.
129 void OnPreconnectsCompleteInternal() override
{
130 preconnect_done_
= true;
131 if (waiting_for_preconnect_
)
132 base::MessageLoop::current()->Quit();
135 bool preconnect_done_
;
136 bool waiting_for_preconnect_
;
139 class StreamRequestWaiter
: public HttpStreamRequest::Delegate
{
141 StreamRequestWaiter()
142 : waiting_for_stream_(false),
143 stream_done_(false) {}
145 // HttpStreamRequest::Delegate
147 void OnStreamReady(const SSLConfig
& used_ssl_config
,
148 const ProxyInfo
& used_proxy_info
,
149 HttpStream
* stream
) override
{
151 if (waiting_for_stream_
)
152 base::MessageLoop::current()->Quit();
153 stream_
.reset(stream
);
154 used_ssl_config_
= used_ssl_config
;
155 used_proxy_info_
= used_proxy_info
;
158 void OnWebSocketHandshakeStreamReady(
159 const SSLConfig
& used_ssl_config
,
160 const ProxyInfo
& used_proxy_info
,
161 WebSocketHandshakeStreamBase
* stream
) override
{
163 if (waiting_for_stream_
)
164 base::MessageLoop::current()->Quit();
165 websocket_stream_
.reset(stream
);
166 used_ssl_config_
= used_ssl_config
;
167 used_proxy_info_
= used_proxy_info
;
170 void OnStreamFailed(int status
,
171 const SSLConfig
& used_ssl_config
,
172 SSLFailureState ssl_failure_state
) override
{}
174 void OnCertificateError(int status
,
175 const SSLConfig
& used_ssl_config
,
176 const SSLInfo
& ssl_info
) override
{}
178 void OnNeedsProxyAuth(const HttpResponseInfo
& proxy_response
,
179 const SSLConfig
& used_ssl_config
,
180 const ProxyInfo
& used_proxy_info
,
181 HttpAuthController
* auth_controller
) override
{}
183 void OnNeedsClientAuth(const SSLConfig
& used_ssl_config
,
184 SSLCertRequestInfo
* cert_info
) override
{}
186 void OnHttpsProxyTunnelResponse(const HttpResponseInfo
& response_info
,
187 const SSLConfig
& used_ssl_config
,
188 const ProxyInfo
& used_proxy_info
,
189 HttpStream
* 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 HttpStream
* 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
<HttpStream
> 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 ~WebSocketSpdyHandshakeStream() override
{}
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 ~WebSocketBasicHandshakeStream() override
{
251 connection_
->socket()->Disconnect();
254 ClientSocketHandle
* connection() { return connection_
.get(); }
257 scoped_ptr
<ClientSocketHandle
> connection_
;
260 class WebSocketStreamCreateHelper
261 : public WebSocketHandshakeStreamBase::CreateHelper
{
263 ~WebSocketStreamCreateHelper() override
{}
265 WebSocketHandshakeStreamBase
* CreateBasicStream(
266 scoped_ptr
<ClientSocketHandle
> connection
,
267 bool using_proxy
) override
{
268 return new WebSocketBasicHandshakeStream(connection
.Pass());
271 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(num_streams
, request
,
306 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 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 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 void CancelRequest(const std::string
& group_name
,
345 ClientSocketHandle
* handle
) override
{
348 void ReleaseSocket(const std::string
& group_name
,
349 scoped_ptr
<StreamSocket
> socket
,
353 void CloseIdleSockets() override
{ ADD_FAILURE(); }
354 int IdleSocketCount() const override
{
358 int IdleSocketCountInGroup(const std::string
& group_name
) const override
{
362 LoadState
GetLoadState(const std::string
& group_name
,
363 const ClientSocketHandle
* handle
) const override
{
365 return LOAD_STATE_IDLE
;
367 base::TimeDelta
ConnectionTimeout() const override
{
368 return base::TimeDelta();
372 int last_num_streams_
;
375 typedef CapturePreconnectsSocketPool
<TransportClientSocketPool
>
376 CapturePreconnectsTransportSocketPool
;
377 typedef CapturePreconnectsSocketPool
<HttpProxyClientSocketPool
>
378 CapturePreconnectsHttpProxySocketPool
;
379 typedef CapturePreconnectsSocketPool
<SOCKSClientSocketPool
>
380 CapturePreconnectsSOCKSSocketPool
;
381 typedef CapturePreconnectsSocketPool
<SSLClientSocketPool
>
382 CapturePreconnectsSSLSocketPool
;
384 template <typename ParentPool
>
385 CapturePreconnectsSocketPool
<ParentPool
>::CapturePreconnectsSocketPool(
386 HostResolver
* host_resolver
,
387 CertVerifier
* /* cert_verifier */)
388 : ParentPool(0, 0, host_resolver
, nullptr, nullptr), last_num_streams_(-1) {
392 CapturePreconnectsHttpProxySocketPool::CapturePreconnectsSocketPool(
393 HostResolver
* /* host_resolver */,
394 CertVerifier
* /* cert_verifier */)
395 : HttpProxyClientSocketPool(0, 0, nullptr, nullptr, nullptr),
396 last_num_streams_(-1) {
400 CapturePreconnectsSSLSocketPool::CapturePreconnectsSocketPool(
401 HostResolver
* /* host_resolver */,
402 CertVerifier
* cert_verifier
)
403 : SSLClientSocketPool(0,
406 nullptr, // channel_id_store
407 nullptr, // transport_security_state
408 nullptr, // cert_transparency_verifier
409 nullptr, // cert_policy_enforcer
410 std::string(), // ssl_session_cache_shard
411 nullptr, // deterministic_socket_factory
412 nullptr, // transport_socket_pool
415 nullptr, // ssl_config_service
417 last_num_streams_(-1) {
420 class HttpStreamFactoryTest
: public ::testing::Test
,
421 public ::testing::WithParamInterface
<NextProto
> {
424 INSTANTIATE_TEST_CASE_P(NextProto
,
425 HttpStreamFactoryTest
,
426 testing::Values(kProtoSPDY31
,
429 TEST_P(HttpStreamFactoryTest
, PreconnectDirect
) {
430 for (size_t i
= 0; i
< arraysize(kTests
); ++i
) {
431 SpdySessionDependencies
session_deps(
432 GetParam(), ProxyService::CreateDirect());
433 scoped_refptr
<HttpNetworkSession
> session(
434 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
435 HttpNetworkSessionPeer
peer(session
);
436 CapturePreconnectsTransportSocketPool
* transport_conn_pool
=
437 new CapturePreconnectsTransportSocketPool(
438 session_deps
.host_resolver
.get(),
439 session_deps
.cert_verifier
.get());
440 CapturePreconnectsSSLSocketPool
* ssl_conn_pool
=
441 new CapturePreconnectsSSLSocketPool(
442 session_deps
.host_resolver
.get(),
443 session_deps
.cert_verifier
.get());
444 scoped_ptr
<MockClientSocketPoolManager
> mock_pool_manager(
445 new MockClientSocketPoolManager
);
446 mock_pool_manager
->SetTransportSocketPool(transport_conn_pool
);
447 mock_pool_manager
->SetSSLSocketPool(ssl_conn_pool
);
448 peer
.SetClientSocketPoolManager(mock_pool_manager
.Pass());
449 PreconnectHelper(kTests
[i
], session
.get());
451 EXPECT_EQ(kTests
[i
].num_streams
, ssl_conn_pool
->last_num_streams());
453 EXPECT_EQ(kTests
[i
].num_streams
, transport_conn_pool
->last_num_streams());
457 TEST_P(HttpStreamFactoryTest
, PreconnectHttpProxy
) {
458 for (size_t i
= 0; i
< arraysize(kTests
); ++i
) {
459 SpdySessionDependencies
session_deps(
460 GetParam(), ProxyService::CreateFixed("http_proxy"));
461 scoped_refptr
<HttpNetworkSession
> session(
462 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
463 HttpNetworkSessionPeer
peer(session
);
464 HostPortPair
proxy_host("http_proxy", 80);
465 CapturePreconnectsHttpProxySocketPool
* http_proxy_pool
=
466 new CapturePreconnectsHttpProxySocketPool(
467 session_deps
.host_resolver
.get(),
468 session_deps
.cert_verifier
.get());
469 CapturePreconnectsSSLSocketPool
* ssl_conn_pool
=
470 new CapturePreconnectsSSLSocketPool(
471 session_deps
.host_resolver
.get(),
472 session_deps
.cert_verifier
.get());
473 scoped_ptr
<MockClientSocketPoolManager
> mock_pool_manager(
474 new MockClientSocketPoolManager
);
475 mock_pool_manager
->SetSocketPoolForHTTPProxy(proxy_host
, http_proxy_pool
);
476 mock_pool_manager
->SetSocketPoolForSSLWithProxy(proxy_host
, ssl_conn_pool
);
477 peer
.SetClientSocketPoolManager(mock_pool_manager
.Pass());
478 PreconnectHelper(kTests
[i
], session
.get());
480 EXPECT_EQ(kTests
[i
].num_streams
, ssl_conn_pool
->last_num_streams());
482 EXPECT_EQ(kTests
[i
].num_streams
, http_proxy_pool
->last_num_streams());
486 TEST_P(HttpStreamFactoryTest
, PreconnectSocksProxy
) {
487 for (size_t i
= 0; i
< arraysize(kTests
); ++i
) {
488 SpdySessionDependencies
session_deps(
489 GetParam(), ProxyService::CreateFixed("socks4://socks_proxy:1080"));
490 scoped_refptr
<HttpNetworkSession
> session(
491 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
492 HttpNetworkSessionPeer
peer(session
);
493 HostPortPair
proxy_host("socks_proxy", 1080);
494 CapturePreconnectsSOCKSSocketPool
* socks_proxy_pool
=
495 new CapturePreconnectsSOCKSSocketPool(
496 session_deps
.host_resolver
.get(),
497 session_deps
.cert_verifier
.get());
498 CapturePreconnectsSSLSocketPool
* ssl_conn_pool
=
499 new CapturePreconnectsSSLSocketPool(
500 session_deps
.host_resolver
.get(),
501 session_deps
.cert_verifier
.get());
502 scoped_ptr
<MockClientSocketPoolManager
> mock_pool_manager(
503 new MockClientSocketPoolManager
);
504 mock_pool_manager
->SetSocketPoolForSOCKSProxy(proxy_host
, socks_proxy_pool
);
505 mock_pool_manager
->SetSocketPoolForSSLWithProxy(proxy_host
, ssl_conn_pool
);
506 peer
.SetClientSocketPoolManager(mock_pool_manager
.Pass());
507 PreconnectHelper(kTests
[i
], session
.get());
509 EXPECT_EQ(kTests
[i
].num_streams
, ssl_conn_pool
->last_num_streams());
511 EXPECT_EQ(kTests
[i
].num_streams
, socks_proxy_pool
->last_num_streams());
515 TEST_P(HttpStreamFactoryTest
, PreconnectDirectWithExistingSpdySession
) {
516 for (size_t i
= 0; i
< arraysize(kTests
); ++i
) {
517 SpdySessionDependencies
session_deps(
518 GetParam(), ProxyService::CreateDirect());
519 scoped_refptr
<HttpNetworkSession
> session(
520 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
521 HttpNetworkSessionPeer
peer(session
);
523 // Put a SpdySession in the pool.
524 HostPortPair
host_port_pair("www.google.com", 443);
525 SpdySessionKey
key(host_port_pair
, ProxyServer::Direct(),
526 PRIVACY_MODE_DISABLED
);
527 ignore_result(CreateFakeSpdySession(session
->spdy_session_pool(), key
));
529 CapturePreconnectsTransportSocketPool
* transport_conn_pool
=
530 new CapturePreconnectsTransportSocketPool(
531 session_deps
.host_resolver
.get(),
532 session_deps
.cert_verifier
.get());
533 CapturePreconnectsSSLSocketPool
* ssl_conn_pool
=
534 new CapturePreconnectsSSLSocketPool(
535 session_deps
.host_resolver
.get(),
536 session_deps
.cert_verifier
.get());
537 scoped_ptr
<MockClientSocketPoolManager
> mock_pool_manager(
538 new MockClientSocketPoolManager
);
539 mock_pool_manager
->SetTransportSocketPool(transport_conn_pool
);
540 mock_pool_manager
->SetSSLSocketPool(ssl_conn_pool
);
541 peer
.SetClientSocketPoolManager(mock_pool_manager
.Pass());
542 PreconnectHelper(kTests
[i
], session
.get());
543 // We shouldn't be preconnecting if we have an existing session, which is
544 // the case for https://www.google.com.
546 EXPECT_EQ(-1, ssl_conn_pool
->last_num_streams());
548 EXPECT_EQ(kTests
[i
].num_streams
,
549 transport_conn_pool
->last_num_streams());
553 // Verify that preconnects to unsafe ports are cancelled before they reach
555 TEST_P(HttpStreamFactoryTest
, PreconnectUnsafePort
) {
556 ASSERT_FALSE(IsPortAllowedForScheme(7, "http"));
558 SpdySessionDependencies
session_deps(
559 GetParam(), ProxyService::CreateDirect());
560 scoped_refptr
<HttpNetworkSession
> session(
561 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
562 HttpNetworkSessionPeer
peer(session
);
563 CapturePreconnectsTransportSocketPool
* transport_conn_pool
=
564 new CapturePreconnectsTransportSocketPool(
565 session_deps
.host_resolver
.get(),
566 session_deps
.cert_verifier
.get());
567 scoped_ptr
<MockClientSocketPoolManager
> mock_pool_manager(
568 new MockClientSocketPoolManager
);
569 mock_pool_manager
->SetTransportSocketPool(transport_conn_pool
);
570 peer
.SetClientSocketPoolManager(mock_pool_manager
.Pass());
572 PreconnectHelperForURL(1, GURL("http://www.google.com:7"), session
.get());
573 EXPECT_EQ(-1, transport_conn_pool
->last_num_streams());
576 TEST_P(HttpStreamFactoryTest
, JobNotifiesProxy
) {
577 const char* kProxyString
= "PROXY bad:99; PROXY maybe:80; DIRECT";
578 SpdySessionDependencies
session_deps(
579 GetParam(), ProxyService::CreateFixedFromPacResult(kProxyString
));
581 // First connection attempt fails
582 StaticSocketDataProvider socket_data1
;
583 socket_data1
.set_connect_data(MockConnect(ASYNC
, ERR_ADDRESS_UNREACHABLE
));
584 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data1
);
586 // Second connection attempt succeeds
587 StaticSocketDataProvider socket_data2
;
588 socket_data2
.set_connect_data(MockConnect(ASYNC
, OK
));
589 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data2
);
591 scoped_refptr
<HttpNetworkSession
> session(
592 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
594 // Now request a stream. It should succeed using the second proxy in the
596 HttpRequestInfo request_info
;
597 request_info
.method
= "GET";
598 request_info
.url
= GURL("http://www.google.com");
600 SSLConfig ssl_config
;
601 StreamRequestWaiter waiter
;
602 scoped_ptr
<HttpStreamRequest
> request(
603 session
->http_stream_factory()->RequestStream(
604 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
,
605 &waiter
, BoundNetLog()));
606 waiter
.WaitForStream();
608 // The proxy that failed should now be known to the proxy_service as bad.
609 const ProxyRetryInfoMap
& retry_info
=
610 session
->proxy_service()->proxy_retry_info();
611 EXPECT_EQ(1u, retry_info
.size());
612 ProxyRetryInfoMap::const_iterator iter
= retry_info
.find("bad:99");
613 EXPECT_TRUE(iter
!= retry_info
.end());
616 TEST_P(HttpStreamFactoryTest
, UnreachableQuicProxyMarkedAsBad
) {
617 const int mock_error
[] = {ERR_QUIC_PROTOCOL_ERROR
, ERR_QUIC_HANDSHAKE_FAILED
,
619 for (size_t i
= 0; i
< arraysize(mock_error
); ++i
) {
620 scoped_ptr
<ProxyService
> proxy_service
;
622 ProxyService::CreateFixedFromPacResult("QUIC bad:99; DIRECT");
624 HttpNetworkSession::Params params
;
625 params
.enable_quic
= true;
626 params
.enable_quic_for_proxies
= true;
627 scoped_refptr
<SSLConfigServiceDefaults
> ssl_config_service(
628 new SSLConfigServiceDefaults
);
629 HttpServerPropertiesImpl http_server_properties
;
630 MockClientSocketFactory socket_factory
;
631 params
.client_socket_factory
= &socket_factory
;
632 MockHostResolver host_resolver
;
633 params
.host_resolver
= &host_resolver
;
634 TransportSecurityState transport_security_state
;
635 params
.transport_security_state
= &transport_security_state
;
636 params
.proxy_service
= proxy_service
.get();
637 params
.ssl_config_service
= ssl_config_service
.get();
638 params
.http_server_properties
= http_server_properties
.GetWeakPtr();
640 scoped_refptr
<HttpNetworkSession
> session
;
641 session
= new HttpNetworkSession(params
);
642 session
->quic_stream_factory()->set_require_confirmation(false);
644 StaticSocketDataProvider socket_data1
;
645 socket_data1
.set_connect_data(MockConnect(ASYNC
, mock_error
[i
]));
646 socket_factory
.AddSocketDataProvider(&socket_data1
);
648 // Second connection attempt succeeds.
649 StaticSocketDataProvider socket_data2
;
650 socket_data2
.set_connect_data(MockConnect(ASYNC
, OK
));
651 socket_factory
.AddSocketDataProvider(&socket_data2
);
653 // Now request a stream. It should succeed using the second proxy in the
655 HttpRequestInfo request_info
;
656 request_info
.method
= "GET";
657 request_info
.url
= GURL("http://www.google.com");
659 SSLConfig ssl_config
;
660 StreamRequestWaiter waiter
;
661 scoped_ptr
<HttpStreamRequest
> request(
662 session
->http_stream_factory()->RequestStream(
663 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
, &waiter
,
665 waiter
.WaitForStream();
667 // The proxy that failed should now be known to the proxy_service as bad.
668 const ProxyRetryInfoMap
& retry_info
=
669 session
->proxy_service()->proxy_retry_info();
670 EXPECT_EQ(1u, retry_info
.size()) << mock_error
[i
];
671 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
673 ProxyRetryInfoMap::const_iterator iter
= retry_info
.find("quic://bad:99");
674 EXPECT_TRUE(iter
!= retry_info
.end()) << mock_error
[i
];
680 TEST_P(HttpStreamFactoryTest
, QuicLossyProxyMarkedAsBad
) {
682 scoped_ptr
<ProxyService
> proxy_service
;
683 proxy_service
= ProxyService::CreateFixedFromPacResult("QUIC bad:99; DIRECT");
685 HttpNetworkSession::Params params
;
686 params
.enable_quic
= true;
687 params
.enable_quic_for_proxies
= true;
688 scoped_refptr
<SSLConfigServiceDefaults
> ssl_config_service(
689 new SSLConfigServiceDefaults
);
690 HttpServerPropertiesImpl http_server_properties
;
691 MockClientSocketFactory socket_factory
;
692 params
.client_socket_factory
= &socket_factory
;
693 MockHostResolver host_resolver
;
694 params
.host_resolver
= &host_resolver
;
695 TransportSecurityState transport_security_state
;
696 params
.transport_security_state
= &transport_security_state
;
697 params
.proxy_service
= proxy_service
.get();
698 params
.ssl_config_service
= ssl_config_service
.get();
699 params
.http_server_properties
= http_server_properties
.GetWeakPtr();
700 params
.quic_max_number_of_lossy_connections
= 2;
702 scoped_refptr
<HttpNetworkSession
> session
;
703 session
= new HttpNetworkSession(params
);
704 session
->quic_stream_factory()->set_require_confirmation(false);
706 session
->quic_stream_factory()->number_of_lossy_connections_
[99] =
707 params
.quic_max_number_of_lossy_connections
;
709 StaticSocketDataProvider socket_data2
;
710 socket_data2
.set_connect_data(MockConnect(ASYNC
, OK
));
711 socket_factory
.AddSocketDataProvider(&socket_data2
);
713 // Now request a stream. It should succeed using the second proxy in the
715 HttpRequestInfo request_info
;
716 request_info
.method
= "GET";
717 request_info
.url
= GURL("http://www.google.com");
719 SSLConfig ssl_config
;
720 StreamRequestWaiter waiter
;
721 scoped_ptr
<HttpStreamRequest
> request(
722 session
->http_stream_factory()->RequestStream(
723 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
, &waiter
,
725 waiter
.WaitForStream();
727 // The proxy that failed should now be known to the proxy_service as bad.
728 const ProxyRetryInfoMap
& retry_info
=
729 session
->proxy_service()->proxy_retry_info();
730 EXPECT_EQ(1u, retry_info
.size());
731 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
733 ProxyRetryInfoMap::const_iterator iter
= retry_info
.find("quic://bad:99");
734 EXPECT_TRUE(iter
!= retry_info
.end());
739 TEST_P(HttpStreamFactoryTest
, PrivacyModeDisablesChannelId
) {
740 SpdySessionDependencies
session_deps(
741 GetParam(), ProxyService::CreateDirect());
743 StaticSocketDataProvider socket_data
;
744 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
745 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
747 SSLSocketDataProvider
ssl(ASYNC
, OK
);
748 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl
);
750 scoped_refptr
<HttpNetworkSession
> session(
751 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
753 // Set an existing SpdySession in the pool.
754 HostPortPair
host_port_pair("www.google.com", 443);
755 SpdySessionKey
key(host_port_pair
, ProxyServer::Direct(),
756 PRIVACY_MODE_ENABLED
);
758 HttpRequestInfo request_info
;
759 request_info
.method
= "GET";
760 request_info
.url
= GURL("https://www.google.com");
761 request_info
.load_flags
= 0;
762 request_info
.privacy_mode
= PRIVACY_MODE_DISABLED
;
764 SSLConfig ssl_config
;
765 StreamRequestWaiter waiter
;
766 scoped_ptr
<HttpStreamRequest
> request(
767 session
->http_stream_factory()->RequestStream(
768 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
,
769 &waiter
, BoundNetLog()));
770 waiter
.WaitForStream();
772 // The stream shouldn't come from spdy as we are using different privacy mode
773 EXPECT_FALSE(request
->using_spdy());
775 SSLConfig used_ssl_config
= waiter
.used_ssl_config();
776 EXPECT_EQ(used_ssl_config
.channel_id_enabled
, ssl_config
.channel_id_enabled
);
781 // Return count of distinct groups in given socket pool.
782 int GetSocketPoolGroupCount(ClientSocketPool
* pool
) {
784 scoped_ptr
<base::DictionaryValue
> dict(pool
->GetInfoAsValue("", "", false));
785 EXPECT_TRUE(dict
!= nullptr);
786 base::DictionaryValue
* groups
= nullptr;
787 if (dict
->GetDictionary("groups", &groups
) && (groups
!= nullptr)) {
788 count
= static_cast<int>(groups
->size());
793 // Return count of distinct spdy sessions.
794 int GetSpdySessionCount(HttpNetworkSession
* session
) {
795 scoped_ptr
<base::Value
> value(
796 session
->spdy_session_pool()->SpdySessionPoolInfoToValue());
797 base::ListValue
* session_list
;
798 if (!value
|| !value
->GetAsList(&session_list
))
800 return session_list
->GetSize();
805 TEST_P(HttpStreamFactoryTest
, PrivacyModeUsesDifferentSocketPoolGroup
) {
806 SpdySessionDependencies
session_deps(
807 GetParam(), ProxyService::CreateDirect());
809 StaticSocketDataProvider socket_data
;
810 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
811 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
813 SSLSocketDataProvider
ssl(ASYNC
, OK
);
814 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl
);
816 scoped_refptr
<HttpNetworkSession
> session(
817 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
818 SSLClientSocketPool
* ssl_pool
= session
->GetSSLSocketPool(
819 HttpNetworkSession::NORMAL_SOCKET_POOL
);
821 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool
), 0);
823 HttpRequestInfo request_info
;
824 request_info
.method
= "GET";
825 request_info
.url
= GURL("https://www.google.com");
826 request_info
.load_flags
= 0;
827 request_info
.privacy_mode
= PRIVACY_MODE_DISABLED
;
829 SSLConfig ssl_config
;
830 StreamRequestWaiter waiter
;
832 scoped_ptr
<HttpStreamRequest
> request1(
833 session
->http_stream_factory()->RequestStream(
834 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
,
835 &waiter
, BoundNetLog()));
836 waiter
.WaitForStream();
838 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool
), 1);
840 scoped_ptr
<HttpStreamRequest
> request2(
841 session
->http_stream_factory()->RequestStream(
842 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
,
843 &waiter
, BoundNetLog()));
844 waiter
.WaitForStream();
846 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool
), 1);
848 request_info
.privacy_mode
= PRIVACY_MODE_ENABLED
;
849 scoped_ptr
<HttpStreamRequest
> request3(
850 session
->http_stream_factory()->RequestStream(
851 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
,
852 &waiter
, BoundNetLog()));
853 waiter
.WaitForStream();
855 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool
), 2);
858 TEST_P(HttpStreamFactoryTest
, GetLoadState
) {
859 SpdySessionDependencies
session_deps(
860 GetParam(), ProxyService::CreateDirect());
862 StaticSocketDataProvider socket_data
;
863 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
864 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
866 scoped_refptr
<HttpNetworkSession
> session(
867 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
869 HttpRequestInfo request_info
;
870 request_info
.method
= "GET";
871 request_info
.url
= GURL("http://www.google.com");
873 SSLConfig ssl_config
;
874 StreamRequestWaiter waiter
;
875 scoped_ptr
<HttpStreamRequest
> request(
876 session
->http_stream_factory()->RequestStream(
877 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
,
878 &waiter
, BoundNetLog()));
880 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST
, request
->GetLoadState());
882 waiter
.WaitForStream();
885 TEST_P(HttpStreamFactoryTest
, RequestHttpStream
) {
886 SpdySessionDependencies
session_deps(
887 GetParam(), ProxyService::CreateDirect());
889 StaticSocketDataProvider socket_data
;
890 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
891 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
893 scoped_refptr
<HttpNetworkSession
> session(
894 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
896 // Now request a stream. It should succeed using the second proxy in the
898 HttpRequestInfo request_info
;
899 request_info
.method
= "GET";
900 request_info
.url
= GURL("http://www.google.com");
901 request_info
.load_flags
= 0;
903 SSLConfig ssl_config
;
904 StreamRequestWaiter waiter
;
905 scoped_ptr
<HttpStreamRequest
> request(
906 session
->http_stream_factory()->RequestStream(
913 waiter
.WaitForStream();
914 EXPECT_TRUE(waiter
.stream_done());
915 ASSERT_TRUE(nullptr != waiter
.stream());
916 EXPECT_TRUE(nullptr == waiter
.websocket_stream());
918 EXPECT_EQ(0, GetSpdySessionCount(session
.get()));
919 EXPECT_EQ(1, GetSocketPoolGroupCount(
920 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
921 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSSLSocketPool(
922 HttpNetworkSession::NORMAL_SOCKET_POOL
)));
923 EXPECT_EQ(0, GetSocketPoolGroupCount(
924 session
->GetTransportSocketPool(
925 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
926 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSSLSocketPool(
927 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
928 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
931 TEST_P(HttpStreamFactoryTest
, RequestHttpStreamOverSSL
) {
932 SpdySessionDependencies
session_deps(
933 GetParam(), ProxyService::CreateDirect());
935 MockRead
mock_read(ASYNC
, OK
);
936 StaticSocketDataProvider
socket_data(&mock_read
, 1, nullptr, 0);
937 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
938 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
940 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
941 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl_socket_data
);
943 scoped_refptr
<HttpNetworkSession
> session(
944 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
946 // Now request a stream.
947 HttpRequestInfo request_info
;
948 request_info
.method
= "GET";
949 request_info
.url
= GURL("https://www.google.com");
950 request_info
.load_flags
= 0;
952 SSLConfig ssl_config
;
953 StreamRequestWaiter waiter
;
954 scoped_ptr
<HttpStreamRequest
> request(
955 session
->http_stream_factory()->RequestStream(
962 waiter
.WaitForStream();
963 EXPECT_TRUE(waiter
.stream_done());
964 ASSERT_TRUE(nullptr != waiter
.stream());
965 EXPECT_TRUE(nullptr == waiter
.websocket_stream());
967 EXPECT_EQ(0, GetSpdySessionCount(session
.get()));
968 EXPECT_EQ(1, GetSocketPoolGroupCount(
969 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
970 EXPECT_EQ(1, GetSocketPoolGroupCount(
971 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
972 EXPECT_EQ(0, GetSocketPoolGroupCount(
973 session
->GetTransportSocketPool(
974 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
975 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSSLSocketPool(
976 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
977 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
980 TEST_P(HttpStreamFactoryTest
, RequestHttpStreamOverProxy
) {
981 SpdySessionDependencies
session_deps(
982 GetParam(), ProxyService::CreateFixed("myproxy:8888"));
984 StaticSocketDataProvider socket_data
;
985 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
986 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
988 scoped_refptr
<HttpNetworkSession
> session(
989 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
991 // Now request a stream. It should succeed using the second proxy in the
993 HttpRequestInfo request_info
;
994 request_info
.method
= "GET";
995 request_info
.url
= GURL("http://www.google.com");
996 request_info
.load_flags
= 0;
998 SSLConfig ssl_config
;
999 StreamRequestWaiter waiter
;
1000 scoped_ptr
<HttpStreamRequest
> request(
1001 session
->http_stream_factory()->RequestStream(
1008 waiter
.WaitForStream();
1009 EXPECT_TRUE(waiter
.stream_done());
1010 ASSERT_TRUE(nullptr != waiter
.stream());
1011 EXPECT_TRUE(nullptr == waiter
.websocket_stream());
1013 EXPECT_EQ(0, GetSpdySessionCount(session
.get()));
1014 EXPECT_EQ(0, GetSocketPoolGroupCount(
1015 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1016 EXPECT_EQ(0, GetSocketPoolGroupCount(
1017 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1018 EXPECT_EQ(1, GetSocketPoolGroupCount(session
->GetSocketPoolForHTTPProxy(
1019 HttpNetworkSession::NORMAL_SOCKET_POOL
,
1020 HostPortPair("myproxy", 8888))));
1021 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSocketPoolForSSLWithProxy(
1022 HttpNetworkSession::NORMAL_SOCKET_POOL
,
1023 HostPortPair("myproxy", 8888))));
1024 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSocketPoolForHTTPProxy(
1025 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
,
1026 HostPortPair("myproxy", 8888))));
1027 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSocketPoolForSSLWithProxy(
1028 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
,
1029 HostPortPair("myproxy", 8888))));
1030 EXPECT_FALSE(waiter
.used_proxy_info().is_direct());
1033 TEST_P(HttpStreamFactoryTest
, RequestWebSocketBasicHandshakeStream
) {
1034 SpdySessionDependencies
session_deps(
1035 GetParam(), ProxyService::CreateDirect());
1037 StaticSocketDataProvider socket_data
;
1038 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
1039 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
1041 scoped_refptr
<HttpNetworkSession
> session(
1042 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
1044 // Now request a stream.
1045 HttpRequestInfo request_info
;
1046 request_info
.method
= "GET";
1047 request_info
.url
= GURL("ws://www.google.com");
1048 request_info
.load_flags
= 0;
1050 SSLConfig ssl_config
;
1051 StreamRequestWaiter waiter
;
1052 WebSocketStreamCreateHelper create_helper
;
1053 scoped_ptr
<HttpStreamRequest
> request(
1054 session
->http_stream_factory_for_websocket()
1055 ->RequestWebSocketHandshakeStream(request_info
,
1062 waiter
.WaitForStream();
1063 EXPECT_TRUE(waiter
.stream_done());
1064 EXPECT_TRUE(nullptr == waiter
.stream());
1065 ASSERT_TRUE(nullptr != waiter
.websocket_stream());
1066 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic
,
1067 waiter
.websocket_stream()->type());
1068 EXPECT_EQ(0, GetSocketPoolGroupCount(
1069 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1070 EXPECT_EQ(0, GetSocketPoolGroupCount(
1071 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1072 EXPECT_EQ(0, GetSocketPoolGroupCount(
1073 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1074 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
1077 TEST_P(HttpStreamFactoryTest
, RequestWebSocketBasicHandshakeStreamOverSSL
) {
1078 SpdySessionDependencies
session_deps(
1079 GetParam(), ProxyService::CreateDirect());
1081 MockRead
mock_read(ASYNC
, OK
);
1082 StaticSocketDataProvider
socket_data(&mock_read
, 1, nullptr, 0);
1083 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
1084 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
1086 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
1087 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl_socket_data
);
1089 scoped_refptr
<HttpNetworkSession
> session(
1090 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
1092 // Now request a stream.
1093 HttpRequestInfo request_info
;
1094 request_info
.method
= "GET";
1095 request_info
.url
= GURL("wss://www.google.com");
1096 request_info
.load_flags
= 0;
1098 SSLConfig ssl_config
;
1099 StreamRequestWaiter waiter
;
1100 WebSocketStreamCreateHelper create_helper
;
1101 scoped_ptr
<HttpStreamRequest
> request(
1102 session
->http_stream_factory_for_websocket()
1103 ->RequestWebSocketHandshakeStream(request_info
,
1110 waiter
.WaitForStream();
1111 EXPECT_TRUE(waiter
.stream_done());
1112 EXPECT_TRUE(nullptr == waiter
.stream());
1113 ASSERT_TRUE(nullptr != waiter
.websocket_stream());
1114 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic
,
1115 waiter
.websocket_stream()->type());
1116 EXPECT_EQ(0, GetSocketPoolGroupCount(
1117 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1118 EXPECT_EQ(0, GetSocketPoolGroupCount(
1119 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1120 EXPECT_EQ(1, GetSocketPoolGroupCount(
1121 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1122 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
1125 TEST_P(HttpStreamFactoryTest
, RequestWebSocketBasicHandshakeStreamOverProxy
) {
1126 SpdySessionDependencies
session_deps(
1127 GetParam(), ProxyService::CreateFixed("myproxy:8888"));
1129 MockRead
read(SYNCHRONOUS
, "HTTP/1.0 200 Connection established\r\n\r\n");
1130 StaticSocketDataProvider
socket_data(&read
, 1, 0, 0);
1131 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
1132 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
1134 scoped_refptr
<HttpNetworkSession
> session(
1135 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
1137 // Now request a stream.
1138 HttpRequestInfo request_info
;
1139 request_info
.method
= "GET";
1140 request_info
.url
= GURL("ws://www.google.com");
1141 request_info
.load_flags
= 0;
1143 SSLConfig ssl_config
;
1144 StreamRequestWaiter waiter
;
1145 WebSocketStreamCreateHelper create_helper
;
1146 scoped_ptr
<HttpStreamRequest
> request(
1147 session
->http_stream_factory_for_websocket()
1148 ->RequestWebSocketHandshakeStream(request_info
,
1155 waiter
.WaitForStream();
1156 EXPECT_TRUE(waiter
.stream_done());
1157 EXPECT_TRUE(nullptr == waiter
.stream());
1158 ASSERT_TRUE(nullptr != waiter
.websocket_stream());
1159 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic
,
1160 waiter
.websocket_stream()->type());
1161 EXPECT_EQ(0, GetSocketPoolGroupCount(
1162 session
->GetTransportSocketPool(
1163 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1164 EXPECT_EQ(0, GetSocketPoolGroupCount(
1165 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1166 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSocketPoolForHTTPProxy(
1167 HttpNetworkSession::NORMAL_SOCKET_POOL
,
1168 HostPortPair("myproxy", 8888))));
1169 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSocketPoolForSSLWithProxy(
1170 HttpNetworkSession::NORMAL_SOCKET_POOL
,
1171 HostPortPair("myproxy", 8888))));
1172 EXPECT_EQ(1, GetSocketPoolGroupCount(session
->GetSocketPoolForHTTPProxy(
1173 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
,
1174 HostPortPair("myproxy", 8888))));
1175 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSocketPoolForSSLWithProxy(
1176 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
,
1177 HostPortPair("myproxy", 8888))));
1178 EXPECT_FALSE(waiter
.used_proxy_info().is_direct());
1181 TEST_P(HttpStreamFactoryTest
, RequestSpdyHttpStream
) {
1182 SpdySessionDependencies
session_deps(GetParam(),
1183 ProxyService::CreateDirect());
1185 MockRead
mock_read(SYNCHRONOUS
, ERR_IO_PENDING
);
1186 SequencedSocketData
socket_data(&mock_read
, 1, nullptr, 0);
1187 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
1188 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
1190 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
1191 ssl_socket_data
.SetNextProto(GetParam());
1192 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl_socket_data
);
1194 HostPortPair
host_port_pair("www.google.com", 443);
1195 scoped_refptr
<HttpNetworkSession
> session(
1196 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
1198 // Now request a stream.
1199 HttpRequestInfo request_info
;
1200 request_info
.method
= "GET";
1201 request_info
.url
= GURL("https://www.google.com");
1202 request_info
.load_flags
= 0;
1204 SSLConfig ssl_config
;
1205 StreamRequestWaiter waiter
;
1206 scoped_ptr
<HttpStreamRequest
> request(
1207 session
->http_stream_factory()->RequestStream(
1214 waiter
.WaitForStream();
1215 EXPECT_TRUE(waiter
.stream_done());
1216 EXPECT_TRUE(nullptr == waiter
.websocket_stream());
1217 ASSERT_TRUE(nullptr != waiter
.stream());
1219 EXPECT_EQ(1, GetSpdySessionCount(session
.get()));
1220 EXPECT_EQ(1, GetSocketPoolGroupCount(
1221 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1222 EXPECT_EQ(1, GetSocketPoolGroupCount(
1223 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1224 EXPECT_EQ(0, GetSocketPoolGroupCount(
1225 session
->GetTransportSocketPool(
1226 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1227 EXPECT_EQ(0, GetSocketPoolGroupCount(
1228 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1229 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
1232 // TODO(ricea): This test can be removed once the new WebSocket stack supports
1233 // SPDY. Currently, even if we connect to a SPDY-supporting server, we need to
1235 TEST_P(HttpStreamFactoryTest
, RequestWebSocketSpdyHandshakeStreamButGetSSL
) {
1236 SpdySessionDependencies
session_deps(GetParam(),
1237 ProxyService::CreateDirect());
1239 MockRead
mock_read(SYNCHRONOUS
, ERR_IO_PENDING
);
1240 StaticSocketDataProvider
socket_data(&mock_read
, 1, nullptr, 0);
1241 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
1242 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
1244 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
1245 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl_socket_data
);
1247 HostPortPair
host_port_pair("www.google.com", 80);
1248 scoped_refptr
<HttpNetworkSession
>
1249 session(SpdySessionDependencies::SpdyCreateSession(&session_deps
));
1251 // Now request a stream.
1252 HttpRequestInfo request_info
;
1253 request_info
.method
= "GET";
1254 request_info
.url
= GURL("wss://www.google.com");
1255 request_info
.load_flags
= 0;
1257 SSLConfig ssl_config
;
1258 StreamRequestWaiter waiter1
;
1259 WebSocketStreamCreateHelper create_helper
;
1260 scoped_ptr
<HttpStreamRequest
> request1(
1261 session
->http_stream_factory_for_websocket()
1262 ->RequestWebSocketHandshakeStream(request_info
,
1269 waiter1
.WaitForStream();
1270 EXPECT_TRUE(waiter1
.stream_done());
1271 ASSERT_TRUE(nullptr != waiter1
.websocket_stream());
1272 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic
,
1273 waiter1
.websocket_stream()->type());
1274 EXPECT_TRUE(nullptr == waiter1
.stream());
1276 EXPECT_EQ(0, GetSocketPoolGroupCount(
1277 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1278 EXPECT_EQ(0, GetSocketPoolGroupCount(
1279 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1280 EXPECT_EQ(1, GetSocketPoolGroupCount(
1281 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1282 EXPECT_TRUE(waiter1
.used_proxy_info().is_direct());
1285 // TODO(ricea): Re-enable once WebSocket-over-SPDY is implemented.
1286 TEST_P(HttpStreamFactoryTest
, DISABLED_RequestWebSocketSpdyHandshakeStream
) {
1287 SpdySessionDependencies
session_deps(GetParam(),
1288 ProxyService::CreateDirect());
1290 MockRead
mock_read(SYNCHRONOUS
, ERR_IO_PENDING
);
1291 StaticSocketDataProvider
socket_data(&mock_read
, 1, nullptr, 0);
1292 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
1293 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
1295 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
1296 ssl_socket_data
.SetNextProto(GetParam());
1297 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl_socket_data
);
1299 HostPortPair
host_port_pair("www.google.com", 80);
1300 scoped_refptr
<HttpNetworkSession
>
1301 session(SpdySessionDependencies::SpdyCreateSession(&session_deps
));
1303 // Now request a stream.
1304 HttpRequestInfo request_info
;
1305 request_info
.method
= "GET";
1306 request_info
.url
= GURL("wss://www.google.com");
1307 request_info
.load_flags
= 0;
1309 SSLConfig ssl_config
;
1310 StreamRequestWaiter waiter1
;
1311 WebSocketStreamCreateHelper create_helper
;
1312 scoped_ptr
<HttpStreamRequest
> request1(
1313 session
->http_stream_factory_for_websocket()
1314 ->RequestWebSocketHandshakeStream(request_info
,
1321 waiter1
.WaitForStream();
1322 EXPECT_TRUE(waiter1
.stream_done());
1323 ASSERT_TRUE(nullptr != waiter1
.websocket_stream());
1324 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy
,
1325 waiter1
.websocket_stream()->type());
1326 EXPECT_TRUE(nullptr == waiter1
.stream());
1328 StreamRequestWaiter waiter2
;
1329 scoped_ptr
<HttpStreamRequest
> request2(
1330 session
->http_stream_factory_for_websocket()
1331 ->RequestWebSocketHandshakeStream(request_info
,
1338 waiter2
.WaitForStream();
1339 EXPECT_TRUE(waiter2
.stream_done());
1340 ASSERT_TRUE(nullptr != waiter2
.websocket_stream());
1341 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy
,
1342 waiter2
.websocket_stream()->type());
1343 EXPECT_TRUE(nullptr == waiter2
.stream());
1344 EXPECT_NE(waiter2
.websocket_stream(), waiter1
.websocket_stream());
1345 EXPECT_EQ(static_cast<WebSocketSpdyHandshakeStream
*>(
1346 waiter2
.websocket_stream())->spdy_session(),
1347 static_cast<WebSocketSpdyHandshakeStream
*>(
1348 waiter1
.websocket_stream())->spdy_session());
1350 EXPECT_EQ(0, GetSocketPoolGroupCount(
1351 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1352 EXPECT_EQ(0, GetSocketPoolGroupCount(
1353 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1354 EXPECT_EQ(1, GetSocketPoolGroupCount(
1355 session
->GetTransportSocketPool(
1356 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1357 EXPECT_EQ(1, GetSocketPoolGroupCount(
1358 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1359 EXPECT_TRUE(waiter1
.used_proxy_info().is_direct());
1362 // TODO(ricea): Re-enable once WebSocket over SPDY is implemented.
1363 TEST_P(HttpStreamFactoryTest
, DISABLED_OrphanedWebSocketStream
) {
1364 SpdySessionDependencies
session_deps(GetParam(),
1365 ProxyService::CreateDirect());
1366 session_deps
.use_alternative_services
= true;
1368 MockRead
mock_read(ASYNC
, OK
);
1369 SequencedSocketData
socket_data(&mock_read
, 1, nullptr, 0);
1370 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
1371 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
1373 MockRead
mock_read2(ASYNC
, OK
);
1374 SequencedSocketData
socket_data2(&mock_read2
, 1, nullptr, 0);
1375 socket_data2
.set_connect_data(MockConnect(ASYNC
, ERR_IO_PENDING
));
1376 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data2
);
1378 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
1379 ssl_socket_data
.SetNextProto(GetParam());
1380 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl_socket_data
);
1382 scoped_refptr
<HttpNetworkSession
> session(
1383 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
1385 // Now request a stream.
1386 HttpRequestInfo request_info
;
1387 request_info
.method
= "GET";
1388 request_info
.url
= GURL("ws://www.google.com:8888");
1389 request_info
.load_flags
= 0;
1391 base::Time expiration
= base::Time::Now() + base::TimeDelta::FromDays(1);
1392 session
->http_server_properties()->SetAlternativeService(
1393 HostPortPair("www.google.com", 8888),
1394 AlternativeService(NPN_HTTP_2
, "www.google.com", 9999), 1.0, expiration
);
1396 SSLConfig ssl_config
;
1397 StreamRequestWaiter waiter
;
1398 WebSocketStreamCreateHelper create_helper
;
1399 scoped_ptr
<HttpStreamRequest
> request(
1400 session
->http_stream_factory_for_websocket()
1401 ->RequestWebSocketHandshakeStream(request_info
,
1408 waiter
.WaitForStream();
1409 EXPECT_TRUE(waiter
.stream_done());
1410 EXPECT_TRUE(nullptr == waiter
.stream());
1411 ASSERT_TRUE(nullptr != waiter
.websocket_stream());
1412 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy
,
1413 waiter
.websocket_stream()->type());
1415 // Make sure that there was an alternative connection
1416 // which consumes extra connections.
1417 EXPECT_EQ(0, GetSocketPoolGroupCount(
1418 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1419 EXPECT_EQ(0, GetSocketPoolGroupCount(
1420 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1421 EXPECT_EQ(2, GetSocketPoolGroupCount(
1422 session
->GetTransportSocketPool(
1423 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1424 EXPECT_EQ(1, GetSocketPoolGroupCount(
1425 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1426 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
1428 // Make sure there is no orphaned job. it is already canceled.
1429 ASSERT_EQ(0u, static_cast<HttpStreamFactoryImpl
*>(
1430 session
->http_stream_factory_for_websocket())->num_orphaned_jobs());