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/port_util.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/log/net_log.h"
26 #include "net/proxy/proxy_info.h"
27 #include "net/proxy/proxy_service.h"
28 #include "net/socket/client_socket_handle.h"
29 #include "net/socket/mock_client_socket_pool_manager.h"
30 #include "net/socket/next_proto.h"
31 #include "net/socket/socket_test_util.h"
32 #include "net/spdy/spdy_session.h"
33 #include "net/spdy/spdy_session_pool.h"
34 #include "net/spdy/spdy_test_util_common.h"
35 #include "net/ssl/ssl_config_service.h"
36 #include "net/ssl/ssl_config_service_defaults.h"
37 // This file can be included from net/http even though
38 // it is in net/websockets because it doesn't
39 // introduce any link dependency to net/websockets.
40 #include "net/websockets/websocket_handshake_stream_base.h"
41 #include "testing/gtest/include/gtest/gtest.h"
47 class MockWebSocketHandshakeStream
: public WebSocketHandshakeStreamBase
{
54 explicit MockWebSocketHandshakeStream(StreamType type
) : type_(type
) {}
56 ~MockWebSocketHandshakeStream() override
{}
58 StreamType
type() const {
63 int InitializeStream(const HttpRequestInfo
* request_info
,
64 RequestPriority priority
,
65 const BoundNetLog
& net_log
,
66 const CompletionCallback
& callback
) override
{
67 return ERR_IO_PENDING
;
69 int SendRequest(const HttpRequestHeaders
& request_headers
,
70 HttpResponseInfo
* response
,
71 const CompletionCallback
& callback
) override
{
72 return ERR_IO_PENDING
;
74 int ReadResponseHeaders(const CompletionCallback
& callback
) override
{
75 return ERR_IO_PENDING
;
77 int ReadResponseBody(IOBuffer
* buf
,
79 const CompletionCallback
& callback
) override
{
80 return ERR_IO_PENDING
;
82 void Close(bool not_reusable
) override
{}
83 bool IsResponseBodyComplete() const override
{ return false; }
84 bool CanFindEndOfResponse() const override
{ return false; }
85 bool IsConnectionReused() const override
{ return false; }
86 void SetConnectionReused() override
{}
87 bool IsConnectionReusable() const override
{ return false; }
88 int64
GetTotalReceivedBytes() const override
{ return 0; }
89 bool GetLoadTimingInfo(LoadTimingInfo
* load_timing_info
) const override
{
92 void GetSSLInfo(SSLInfo
* ssl_info
) override
{}
93 void GetSSLCertRequestInfo(SSLCertRequestInfo
* cert_request_info
) override
{}
94 bool IsSpdyHttpStream() const override
{ return false; }
95 void Drain(HttpNetworkSession
* session
) override
{}
96 void SetPriority(RequestPriority priority
) override
{}
97 UploadProgress
GetUploadProgress() const override
{ return UploadProgress(); }
98 HttpStream
* RenewStreamForAuth() override
{ return nullptr; }
100 scoped_ptr
<WebSocketStream
> Upgrade() override
{
101 return scoped_ptr
<WebSocketStream
>();
105 const StreamType type_
;
108 // HttpStreamFactoryImpl subclass that can wait until a preconnect is complete.
109 class MockHttpStreamFactoryImplForPreconnect
: public HttpStreamFactoryImpl
{
111 MockHttpStreamFactoryImplForPreconnect(HttpNetworkSession
* session
,
113 : HttpStreamFactoryImpl(session
, for_websockets
),
114 preconnect_done_(false),
115 waiting_for_preconnect_(false) {}
118 void WaitForPreconnects() {
119 while (!preconnect_done_
) {
120 waiting_for_preconnect_
= true;
121 base::MessageLoop::current()->Run();
122 waiting_for_preconnect_
= false;
127 // HttpStreamFactoryImpl methods.
128 void OnPreconnectsCompleteInternal() override
{
129 preconnect_done_
= true;
130 if (waiting_for_preconnect_
)
131 base::MessageLoop::current()->Quit();
134 bool preconnect_done_
;
135 bool waiting_for_preconnect_
;
138 class StreamRequestWaiter
: public HttpStreamRequest::Delegate
{
140 StreamRequestWaiter()
141 : waiting_for_stream_(false),
142 stream_done_(false) {}
144 // HttpStreamRequest::Delegate
146 void OnStreamReady(const SSLConfig
& used_ssl_config
,
147 const ProxyInfo
& used_proxy_info
,
148 HttpStream
* 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 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 void OnStreamFailed(int status
,
170 const SSLConfig
& used_ssl_config
,
171 SSLFailureState ssl_failure_state
) override
{}
173 void OnCertificateError(int status
,
174 const SSLConfig
& used_ssl_config
,
175 const SSLInfo
& ssl_info
) override
{}
177 void OnNeedsProxyAuth(const HttpResponseInfo
& proxy_response
,
178 const SSLConfig
& used_ssl_config
,
179 const ProxyInfo
& used_proxy_info
,
180 HttpAuthController
* auth_controller
) override
{}
182 void OnNeedsClientAuth(const SSLConfig
& used_ssl_config
,
183 SSLCertRequestInfo
* cert_info
) override
{}
185 void OnHttpsProxyTunnelResponse(const HttpResponseInfo
& response_info
,
186 const SSLConfig
& used_ssl_config
,
187 const ProxyInfo
& used_proxy_info
,
188 HttpStream
* stream
) override
{}
190 void WaitForStream() {
191 while (!stream_done_
) {
192 waiting_for_stream_
= true;
193 base::MessageLoop::current()->Run();
194 waiting_for_stream_
= false;
198 const SSLConfig
& used_ssl_config() const {
199 return used_ssl_config_
;
202 const ProxyInfo
& used_proxy_info() const {
203 return used_proxy_info_
;
206 HttpStream
* stream() {
207 return stream_
.get();
210 MockWebSocketHandshakeStream
* websocket_stream() {
211 return static_cast<MockWebSocketHandshakeStream
*>(websocket_stream_
.get());
214 bool stream_done() const { return stream_done_
; }
217 bool waiting_for_stream_
;
219 scoped_ptr
<HttpStream
> stream_
;
220 scoped_ptr
<WebSocketHandshakeStreamBase
> websocket_stream_
;
221 SSLConfig used_ssl_config_
;
222 ProxyInfo used_proxy_info_
;
224 DISALLOW_COPY_AND_ASSIGN(StreamRequestWaiter
);
227 class WebSocketSpdyHandshakeStream
: public MockWebSocketHandshakeStream
{
229 explicit WebSocketSpdyHandshakeStream(
230 const base::WeakPtr
<SpdySession
>& spdy_session
)
231 : MockWebSocketHandshakeStream(kStreamTypeSpdy
),
232 spdy_session_(spdy_session
) {}
234 ~WebSocketSpdyHandshakeStream() override
{}
236 SpdySession
* spdy_session() { return spdy_session_
.get(); }
239 base::WeakPtr
<SpdySession
> spdy_session_
;
242 class WebSocketBasicHandshakeStream
: public MockWebSocketHandshakeStream
{
244 explicit WebSocketBasicHandshakeStream(
245 scoped_ptr
<ClientSocketHandle
> connection
)
246 : MockWebSocketHandshakeStream(kStreamTypeBasic
),
247 connection_(connection
.Pass()) {}
249 ~WebSocketBasicHandshakeStream() override
{
250 connection_
->socket()->Disconnect();
253 ClientSocketHandle
* connection() { return connection_
.get(); }
256 scoped_ptr
<ClientSocketHandle
> connection_
;
259 class WebSocketStreamCreateHelper
260 : public WebSocketHandshakeStreamBase::CreateHelper
{
262 ~WebSocketStreamCreateHelper() override
{}
264 WebSocketHandshakeStreamBase
* CreateBasicStream(
265 scoped_ptr
<ClientSocketHandle
> connection
,
266 bool using_proxy
) override
{
267 return new WebSocketBasicHandshakeStream(connection
.Pass());
270 WebSocketHandshakeStreamBase
* CreateSpdyStream(
271 const base::WeakPtr
<SpdySession
>& spdy_session
,
272 bool use_relative_url
) override
{
273 return new WebSocketSpdyHandshakeStream(spdy_session
);
282 TestCase kTests
[] = {
289 void PreconnectHelperForURL(int num_streams
,
291 HttpNetworkSession
* session
) {
292 HttpNetworkSessionPeer
peer(session
);
293 MockHttpStreamFactoryImplForPreconnect
* mock_factory
=
294 new MockHttpStreamFactoryImplForPreconnect(session
, false);
295 peer
.SetHttpStreamFactory(scoped_ptr
<HttpStreamFactory
>(mock_factory
));
296 SSLConfig ssl_config
;
297 session
->ssl_config_service()->GetSSLConfig(&ssl_config
);
299 HttpRequestInfo request
;
300 request
.method
= "GET";
302 request
.load_flags
= 0;
304 session
->http_stream_factory()->PreconnectStreams(num_streams
, request
,
305 ssl_config
, ssl_config
);
306 mock_factory
->WaitForPreconnects();
309 void PreconnectHelper(const TestCase
& test
,
310 HttpNetworkSession
* session
) {
311 GURL url
= test
.ssl
? GURL("https://www.google.com") :
312 GURL("http://www.google.com");
313 PreconnectHelperForURL(test
.num_streams
, url
, session
);
316 template<typename ParentPool
>
317 class CapturePreconnectsSocketPool
: public ParentPool
{
319 CapturePreconnectsSocketPool(HostResolver
* host_resolver
,
320 CertVerifier
* cert_verifier
);
322 int last_num_streams() const {
323 return last_num_streams_
;
326 int RequestSocket(const std::string
& group_name
,
327 const void* socket_params
,
328 RequestPriority priority
,
329 ClientSocketHandle
* handle
,
330 const CompletionCallback
& callback
,
331 const BoundNetLog
& net_log
) override
{
333 return ERR_UNEXPECTED
;
336 void RequestSockets(const std::string
& group_name
,
337 const void* socket_params
,
339 const BoundNetLog
& net_log
) override
{
340 last_num_streams_
= num_sockets
;
343 void CancelRequest(const std::string
& group_name
,
344 ClientSocketHandle
* handle
) override
{
347 void ReleaseSocket(const std::string
& group_name
,
348 scoped_ptr
<StreamSocket
> socket
,
352 void CloseIdleSockets() override
{ ADD_FAILURE(); }
353 int IdleSocketCount() const override
{
357 int IdleSocketCountInGroup(const std::string
& group_name
) const override
{
361 LoadState
GetLoadState(const std::string
& group_name
,
362 const ClientSocketHandle
* handle
) const override
{
364 return LOAD_STATE_IDLE
;
366 base::TimeDelta
ConnectionTimeout() const override
{
367 return base::TimeDelta();
371 int last_num_streams_
;
374 typedef CapturePreconnectsSocketPool
<TransportClientSocketPool
>
375 CapturePreconnectsTransportSocketPool
;
376 typedef CapturePreconnectsSocketPool
<HttpProxyClientSocketPool
>
377 CapturePreconnectsHttpProxySocketPool
;
378 typedef CapturePreconnectsSocketPool
<SOCKSClientSocketPool
>
379 CapturePreconnectsSOCKSSocketPool
;
380 typedef CapturePreconnectsSocketPool
<SSLClientSocketPool
>
381 CapturePreconnectsSSLSocketPool
;
383 template <typename ParentPool
>
384 CapturePreconnectsSocketPool
<ParentPool
>::CapturePreconnectsSocketPool(
385 HostResolver
* host_resolver
,
386 CertVerifier
* /* cert_verifier */)
387 : ParentPool(0, 0, host_resolver
, nullptr, nullptr), last_num_streams_(-1) {
391 CapturePreconnectsHttpProxySocketPool::CapturePreconnectsSocketPool(
392 HostResolver
* /* host_resolver */,
393 CertVerifier
* /* cert_verifier */)
394 : HttpProxyClientSocketPool(0, 0, nullptr, nullptr, nullptr),
395 last_num_streams_(-1) {
399 CapturePreconnectsSSLSocketPool::CapturePreconnectsSocketPool(
400 HostResolver
* /* host_resolver */,
401 CertVerifier
* cert_verifier
)
402 : SSLClientSocketPool(0,
405 nullptr, // channel_id_store
406 nullptr, // transport_security_state
407 nullptr, // cert_transparency_verifier
408 nullptr, // cert_policy_enforcer
409 std::string(), // ssl_session_cache_shard
410 nullptr, // deterministic_socket_factory
411 nullptr, // transport_socket_pool
414 nullptr, // ssl_config_service
416 last_num_streams_(-1) {
419 class HttpStreamFactoryTest
: public ::testing::Test
,
420 public ::testing::WithParamInterface
<NextProto
> {
423 INSTANTIATE_TEST_CASE_P(NextProto
,
424 HttpStreamFactoryTest
,
425 testing::Values(kProtoSPDY31
,
428 TEST_P(HttpStreamFactoryTest
, PreconnectDirect
) {
429 for (size_t i
= 0; i
< arraysize(kTests
); ++i
) {
430 SpdySessionDependencies
session_deps(
431 GetParam(), ProxyService::CreateDirect());
432 scoped_refptr
<HttpNetworkSession
> session(
433 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
434 HttpNetworkSessionPeer
peer(session
);
435 CapturePreconnectsTransportSocketPool
* transport_conn_pool
=
436 new CapturePreconnectsTransportSocketPool(
437 session_deps
.host_resolver
.get(),
438 session_deps
.cert_verifier
.get());
439 CapturePreconnectsSSLSocketPool
* ssl_conn_pool
=
440 new CapturePreconnectsSSLSocketPool(
441 session_deps
.host_resolver
.get(),
442 session_deps
.cert_verifier
.get());
443 scoped_ptr
<MockClientSocketPoolManager
> mock_pool_manager(
444 new MockClientSocketPoolManager
);
445 mock_pool_manager
->SetTransportSocketPool(transport_conn_pool
);
446 mock_pool_manager
->SetSSLSocketPool(ssl_conn_pool
);
447 peer
.SetClientSocketPoolManager(mock_pool_manager
.Pass());
448 PreconnectHelper(kTests
[i
], session
.get());
450 EXPECT_EQ(kTests
[i
].num_streams
, ssl_conn_pool
->last_num_streams());
452 EXPECT_EQ(kTests
[i
].num_streams
, transport_conn_pool
->last_num_streams());
456 TEST_P(HttpStreamFactoryTest
, PreconnectHttpProxy
) {
457 for (size_t i
= 0; i
< arraysize(kTests
); ++i
) {
458 SpdySessionDependencies
session_deps(
459 GetParam(), ProxyService::CreateFixed("http_proxy"));
460 scoped_refptr
<HttpNetworkSession
> session(
461 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
462 HttpNetworkSessionPeer
peer(session
);
463 HostPortPair
proxy_host("http_proxy", 80);
464 CapturePreconnectsHttpProxySocketPool
* http_proxy_pool
=
465 new CapturePreconnectsHttpProxySocketPool(
466 session_deps
.host_resolver
.get(),
467 session_deps
.cert_verifier
.get());
468 CapturePreconnectsSSLSocketPool
* ssl_conn_pool
=
469 new CapturePreconnectsSSLSocketPool(
470 session_deps
.host_resolver
.get(),
471 session_deps
.cert_verifier
.get());
472 scoped_ptr
<MockClientSocketPoolManager
> mock_pool_manager(
473 new MockClientSocketPoolManager
);
474 mock_pool_manager
->SetSocketPoolForHTTPProxy(proxy_host
, http_proxy_pool
);
475 mock_pool_manager
->SetSocketPoolForSSLWithProxy(proxy_host
, ssl_conn_pool
);
476 peer
.SetClientSocketPoolManager(mock_pool_manager
.Pass());
477 PreconnectHelper(kTests
[i
], session
.get());
479 EXPECT_EQ(kTests
[i
].num_streams
, ssl_conn_pool
->last_num_streams());
481 EXPECT_EQ(kTests
[i
].num_streams
, http_proxy_pool
->last_num_streams());
485 TEST_P(HttpStreamFactoryTest
, PreconnectSocksProxy
) {
486 for (size_t i
= 0; i
< arraysize(kTests
); ++i
) {
487 SpdySessionDependencies
session_deps(
488 GetParam(), ProxyService::CreateFixed("socks4://socks_proxy:1080"));
489 scoped_refptr
<HttpNetworkSession
> session(
490 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
491 HttpNetworkSessionPeer
peer(session
);
492 HostPortPair
proxy_host("socks_proxy", 1080);
493 CapturePreconnectsSOCKSSocketPool
* socks_proxy_pool
=
494 new CapturePreconnectsSOCKSSocketPool(
495 session_deps
.host_resolver
.get(),
496 session_deps
.cert_verifier
.get());
497 CapturePreconnectsSSLSocketPool
* ssl_conn_pool
=
498 new CapturePreconnectsSSLSocketPool(
499 session_deps
.host_resolver
.get(),
500 session_deps
.cert_verifier
.get());
501 scoped_ptr
<MockClientSocketPoolManager
> mock_pool_manager(
502 new MockClientSocketPoolManager
);
503 mock_pool_manager
->SetSocketPoolForSOCKSProxy(proxy_host
, socks_proxy_pool
);
504 mock_pool_manager
->SetSocketPoolForSSLWithProxy(proxy_host
, ssl_conn_pool
);
505 peer
.SetClientSocketPoolManager(mock_pool_manager
.Pass());
506 PreconnectHelper(kTests
[i
], session
.get());
508 EXPECT_EQ(kTests
[i
].num_streams
, ssl_conn_pool
->last_num_streams());
510 EXPECT_EQ(kTests
[i
].num_streams
, socks_proxy_pool
->last_num_streams());
514 TEST_P(HttpStreamFactoryTest
, PreconnectDirectWithExistingSpdySession
) {
515 for (size_t i
= 0; i
< arraysize(kTests
); ++i
) {
516 SpdySessionDependencies
session_deps(
517 GetParam(), ProxyService::CreateDirect());
518 scoped_refptr
<HttpNetworkSession
> session(
519 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
520 HttpNetworkSessionPeer
peer(session
);
522 // Put a SpdySession in the pool.
523 HostPortPair
host_port_pair("www.google.com", 443);
524 SpdySessionKey
key(host_port_pair
, ProxyServer::Direct(),
525 PRIVACY_MODE_DISABLED
);
526 ignore_result(CreateFakeSpdySession(session
->spdy_session_pool(), key
));
528 CapturePreconnectsTransportSocketPool
* transport_conn_pool
=
529 new CapturePreconnectsTransportSocketPool(
530 session_deps
.host_resolver
.get(),
531 session_deps
.cert_verifier
.get());
532 CapturePreconnectsSSLSocketPool
* ssl_conn_pool
=
533 new CapturePreconnectsSSLSocketPool(
534 session_deps
.host_resolver
.get(),
535 session_deps
.cert_verifier
.get());
536 scoped_ptr
<MockClientSocketPoolManager
> mock_pool_manager(
537 new MockClientSocketPoolManager
);
538 mock_pool_manager
->SetTransportSocketPool(transport_conn_pool
);
539 mock_pool_manager
->SetSSLSocketPool(ssl_conn_pool
);
540 peer
.SetClientSocketPoolManager(mock_pool_manager
.Pass());
541 PreconnectHelper(kTests
[i
], session
.get());
542 // We shouldn't be preconnecting if we have an existing session, which is
543 // the case for https://www.google.com.
545 EXPECT_EQ(-1, ssl_conn_pool
->last_num_streams());
547 EXPECT_EQ(kTests
[i
].num_streams
,
548 transport_conn_pool
->last_num_streams());
552 // Verify that preconnects to unsafe ports are cancelled before they reach
554 TEST_P(HttpStreamFactoryTest
, PreconnectUnsafePort
) {
555 ASSERT_FALSE(IsPortAllowedForScheme(7, "http"));
557 SpdySessionDependencies
session_deps(
558 GetParam(), ProxyService::CreateDirect());
559 scoped_refptr
<HttpNetworkSession
> session(
560 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
561 HttpNetworkSessionPeer
peer(session
);
562 CapturePreconnectsTransportSocketPool
* transport_conn_pool
=
563 new CapturePreconnectsTransportSocketPool(
564 session_deps
.host_resolver
.get(),
565 session_deps
.cert_verifier
.get());
566 scoped_ptr
<MockClientSocketPoolManager
> mock_pool_manager(
567 new MockClientSocketPoolManager
);
568 mock_pool_manager
->SetTransportSocketPool(transport_conn_pool
);
569 peer
.SetClientSocketPoolManager(mock_pool_manager
.Pass());
571 PreconnectHelperForURL(1, GURL("http://www.google.com:7"), session
.get());
572 EXPECT_EQ(-1, transport_conn_pool
->last_num_streams());
575 TEST_P(HttpStreamFactoryTest
, JobNotifiesProxy
) {
576 const char* kProxyString
= "PROXY bad:99; PROXY maybe:80; DIRECT";
577 SpdySessionDependencies
session_deps(
578 GetParam(), ProxyService::CreateFixedFromPacResult(kProxyString
));
580 // First connection attempt fails
581 StaticSocketDataProvider socket_data1
;
582 socket_data1
.set_connect_data(MockConnect(ASYNC
, ERR_ADDRESS_UNREACHABLE
));
583 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data1
);
585 // Second connection attempt succeeds
586 StaticSocketDataProvider socket_data2
;
587 socket_data2
.set_connect_data(MockConnect(ASYNC
, OK
));
588 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data2
);
590 scoped_refptr
<HttpNetworkSession
> session(
591 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
593 // Now request a stream. It should succeed using the second proxy in the
595 HttpRequestInfo request_info
;
596 request_info
.method
= "GET";
597 request_info
.url
= GURL("http://www.google.com");
599 SSLConfig ssl_config
;
600 StreamRequestWaiter waiter
;
601 scoped_ptr
<HttpStreamRequest
> request(
602 session
->http_stream_factory()->RequestStream(
603 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
,
604 &waiter
, BoundNetLog()));
605 waiter
.WaitForStream();
607 // The proxy that failed should now be known to the proxy_service as bad.
608 const ProxyRetryInfoMap
& retry_info
=
609 session
->proxy_service()->proxy_retry_info();
610 EXPECT_EQ(1u, retry_info
.size());
611 ProxyRetryInfoMap::const_iterator iter
= retry_info
.find("bad:99");
612 EXPECT_TRUE(iter
!= retry_info
.end());
615 TEST_P(HttpStreamFactoryTest
, UnreachableQuicProxyMarkedAsBad
) {
616 for (int i
= 1; i
<= 2; i
++) {
618 i
== 1 ? ERR_QUIC_PROTOCOL_ERROR
: ERR_QUIC_HANDSHAKE_FAILED
;
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
));
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()) << 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()) << i
;
680 TEST_P(HttpStreamFactoryTest
, QuicLossyProxyMarkedAsBad
) {
682 scoped_ptr
<ProxyService
> proxy_service
;
684 ProxyService::CreateFixedFromPacResult("QUIC bad:99; DIRECT"));
686 HttpNetworkSession::Params params
;
687 params
.enable_quic
= true;
688 params
.enable_quic_for_proxies
= true;
689 scoped_refptr
<SSLConfigServiceDefaults
> ssl_config_service(
690 new SSLConfigServiceDefaults
);
691 HttpServerPropertiesImpl http_server_properties
;
692 MockClientSocketFactory socket_factory
;
693 params
.client_socket_factory
= &socket_factory
;
694 MockHostResolver host_resolver
;
695 params
.host_resolver
= &host_resolver
;
696 TransportSecurityState transport_security_state
;
697 params
.transport_security_state
= &transport_security_state
;
698 params
.proxy_service
= proxy_service
.get();
699 params
.ssl_config_service
= ssl_config_service
.get();
700 params
.http_server_properties
= http_server_properties
.GetWeakPtr();
701 params
.quic_max_number_of_lossy_connections
= 2;
703 scoped_refptr
<HttpNetworkSession
> session
;
704 session
= new HttpNetworkSession(params
);
705 session
->quic_stream_factory()->set_require_confirmation(false);
707 session
->quic_stream_factory()->number_of_lossy_connections_
[99] =
708 params
.quic_max_number_of_lossy_connections
;
710 StaticSocketDataProvider socket_data2
;
711 socket_data2
.set_connect_data(MockConnect(ASYNC
, OK
));
712 socket_factory
.AddSocketDataProvider(&socket_data2
);
714 // Now request a stream. It should succeed using the second proxy in the
716 HttpRequestInfo request_info
;
717 request_info
.method
= "GET";
718 request_info
.url
= GURL("http://www.google.com");
720 SSLConfig ssl_config
;
721 StreamRequestWaiter waiter
;
722 scoped_ptr
<HttpStreamRequest
> request(
723 session
->http_stream_factory()->RequestStream(
724 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
, &waiter
,
726 waiter
.WaitForStream();
728 // The proxy that failed should now be known to the proxy_service as bad.
729 const ProxyRetryInfoMap
& retry_info
=
730 session
->proxy_service()->proxy_retry_info();
731 EXPECT_EQ(1u, retry_info
.size());
732 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
734 ProxyRetryInfoMap::const_iterator iter
= retry_info
.find("quic://bad:99");
735 EXPECT_TRUE(iter
!= retry_info
.end());
740 TEST_P(HttpStreamFactoryTest
, PrivacyModeDisablesChannelId
) {
741 SpdySessionDependencies
session_deps(
742 GetParam(), ProxyService::CreateDirect());
744 StaticSocketDataProvider socket_data
;
745 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
746 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
748 SSLSocketDataProvider
ssl(ASYNC
, OK
);
749 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl
);
751 scoped_refptr
<HttpNetworkSession
> session(
752 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
754 // Set an existing SpdySession in the pool.
755 HostPortPair
host_port_pair("www.google.com", 443);
756 SpdySessionKey
key(host_port_pair
, ProxyServer::Direct(),
757 PRIVACY_MODE_ENABLED
);
759 HttpRequestInfo request_info
;
760 request_info
.method
= "GET";
761 request_info
.url
= GURL("https://www.google.com");
762 request_info
.load_flags
= 0;
763 request_info
.privacy_mode
= PRIVACY_MODE_DISABLED
;
765 SSLConfig ssl_config
;
766 StreamRequestWaiter waiter
;
767 scoped_ptr
<HttpStreamRequest
> request(
768 session
->http_stream_factory()->RequestStream(
769 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
,
770 &waiter
, BoundNetLog()));
771 waiter
.WaitForStream();
773 // The stream shouldn't come from spdy as we are using different privacy mode
774 EXPECT_FALSE(request
->using_spdy());
776 SSLConfig used_ssl_config
= waiter
.used_ssl_config();
777 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());
794 TEST_P(HttpStreamFactoryTest
, PrivacyModeUsesDifferentSocketPoolGroup
) {
795 SpdySessionDependencies
session_deps(
796 GetParam(), ProxyService::CreateDirect());
798 StaticSocketDataProvider socket_data
;
799 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
800 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
802 SSLSocketDataProvider
ssl(ASYNC
, OK
);
803 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl
);
805 scoped_refptr
<HttpNetworkSession
> session(
806 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
807 SSLClientSocketPool
* ssl_pool
= session
->GetSSLSocketPool(
808 HttpNetworkSession::NORMAL_SOCKET_POOL
);
810 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool
), 0);
812 HttpRequestInfo request_info
;
813 request_info
.method
= "GET";
814 request_info
.url
= GURL("https://www.google.com");
815 request_info
.load_flags
= 0;
816 request_info
.privacy_mode
= PRIVACY_MODE_DISABLED
;
818 SSLConfig ssl_config
;
819 StreamRequestWaiter waiter
;
821 scoped_ptr
<HttpStreamRequest
> request1(
822 session
->http_stream_factory()->RequestStream(
823 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
,
824 &waiter
, BoundNetLog()));
825 waiter
.WaitForStream();
827 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool
), 1);
829 scoped_ptr
<HttpStreamRequest
> request2(
830 session
->http_stream_factory()->RequestStream(
831 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
,
832 &waiter
, BoundNetLog()));
833 waiter
.WaitForStream();
835 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool
), 1);
837 request_info
.privacy_mode
= PRIVACY_MODE_ENABLED
;
838 scoped_ptr
<HttpStreamRequest
> request3(
839 session
->http_stream_factory()->RequestStream(
840 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
,
841 &waiter
, BoundNetLog()));
842 waiter
.WaitForStream();
844 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool
), 2);
847 TEST_P(HttpStreamFactoryTest
, GetLoadState
) {
848 SpdySessionDependencies
session_deps(
849 GetParam(), ProxyService::CreateDirect());
851 StaticSocketDataProvider socket_data
;
852 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
853 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
855 scoped_refptr
<HttpNetworkSession
> session(
856 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
858 HttpRequestInfo request_info
;
859 request_info
.method
= "GET";
860 request_info
.url
= GURL("http://www.google.com");
862 SSLConfig ssl_config
;
863 StreamRequestWaiter waiter
;
864 scoped_ptr
<HttpStreamRequest
> request(
865 session
->http_stream_factory()->RequestStream(
866 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
,
867 &waiter
, BoundNetLog()));
869 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST
, request
->GetLoadState());
871 waiter
.WaitForStream();
874 TEST_P(HttpStreamFactoryTest
, RequestHttpStream
) {
875 SpdySessionDependencies
session_deps(
876 GetParam(), ProxyService::CreateDirect());
878 StaticSocketDataProvider socket_data
;
879 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
880 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
882 scoped_refptr
<HttpNetworkSession
> session(
883 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
885 // Now request a stream. It should succeed using the second proxy in the
887 HttpRequestInfo request_info
;
888 request_info
.method
= "GET";
889 request_info
.url
= GURL("http://www.google.com");
890 request_info
.load_flags
= 0;
892 SSLConfig ssl_config
;
893 StreamRequestWaiter waiter
;
894 scoped_ptr
<HttpStreamRequest
> request(
895 session
->http_stream_factory()->RequestStream(
902 waiter
.WaitForStream();
903 EXPECT_TRUE(waiter
.stream_done());
904 ASSERT_TRUE(nullptr != waiter
.stream());
905 EXPECT_TRUE(nullptr == waiter
.websocket_stream());
906 EXPECT_FALSE(waiter
.stream()->IsSpdyHttpStream());
908 EXPECT_EQ(1, GetSocketPoolGroupCount(
909 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
910 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSSLSocketPool(
911 HttpNetworkSession::NORMAL_SOCKET_POOL
)));
912 EXPECT_EQ(0, GetSocketPoolGroupCount(
913 session
->GetTransportSocketPool(
914 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
915 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSSLSocketPool(
916 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
917 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
920 TEST_P(HttpStreamFactoryTest
, RequestHttpStreamOverSSL
) {
921 SpdySessionDependencies
session_deps(
922 GetParam(), ProxyService::CreateDirect());
924 MockRead
mock_read(ASYNC
, OK
);
925 StaticSocketDataProvider
socket_data(&mock_read
, 1, nullptr, 0);
926 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
927 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
929 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
930 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl_socket_data
);
932 scoped_refptr
<HttpNetworkSession
> session(
933 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
935 // Now request a stream.
936 HttpRequestInfo request_info
;
937 request_info
.method
= "GET";
938 request_info
.url
= GURL("https://www.google.com");
939 request_info
.load_flags
= 0;
941 SSLConfig ssl_config
;
942 StreamRequestWaiter waiter
;
943 scoped_ptr
<HttpStreamRequest
> request(
944 session
->http_stream_factory()->RequestStream(
951 waiter
.WaitForStream();
952 EXPECT_TRUE(waiter
.stream_done());
953 ASSERT_TRUE(nullptr != waiter
.stream());
954 EXPECT_TRUE(nullptr == waiter
.websocket_stream());
955 EXPECT_FALSE(waiter
.stream()->IsSpdyHttpStream());
956 EXPECT_EQ(1, GetSocketPoolGroupCount(
957 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
958 EXPECT_EQ(1, GetSocketPoolGroupCount(
959 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
960 EXPECT_EQ(0, GetSocketPoolGroupCount(
961 session
->GetTransportSocketPool(
962 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
963 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSSLSocketPool(
964 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
965 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
968 TEST_P(HttpStreamFactoryTest
, RequestHttpStreamOverProxy
) {
969 SpdySessionDependencies
session_deps(
970 GetParam(), ProxyService::CreateFixed("myproxy:8888"));
972 StaticSocketDataProvider socket_data
;
973 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
974 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
976 scoped_refptr
<HttpNetworkSession
> session(
977 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
979 // Now request a stream. It should succeed using the second proxy in the
981 HttpRequestInfo request_info
;
982 request_info
.method
= "GET";
983 request_info
.url
= GURL("http://www.google.com");
984 request_info
.load_flags
= 0;
986 SSLConfig ssl_config
;
987 StreamRequestWaiter waiter
;
988 scoped_ptr
<HttpStreamRequest
> request(
989 session
->http_stream_factory()->RequestStream(
996 waiter
.WaitForStream();
997 EXPECT_TRUE(waiter
.stream_done());
998 ASSERT_TRUE(nullptr != waiter
.stream());
999 EXPECT_TRUE(nullptr == waiter
.websocket_stream());
1000 EXPECT_FALSE(waiter
.stream()->IsSpdyHttpStream());
1001 EXPECT_EQ(0, GetSocketPoolGroupCount(
1002 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1003 EXPECT_EQ(0, GetSocketPoolGroupCount(
1004 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1005 EXPECT_EQ(1, GetSocketPoolGroupCount(session
->GetSocketPoolForHTTPProxy(
1006 HttpNetworkSession::NORMAL_SOCKET_POOL
,
1007 HostPortPair("myproxy", 8888))));
1008 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSocketPoolForSSLWithProxy(
1009 HttpNetworkSession::NORMAL_SOCKET_POOL
,
1010 HostPortPair("myproxy", 8888))));
1011 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSocketPoolForHTTPProxy(
1012 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
,
1013 HostPortPair("myproxy", 8888))));
1014 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSocketPoolForSSLWithProxy(
1015 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
,
1016 HostPortPair("myproxy", 8888))));
1017 EXPECT_FALSE(waiter
.used_proxy_info().is_direct());
1020 TEST_P(HttpStreamFactoryTest
, RequestWebSocketBasicHandshakeStream
) {
1021 SpdySessionDependencies
session_deps(
1022 GetParam(), ProxyService::CreateDirect());
1024 StaticSocketDataProvider socket_data
;
1025 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
1026 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
1028 scoped_refptr
<HttpNetworkSession
> session(
1029 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
1031 // Now request a stream.
1032 HttpRequestInfo request_info
;
1033 request_info
.method
= "GET";
1034 request_info
.url
= GURL("ws://www.google.com");
1035 request_info
.load_flags
= 0;
1037 SSLConfig ssl_config
;
1038 StreamRequestWaiter waiter
;
1039 WebSocketStreamCreateHelper create_helper
;
1040 scoped_ptr
<HttpStreamRequest
> request(
1041 session
->http_stream_factory_for_websocket()
1042 ->RequestWebSocketHandshakeStream(request_info
,
1049 waiter
.WaitForStream();
1050 EXPECT_TRUE(waiter
.stream_done());
1051 EXPECT_TRUE(nullptr == waiter
.stream());
1052 ASSERT_TRUE(nullptr != waiter
.websocket_stream());
1053 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic
,
1054 waiter
.websocket_stream()->type());
1055 EXPECT_EQ(0, GetSocketPoolGroupCount(
1056 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1057 EXPECT_EQ(0, GetSocketPoolGroupCount(
1058 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1059 EXPECT_EQ(0, GetSocketPoolGroupCount(
1060 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1061 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
1064 TEST_P(HttpStreamFactoryTest
, RequestWebSocketBasicHandshakeStreamOverSSL
) {
1065 SpdySessionDependencies
session_deps(
1066 GetParam(), ProxyService::CreateDirect());
1068 MockRead
mock_read(ASYNC
, OK
);
1069 StaticSocketDataProvider
socket_data(&mock_read
, 1, nullptr, 0);
1070 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
1071 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
1073 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
1074 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl_socket_data
);
1076 scoped_refptr
<HttpNetworkSession
> session(
1077 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
1079 // Now request a stream.
1080 HttpRequestInfo request_info
;
1081 request_info
.method
= "GET";
1082 request_info
.url
= GURL("wss://www.google.com");
1083 request_info
.load_flags
= 0;
1085 SSLConfig ssl_config
;
1086 StreamRequestWaiter waiter
;
1087 WebSocketStreamCreateHelper create_helper
;
1088 scoped_ptr
<HttpStreamRequest
> request(
1089 session
->http_stream_factory_for_websocket()
1090 ->RequestWebSocketHandshakeStream(request_info
,
1097 waiter
.WaitForStream();
1098 EXPECT_TRUE(waiter
.stream_done());
1099 EXPECT_TRUE(nullptr == waiter
.stream());
1100 ASSERT_TRUE(nullptr != waiter
.websocket_stream());
1101 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic
,
1102 waiter
.websocket_stream()->type());
1103 EXPECT_EQ(0, GetSocketPoolGroupCount(
1104 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1105 EXPECT_EQ(0, GetSocketPoolGroupCount(
1106 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1107 EXPECT_EQ(1, GetSocketPoolGroupCount(
1108 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1109 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
1112 TEST_P(HttpStreamFactoryTest
, RequestWebSocketBasicHandshakeStreamOverProxy
) {
1113 SpdySessionDependencies
session_deps(
1114 GetParam(), ProxyService::CreateFixed("myproxy:8888"));
1116 MockRead
read(SYNCHRONOUS
, "HTTP/1.0 200 Connection established\r\n\r\n");
1117 StaticSocketDataProvider
socket_data(&read
, 1, 0, 0);
1118 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
1119 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
1121 scoped_refptr
<HttpNetworkSession
> session(
1122 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
1124 // Now request a stream.
1125 HttpRequestInfo request_info
;
1126 request_info
.method
= "GET";
1127 request_info
.url
= GURL("ws://www.google.com");
1128 request_info
.load_flags
= 0;
1130 SSLConfig ssl_config
;
1131 StreamRequestWaiter waiter
;
1132 WebSocketStreamCreateHelper create_helper
;
1133 scoped_ptr
<HttpStreamRequest
> request(
1134 session
->http_stream_factory_for_websocket()
1135 ->RequestWebSocketHandshakeStream(request_info
,
1142 waiter
.WaitForStream();
1143 EXPECT_TRUE(waiter
.stream_done());
1144 EXPECT_TRUE(nullptr == waiter
.stream());
1145 ASSERT_TRUE(nullptr != waiter
.websocket_stream());
1146 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic
,
1147 waiter
.websocket_stream()->type());
1148 EXPECT_EQ(0, GetSocketPoolGroupCount(
1149 session
->GetTransportSocketPool(
1150 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1151 EXPECT_EQ(0, GetSocketPoolGroupCount(
1152 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1153 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSocketPoolForHTTPProxy(
1154 HttpNetworkSession::NORMAL_SOCKET_POOL
,
1155 HostPortPair("myproxy", 8888))));
1156 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSocketPoolForSSLWithProxy(
1157 HttpNetworkSession::NORMAL_SOCKET_POOL
,
1158 HostPortPair("myproxy", 8888))));
1159 EXPECT_EQ(1, GetSocketPoolGroupCount(session
->GetSocketPoolForHTTPProxy(
1160 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
,
1161 HostPortPair("myproxy", 8888))));
1162 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSocketPoolForSSLWithProxy(
1163 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
,
1164 HostPortPair("myproxy", 8888))));
1165 EXPECT_FALSE(waiter
.used_proxy_info().is_direct());
1168 TEST_P(HttpStreamFactoryTest
, RequestSpdyHttpStream
) {
1169 SpdySessionDependencies
session_deps(GetParam(),
1170 ProxyService::CreateDirect());
1172 MockRead
mock_read(ASYNC
, OK
);
1173 SequencedSocketData
socket_data(&mock_read
, 1, nullptr, 0);
1174 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
1175 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
1177 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
1178 ssl_socket_data
.SetNextProto(GetParam());
1179 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl_socket_data
);
1181 HostPortPair
host_port_pair("www.google.com", 443);
1182 scoped_refptr
<HttpNetworkSession
> session(
1183 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
1185 // Now request a stream.
1186 HttpRequestInfo request_info
;
1187 request_info
.method
= "GET";
1188 request_info
.url
= GURL("https://www.google.com");
1189 request_info
.load_flags
= 0;
1191 SSLConfig ssl_config
;
1192 StreamRequestWaiter waiter
;
1193 scoped_ptr
<HttpStreamRequest
> request(
1194 session
->http_stream_factory()->RequestStream(
1201 waiter
.WaitForStream();
1202 EXPECT_TRUE(waiter
.stream_done());
1203 EXPECT_TRUE(nullptr == waiter
.websocket_stream());
1204 ASSERT_TRUE(nullptr != waiter
.stream());
1205 EXPECT_TRUE(waiter
.stream()->IsSpdyHttpStream());
1206 EXPECT_EQ(1, GetSocketPoolGroupCount(
1207 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1208 EXPECT_EQ(1, GetSocketPoolGroupCount(
1209 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1210 EXPECT_EQ(0, GetSocketPoolGroupCount(
1211 session
->GetTransportSocketPool(
1212 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1213 EXPECT_EQ(0, GetSocketPoolGroupCount(
1214 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1215 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
1218 // TODO(ricea): This test can be removed once the new WebSocket stack supports
1219 // SPDY. Currently, even if we connect to a SPDY-supporting server, we need to
1221 TEST_P(HttpStreamFactoryTest
, RequestWebSocketSpdyHandshakeStreamButGetSSL
) {
1222 SpdySessionDependencies
session_deps(GetParam(),
1223 ProxyService::CreateDirect());
1225 MockRead
mock_read(SYNCHRONOUS
, ERR_IO_PENDING
);
1226 StaticSocketDataProvider
socket_data(&mock_read
, 1, nullptr, 0);
1227 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
1228 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
1230 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
1231 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl_socket_data
);
1233 HostPortPair
host_port_pair("www.google.com", 80);
1234 scoped_refptr
<HttpNetworkSession
>
1235 session(SpdySessionDependencies::SpdyCreateSession(&session_deps
));
1237 // Now request a stream.
1238 HttpRequestInfo request_info
;
1239 request_info
.method
= "GET";
1240 request_info
.url
= GURL("wss://www.google.com");
1241 request_info
.load_flags
= 0;
1243 SSLConfig ssl_config
;
1244 StreamRequestWaiter waiter1
;
1245 WebSocketStreamCreateHelper create_helper
;
1246 scoped_ptr
<HttpStreamRequest
> request1(
1247 session
->http_stream_factory_for_websocket()
1248 ->RequestWebSocketHandshakeStream(request_info
,
1255 waiter1
.WaitForStream();
1256 EXPECT_TRUE(waiter1
.stream_done());
1257 ASSERT_TRUE(nullptr != waiter1
.websocket_stream());
1258 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic
,
1259 waiter1
.websocket_stream()->type());
1260 EXPECT_TRUE(nullptr == waiter1
.stream());
1262 EXPECT_EQ(0, GetSocketPoolGroupCount(
1263 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1264 EXPECT_EQ(0, GetSocketPoolGroupCount(
1265 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1266 EXPECT_EQ(1, GetSocketPoolGroupCount(
1267 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1268 EXPECT_TRUE(waiter1
.used_proxy_info().is_direct());
1271 // TODO(ricea): Re-enable once WebSocket-over-SPDY is implemented.
1272 TEST_P(HttpStreamFactoryTest
, DISABLED_RequestWebSocketSpdyHandshakeStream
) {
1273 SpdySessionDependencies
session_deps(GetParam(),
1274 ProxyService::CreateDirect());
1276 MockRead
mock_read(SYNCHRONOUS
, ERR_IO_PENDING
);
1277 StaticSocketDataProvider
socket_data(&mock_read
, 1, nullptr, 0);
1278 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
1279 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
1281 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
1282 ssl_socket_data
.SetNextProto(GetParam());
1283 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl_socket_data
);
1285 HostPortPair
host_port_pair("www.google.com", 80);
1286 scoped_refptr
<HttpNetworkSession
>
1287 session(SpdySessionDependencies::SpdyCreateSession(&session_deps
));
1289 // Now request a stream.
1290 HttpRequestInfo request_info
;
1291 request_info
.method
= "GET";
1292 request_info
.url
= GURL("wss://www.google.com");
1293 request_info
.load_flags
= 0;
1295 SSLConfig ssl_config
;
1296 StreamRequestWaiter waiter1
;
1297 WebSocketStreamCreateHelper create_helper
;
1298 scoped_ptr
<HttpStreamRequest
> request1(
1299 session
->http_stream_factory_for_websocket()
1300 ->RequestWebSocketHandshakeStream(request_info
,
1307 waiter1
.WaitForStream();
1308 EXPECT_TRUE(waiter1
.stream_done());
1309 ASSERT_TRUE(nullptr != waiter1
.websocket_stream());
1310 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy
,
1311 waiter1
.websocket_stream()->type());
1312 EXPECT_TRUE(nullptr == waiter1
.stream());
1314 StreamRequestWaiter waiter2
;
1315 scoped_ptr
<HttpStreamRequest
> request2(
1316 session
->http_stream_factory_for_websocket()
1317 ->RequestWebSocketHandshakeStream(request_info
,
1324 waiter2
.WaitForStream();
1325 EXPECT_TRUE(waiter2
.stream_done());
1326 ASSERT_TRUE(nullptr != waiter2
.websocket_stream());
1327 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy
,
1328 waiter2
.websocket_stream()->type());
1329 EXPECT_TRUE(nullptr == waiter2
.stream());
1330 EXPECT_NE(waiter2
.websocket_stream(), waiter1
.websocket_stream());
1331 EXPECT_EQ(static_cast<WebSocketSpdyHandshakeStream
*>(
1332 waiter2
.websocket_stream())->spdy_session(),
1333 static_cast<WebSocketSpdyHandshakeStream
*>(
1334 waiter1
.websocket_stream())->spdy_session());
1336 EXPECT_EQ(0, GetSocketPoolGroupCount(
1337 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1338 EXPECT_EQ(0, GetSocketPoolGroupCount(
1339 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1340 EXPECT_EQ(1, GetSocketPoolGroupCount(
1341 session
->GetTransportSocketPool(
1342 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1343 EXPECT_EQ(1, GetSocketPoolGroupCount(
1344 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1345 EXPECT_TRUE(waiter1
.used_proxy_info().is_direct());
1348 // TODO(ricea): Re-enable once WebSocket over SPDY is implemented.
1349 TEST_P(HttpStreamFactoryTest
, DISABLED_OrphanedWebSocketStream
) {
1350 SpdySessionDependencies
session_deps(GetParam(),
1351 ProxyService::CreateDirect());
1352 session_deps
.use_alternative_services
= true;
1354 MockRead
mock_read(ASYNC
, OK
);
1355 SequencedSocketData
socket_data(&mock_read
, 1, nullptr, 0);
1356 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
1357 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
1359 MockRead
mock_read2(ASYNC
, OK
);
1360 SequencedSocketData
socket_data2(&mock_read2
, 1, nullptr, 0);
1361 socket_data2
.set_connect_data(MockConnect(ASYNC
, ERR_IO_PENDING
));
1362 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data2
);
1364 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
1365 ssl_socket_data
.SetNextProto(GetParam());
1366 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl_socket_data
);
1368 scoped_refptr
<HttpNetworkSession
> session(
1369 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
1371 // Now request a stream.
1372 HttpRequestInfo request_info
;
1373 request_info
.method
= "GET";
1374 request_info
.url
= GURL("ws://www.google.com:8888");
1375 request_info
.load_flags
= 0;
1377 base::Time expiration
= base::Time::Now() + base::TimeDelta::FromDays(1);
1378 session
->http_server_properties()->SetAlternativeService(
1379 HostPortPair("www.google.com", 8888),
1380 AlternativeService(NPN_HTTP_2
, "www.google.com", 9999), 1.0, expiration
);
1382 SSLConfig ssl_config
;
1383 StreamRequestWaiter waiter
;
1384 WebSocketStreamCreateHelper create_helper
;
1385 scoped_ptr
<HttpStreamRequest
> request(
1386 session
->http_stream_factory_for_websocket()
1387 ->RequestWebSocketHandshakeStream(request_info
,
1394 waiter
.WaitForStream();
1395 EXPECT_TRUE(waiter
.stream_done());
1396 EXPECT_TRUE(nullptr == waiter
.stream());
1397 ASSERT_TRUE(nullptr != waiter
.websocket_stream());
1398 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy
,
1399 waiter
.websocket_stream()->type());
1401 // Make sure that there was an alternative connection
1402 // which consumes extra connections.
1403 EXPECT_EQ(0, GetSocketPoolGroupCount(
1404 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1405 EXPECT_EQ(0, GetSocketPoolGroupCount(
1406 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1407 EXPECT_EQ(2, GetSocketPoolGroupCount(
1408 session
->GetTransportSocketPool(
1409 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1410 EXPECT_EQ(1, GetSocketPoolGroupCount(
1411 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1412 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
1414 // Make sure there is no orphaned job. it is already canceled.
1415 ASSERT_EQ(0u, static_cast<HttpStreamFactoryImpl
*>(
1416 session
->http_stream_factory_for_websocket())->num_orphaned_jobs());