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
,
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 for (int i
= 1; i
<= 2; i
++) {
619 i
== 1 ? ERR_QUIC_PROTOCOL_ERROR
: ERR_QUIC_HANDSHAKE_FAILED
;
621 scoped_ptr
<ProxyService
> proxy_service
;
623 ProxyService::CreateFixedFromPacResult("QUIC bad:99; DIRECT"));
625 HttpNetworkSession::Params params
;
626 params
.enable_quic
= true;
627 params
.enable_quic_for_proxies
= true;
628 scoped_refptr
<SSLConfigServiceDefaults
> ssl_config_service(
629 new SSLConfigServiceDefaults
);
630 HttpServerPropertiesImpl http_server_properties
;
631 MockClientSocketFactory socket_factory
;
632 params
.client_socket_factory
= &socket_factory
;
633 MockHostResolver host_resolver
;
634 params
.host_resolver
= &host_resolver
;
635 TransportSecurityState transport_security_state
;
636 params
.transport_security_state
= &transport_security_state
;
637 params
.proxy_service
= proxy_service
.get();
638 params
.ssl_config_service
= ssl_config_service
.get();
639 params
.http_server_properties
= http_server_properties
.GetWeakPtr();
641 scoped_refptr
<HttpNetworkSession
> session
;
642 session
= new HttpNetworkSession(params
);
643 session
->quic_stream_factory()->set_require_confirmation(false);
645 StaticSocketDataProvider socket_data1
;
646 socket_data1
.set_connect_data(MockConnect(ASYNC
, mock_error
));
647 socket_factory
.AddSocketDataProvider(&socket_data1
);
649 // Second connection attempt succeeds.
650 StaticSocketDataProvider socket_data2
;
651 socket_data2
.set_connect_data(MockConnect(ASYNC
, OK
));
652 socket_factory
.AddSocketDataProvider(&socket_data2
);
654 // Now request a stream. It should succeed using the second proxy in the
656 HttpRequestInfo request_info
;
657 request_info
.method
= "GET";
658 request_info
.url
= GURL("http://www.google.com");
660 SSLConfig ssl_config
;
661 StreamRequestWaiter waiter
;
662 scoped_ptr
<HttpStreamRequest
> request(
663 session
->http_stream_factory()->RequestStream(
664 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
, &waiter
,
666 waiter
.WaitForStream();
668 // The proxy that failed should now be known to the proxy_service as bad.
669 const ProxyRetryInfoMap
& retry_info
=
670 session
->proxy_service()->proxy_retry_info();
671 EXPECT_EQ(1u, retry_info
.size()) << i
;
672 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
674 ProxyRetryInfoMap::const_iterator iter
= retry_info
.find("quic://bad:99");
675 EXPECT_TRUE(iter
!= retry_info
.end()) << i
;
681 TEST_P(HttpStreamFactoryTest
, QuicLossyProxyMarkedAsBad
) {
683 scoped_ptr
<ProxyService
> proxy_service
;
685 ProxyService::CreateFixedFromPacResult("QUIC bad:99; DIRECT"));
687 HttpNetworkSession::Params params
;
688 params
.enable_quic
= true;
689 params
.enable_quic_for_proxies
= true;
690 scoped_refptr
<SSLConfigServiceDefaults
> ssl_config_service(
691 new SSLConfigServiceDefaults
);
692 HttpServerPropertiesImpl http_server_properties
;
693 MockClientSocketFactory socket_factory
;
694 params
.client_socket_factory
= &socket_factory
;
695 MockHostResolver host_resolver
;
696 params
.host_resolver
= &host_resolver
;
697 TransportSecurityState transport_security_state
;
698 params
.transport_security_state
= &transport_security_state
;
699 params
.proxy_service
= proxy_service
.get();
700 params
.ssl_config_service
= ssl_config_service
.get();
701 params
.http_server_properties
= http_server_properties
.GetWeakPtr();
702 params
.quic_max_number_of_lossy_connections
= 2;
704 scoped_refptr
<HttpNetworkSession
> session
;
705 session
= new HttpNetworkSession(params
);
706 session
->quic_stream_factory()->set_require_confirmation(false);
708 session
->quic_stream_factory()->number_of_lossy_connections_
[99] =
709 params
.quic_max_number_of_lossy_connections
;
711 StaticSocketDataProvider socket_data2
;
712 socket_data2
.set_connect_data(MockConnect(ASYNC
, OK
));
713 socket_factory
.AddSocketDataProvider(&socket_data2
);
715 // Now request a stream. It should succeed using the second proxy in the
717 HttpRequestInfo request_info
;
718 request_info
.method
= "GET";
719 request_info
.url
= GURL("http://www.google.com");
721 SSLConfig ssl_config
;
722 StreamRequestWaiter waiter
;
723 scoped_ptr
<HttpStreamRequest
> request(
724 session
->http_stream_factory()->RequestStream(
725 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
, &waiter
,
727 waiter
.WaitForStream();
729 // The proxy that failed should now be known to the proxy_service as bad.
730 const ProxyRetryInfoMap
& retry_info
=
731 session
->proxy_service()->proxy_retry_info();
732 EXPECT_EQ(1u, retry_info
.size());
733 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
735 ProxyRetryInfoMap::const_iterator iter
= retry_info
.find("quic://bad:99");
736 EXPECT_TRUE(iter
!= retry_info
.end());
741 TEST_P(HttpStreamFactoryTest
, PrivacyModeDisablesChannelId
) {
742 SpdySessionDependencies
session_deps(
743 GetParam(), ProxyService::CreateDirect());
745 StaticSocketDataProvider socket_data
;
746 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
747 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
749 SSLSocketDataProvider
ssl(ASYNC
, OK
);
750 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl
);
752 scoped_refptr
<HttpNetworkSession
> session(
753 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
755 // Set an existing SpdySession in the pool.
756 HostPortPair
host_port_pair("www.google.com", 443);
757 SpdySessionKey
key(host_port_pair
, ProxyServer::Direct(),
758 PRIVACY_MODE_ENABLED
);
760 HttpRequestInfo request_info
;
761 request_info
.method
= "GET";
762 request_info
.url
= GURL("https://www.google.com");
763 request_info
.load_flags
= 0;
764 request_info
.privacy_mode
= PRIVACY_MODE_DISABLED
;
766 SSLConfig ssl_config
;
767 StreamRequestWaiter waiter
;
768 scoped_ptr
<HttpStreamRequest
> request(
769 session
->http_stream_factory()->RequestStream(
770 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
,
771 &waiter
, BoundNetLog()));
772 waiter
.WaitForStream();
774 // The stream shouldn't come from spdy as we are using different privacy mode
775 EXPECT_FALSE(request
->using_spdy());
777 SSLConfig used_ssl_config
= waiter
.used_ssl_config();
778 EXPECT_EQ(used_ssl_config
.channel_id_enabled
, ssl_config
.channel_id_enabled
);
782 // Return count of distinct groups in given socket pool.
783 int GetSocketPoolGroupCount(ClientSocketPool
* pool
) {
785 scoped_ptr
<base::DictionaryValue
> dict(pool
->GetInfoAsValue("", "", false));
786 EXPECT_TRUE(dict
!= nullptr);
787 base::DictionaryValue
* groups
= nullptr;
788 if (dict
->GetDictionary("groups", &groups
) && (groups
!= nullptr)) {
789 count
= static_cast<int>(groups
->size());
795 TEST_P(HttpStreamFactoryTest
, PrivacyModeUsesDifferentSocketPoolGroup
) {
796 SpdySessionDependencies
session_deps(
797 GetParam(), ProxyService::CreateDirect());
799 StaticSocketDataProvider socket_data
;
800 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
801 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
803 SSLSocketDataProvider
ssl(ASYNC
, OK
);
804 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl
);
806 scoped_refptr
<HttpNetworkSession
> session(
807 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
808 SSLClientSocketPool
* ssl_pool
= session
->GetSSLSocketPool(
809 HttpNetworkSession::NORMAL_SOCKET_POOL
);
811 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool
), 0);
813 HttpRequestInfo request_info
;
814 request_info
.method
= "GET";
815 request_info
.url
= GURL("https://www.google.com");
816 request_info
.load_flags
= 0;
817 request_info
.privacy_mode
= PRIVACY_MODE_DISABLED
;
819 SSLConfig ssl_config
;
820 StreamRequestWaiter waiter
;
822 scoped_ptr
<HttpStreamRequest
> request1(
823 session
->http_stream_factory()->RequestStream(
824 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
,
825 &waiter
, BoundNetLog()));
826 waiter
.WaitForStream();
828 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool
), 1);
830 scoped_ptr
<HttpStreamRequest
> request2(
831 session
->http_stream_factory()->RequestStream(
832 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
,
833 &waiter
, BoundNetLog()));
834 waiter
.WaitForStream();
836 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool
), 1);
838 request_info
.privacy_mode
= PRIVACY_MODE_ENABLED
;
839 scoped_ptr
<HttpStreamRequest
> request3(
840 session
->http_stream_factory()->RequestStream(
841 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
,
842 &waiter
, BoundNetLog()));
843 waiter
.WaitForStream();
845 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool
), 2);
848 TEST_P(HttpStreamFactoryTest
, GetLoadState
) {
849 SpdySessionDependencies
session_deps(
850 GetParam(), ProxyService::CreateDirect());
852 StaticSocketDataProvider socket_data
;
853 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
854 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
856 scoped_refptr
<HttpNetworkSession
> session(
857 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
859 HttpRequestInfo request_info
;
860 request_info
.method
= "GET";
861 request_info
.url
= GURL("http://www.google.com");
863 SSLConfig ssl_config
;
864 StreamRequestWaiter waiter
;
865 scoped_ptr
<HttpStreamRequest
> request(
866 session
->http_stream_factory()->RequestStream(
867 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
,
868 &waiter
, BoundNetLog()));
870 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST
, request
->GetLoadState());
872 waiter
.WaitForStream();
875 TEST_P(HttpStreamFactoryTest
, RequestHttpStream
) {
876 SpdySessionDependencies
session_deps(
877 GetParam(), ProxyService::CreateDirect());
879 StaticSocketDataProvider socket_data
;
880 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
881 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
883 scoped_refptr
<HttpNetworkSession
> session(
884 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
886 // Now request a stream. It should succeed using the second proxy in the
888 HttpRequestInfo request_info
;
889 request_info
.method
= "GET";
890 request_info
.url
= GURL("http://www.google.com");
891 request_info
.load_flags
= 0;
893 SSLConfig ssl_config
;
894 StreamRequestWaiter waiter
;
895 scoped_ptr
<HttpStreamRequest
> request(
896 session
->http_stream_factory()->RequestStream(
903 waiter
.WaitForStream();
904 EXPECT_TRUE(waiter
.stream_done());
905 ASSERT_TRUE(nullptr != waiter
.stream());
906 EXPECT_TRUE(nullptr == waiter
.websocket_stream());
907 EXPECT_FALSE(waiter
.stream()->IsSpdyHttpStream());
909 EXPECT_EQ(1, GetSocketPoolGroupCount(
910 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
911 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSSLSocketPool(
912 HttpNetworkSession::NORMAL_SOCKET_POOL
)));
913 EXPECT_EQ(0, GetSocketPoolGroupCount(
914 session
->GetTransportSocketPool(
915 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
916 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSSLSocketPool(
917 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
918 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
921 TEST_P(HttpStreamFactoryTest
, RequestHttpStreamOverSSL
) {
922 SpdySessionDependencies
session_deps(
923 GetParam(), ProxyService::CreateDirect());
925 MockRead
mock_read(ASYNC
, OK
);
926 StaticSocketDataProvider
socket_data(&mock_read
, 1, nullptr, 0);
927 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
928 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
930 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
931 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl_socket_data
);
933 scoped_refptr
<HttpNetworkSession
> session(
934 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
936 // Now request a stream.
937 HttpRequestInfo request_info
;
938 request_info
.method
= "GET";
939 request_info
.url
= GURL("https://www.google.com");
940 request_info
.load_flags
= 0;
942 SSLConfig ssl_config
;
943 StreamRequestWaiter waiter
;
944 scoped_ptr
<HttpStreamRequest
> request(
945 session
->http_stream_factory()->RequestStream(
952 waiter
.WaitForStream();
953 EXPECT_TRUE(waiter
.stream_done());
954 ASSERT_TRUE(nullptr != waiter
.stream());
955 EXPECT_TRUE(nullptr == waiter
.websocket_stream());
956 EXPECT_FALSE(waiter
.stream()->IsSpdyHttpStream());
957 EXPECT_EQ(1, GetSocketPoolGroupCount(
958 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
959 EXPECT_EQ(1, GetSocketPoolGroupCount(
960 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
961 EXPECT_EQ(0, GetSocketPoolGroupCount(
962 session
->GetTransportSocketPool(
963 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
964 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSSLSocketPool(
965 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
966 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
969 TEST_P(HttpStreamFactoryTest
, RequestHttpStreamOverProxy
) {
970 SpdySessionDependencies
session_deps(
971 GetParam(), ProxyService::CreateFixed("myproxy:8888"));
973 StaticSocketDataProvider socket_data
;
974 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
975 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
977 scoped_refptr
<HttpNetworkSession
> session(
978 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
980 // Now request a stream. It should succeed using the second proxy in the
982 HttpRequestInfo request_info
;
983 request_info
.method
= "GET";
984 request_info
.url
= GURL("http://www.google.com");
985 request_info
.load_flags
= 0;
987 SSLConfig ssl_config
;
988 StreamRequestWaiter waiter
;
989 scoped_ptr
<HttpStreamRequest
> request(
990 session
->http_stream_factory()->RequestStream(
997 waiter
.WaitForStream();
998 EXPECT_TRUE(waiter
.stream_done());
999 ASSERT_TRUE(nullptr != waiter
.stream());
1000 EXPECT_TRUE(nullptr == waiter
.websocket_stream());
1001 EXPECT_FALSE(waiter
.stream()->IsSpdyHttpStream());
1002 EXPECT_EQ(0, GetSocketPoolGroupCount(
1003 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1004 EXPECT_EQ(0, GetSocketPoolGroupCount(
1005 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1006 EXPECT_EQ(1, GetSocketPoolGroupCount(session
->GetSocketPoolForHTTPProxy(
1007 HttpNetworkSession::NORMAL_SOCKET_POOL
,
1008 HostPortPair("myproxy", 8888))));
1009 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSocketPoolForSSLWithProxy(
1010 HttpNetworkSession::NORMAL_SOCKET_POOL
,
1011 HostPortPair("myproxy", 8888))));
1012 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSocketPoolForHTTPProxy(
1013 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
,
1014 HostPortPair("myproxy", 8888))));
1015 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSocketPoolForSSLWithProxy(
1016 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
,
1017 HostPortPair("myproxy", 8888))));
1018 EXPECT_FALSE(waiter
.used_proxy_info().is_direct());
1021 TEST_P(HttpStreamFactoryTest
, RequestWebSocketBasicHandshakeStream
) {
1022 SpdySessionDependencies
session_deps(
1023 GetParam(), ProxyService::CreateDirect());
1025 StaticSocketDataProvider socket_data
;
1026 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
1027 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
1029 scoped_refptr
<HttpNetworkSession
> session(
1030 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
1032 // Now request a stream.
1033 HttpRequestInfo request_info
;
1034 request_info
.method
= "GET";
1035 request_info
.url
= GURL("ws://www.google.com");
1036 request_info
.load_flags
= 0;
1038 SSLConfig ssl_config
;
1039 StreamRequestWaiter waiter
;
1040 WebSocketStreamCreateHelper create_helper
;
1041 scoped_ptr
<HttpStreamRequest
> request(
1042 session
->http_stream_factory_for_websocket()
1043 ->RequestWebSocketHandshakeStream(request_info
,
1050 waiter
.WaitForStream();
1051 EXPECT_TRUE(waiter
.stream_done());
1052 EXPECT_TRUE(nullptr == waiter
.stream());
1053 ASSERT_TRUE(nullptr != waiter
.websocket_stream());
1054 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic
,
1055 waiter
.websocket_stream()->type());
1056 EXPECT_EQ(0, GetSocketPoolGroupCount(
1057 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1058 EXPECT_EQ(0, GetSocketPoolGroupCount(
1059 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1060 EXPECT_EQ(0, GetSocketPoolGroupCount(
1061 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1062 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
1065 TEST_P(HttpStreamFactoryTest
, RequestWebSocketBasicHandshakeStreamOverSSL
) {
1066 SpdySessionDependencies
session_deps(
1067 GetParam(), ProxyService::CreateDirect());
1069 MockRead
mock_read(ASYNC
, OK
);
1070 StaticSocketDataProvider
socket_data(&mock_read
, 1, nullptr, 0);
1071 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
1072 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
1074 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
1075 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl_socket_data
);
1077 scoped_refptr
<HttpNetworkSession
> session(
1078 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
1080 // Now request a stream.
1081 HttpRequestInfo request_info
;
1082 request_info
.method
= "GET";
1083 request_info
.url
= GURL("wss://www.google.com");
1084 request_info
.load_flags
= 0;
1086 SSLConfig ssl_config
;
1087 StreamRequestWaiter waiter
;
1088 WebSocketStreamCreateHelper create_helper
;
1089 scoped_ptr
<HttpStreamRequest
> request(
1090 session
->http_stream_factory_for_websocket()
1091 ->RequestWebSocketHandshakeStream(request_info
,
1098 waiter
.WaitForStream();
1099 EXPECT_TRUE(waiter
.stream_done());
1100 EXPECT_TRUE(nullptr == waiter
.stream());
1101 ASSERT_TRUE(nullptr != waiter
.websocket_stream());
1102 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic
,
1103 waiter
.websocket_stream()->type());
1104 EXPECT_EQ(0, GetSocketPoolGroupCount(
1105 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1106 EXPECT_EQ(0, GetSocketPoolGroupCount(
1107 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1108 EXPECT_EQ(1, GetSocketPoolGroupCount(
1109 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1110 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
1113 TEST_P(HttpStreamFactoryTest
, RequestWebSocketBasicHandshakeStreamOverProxy
) {
1114 SpdySessionDependencies
session_deps(
1115 GetParam(), ProxyService::CreateFixed("myproxy:8888"));
1117 MockRead
read(SYNCHRONOUS
, "HTTP/1.0 200 Connection established\r\n\r\n");
1118 StaticSocketDataProvider
socket_data(&read
, 1, 0, 0);
1119 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
1120 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
1122 scoped_refptr
<HttpNetworkSession
> session(
1123 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
1125 // Now request a stream.
1126 HttpRequestInfo request_info
;
1127 request_info
.method
= "GET";
1128 request_info
.url
= GURL("ws://www.google.com");
1129 request_info
.load_flags
= 0;
1131 SSLConfig ssl_config
;
1132 StreamRequestWaiter waiter
;
1133 WebSocketStreamCreateHelper create_helper
;
1134 scoped_ptr
<HttpStreamRequest
> request(
1135 session
->http_stream_factory_for_websocket()
1136 ->RequestWebSocketHandshakeStream(request_info
,
1143 waiter
.WaitForStream();
1144 EXPECT_TRUE(waiter
.stream_done());
1145 EXPECT_TRUE(nullptr == waiter
.stream());
1146 ASSERT_TRUE(nullptr != waiter
.websocket_stream());
1147 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic
,
1148 waiter
.websocket_stream()->type());
1149 EXPECT_EQ(0, GetSocketPoolGroupCount(
1150 session
->GetTransportSocketPool(
1151 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1152 EXPECT_EQ(0, GetSocketPoolGroupCount(
1153 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1154 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSocketPoolForHTTPProxy(
1155 HttpNetworkSession::NORMAL_SOCKET_POOL
,
1156 HostPortPair("myproxy", 8888))));
1157 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSocketPoolForSSLWithProxy(
1158 HttpNetworkSession::NORMAL_SOCKET_POOL
,
1159 HostPortPair("myproxy", 8888))));
1160 EXPECT_EQ(1, GetSocketPoolGroupCount(session
->GetSocketPoolForHTTPProxy(
1161 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
,
1162 HostPortPair("myproxy", 8888))));
1163 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSocketPoolForSSLWithProxy(
1164 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
,
1165 HostPortPair("myproxy", 8888))));
1166 EXPECT_FALSE(waiter
.used_proxy_info().is_direct());
1169 TEST_P(HttpStreamFactoryTest
, RequestSpdyHttpStream
) {
1170 SpdySessionDependencies
session_deps(GetParam(),
1171 ProxyService::CreateDirect());
1173 MockRead
mock_read(ASYNC
, OK
);
1174 SequencedSocketData
socket_data(&mock_read
, 1, nullptr, 0);
1175 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
1176 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
1178 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
1179 ssl_socket_data
.SetNextProto(GetParam());
1180 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl_socket_data
);
1182 HostPortPair
host_port_pair("www.google.com", 443);
1183 scoped_refptr
<HttpNetworkSession
> session(
1184 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
1186 // Now request a stream.
1187 HttpRequestInfo request_info
;
1188 request_info
.method
= "GET";
1189 request_info
.url
= GURL("https://www.google.com");
1190 request_info
.load_flags
= 0;
1192 SSLConfig ssl_config
;
1193 StreamRequestWaiter waiter
;
1194 scoped_ptr
<HttpStreamRequest
> request(
1195 session
->http_stream_factory()->RequestStream(
1202 waiter
.WaitForStream();
1203 EXPECT_TRUE(waiter
.stream_done());
1204 EXPECT_TRUE(nullptr == waiter
.websocket_stream());
1205 ASSERT_TRUE(nullptr != waiter
.stream());
1206 EXPECT_TRUE(waiter
.stream()->IsSpdyHttpStream());
1207 EXPECT_EQ(1, GetSocketPoolGroupCount(
1208 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1209 EXPECT_EQ(1, GetSocketPoolGroupCount(
1210 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1211 EXPECT_EQ(0, GetSocketPoolGroupCount(
1212 session
->GetTransportSocketPool(
1213 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1214 EXPECT_EQ(0, GetSocketPoolGroupCount(
1215 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1216 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
1219 // TODO(ricea): This test can be removed once the new WebSocket stack supports
1220 // SPDY. Currently, even if we connect to a SPDY-supporting server, we need to
1222 TEST_P(HttpStreamFactoryTest
, RequestWebSocketSpdyHandshakeStreamButGetSSL
) {
1223 SpdySessionDependencies
session_deps(GetParam(),
1224 ProxyService::CreateDirect());
1226 MockRead
mock_read(SYNCHRONOUS
, ERR_IO_PENDING
);
1227 StaticSocketDataProvider
socket_data(&mock_read
, 1, nullptr, 0);
1228 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
1229 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
1231 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
1232 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl_socket_data
);
1234 HostPortPair
host_port_pair("www.google.com", 80);
1235 scoped_refptr
<HttpNetworkSession
>
1236 session(SpdySessionDependencies::SpdyCreateSession(&session_deps
));
1238 // Now request a stream.
1239 HttpRequestInfo request_info
;
1240 request_info
.method
= "GET";
1241 request_info
.url
= GURL("wss://www.google.com");
1242 request_info
.load_flags
= 0;
1244 SSLConfig ssl_config
;
1245 StreamRequestWaiter waiter1
;
1246 WebSocketStreamCreateHelper create_helper
;
1247 scoped_ptr
<HttpStreamRequest
> request1(
1248 session
->http_stream_factory_for_websocket()
1249 ->RequestWebSocketHandshakeStream(request_info
,
1256 waiter1
.WaitForStream();
1257 EXPECT_TRUE(waiter1
.stream_done());
1258 ASSERT_TRUE(nullptr != waiter1
.websocket_stream());
1259 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic
,
1260 waiter1
.websocket_stream()->type());
1261 EXPECT_TRUE(nullptr == waiter1
.stream());
1263 EXPECT_EQ(0, GetSocketPoolGroupCount(
1264 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1265 EXPECT_EQ(0, GetSocketPoolGroupCount(
1266 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1267 EXPECT_EQ(1, GetSocketPoolGroupCount(
1268 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1269 EXPECT_TRUE(waiter1
.used_proxy_info().is_direct());
1272 // TODO(ricea): Re-enable once WebSocket-over-SPDY is implemented.
1273 TEST_P(HttpStreamFactoryTest
, DISABLED_RequestWebSocketSpdyHandshakeStream
) {
1274 SpdySessionDependencies
session_deps(GetParam(),
1275 ProxyService::CreateDirect());
1277 MockRead
mock_read(SYNCHRONOUS
, ERR_IO_PENDING
);
1278 StaticSocketDataProvider
socket_data(&mock_read
, 1, nullptr, 0);
1279 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
1280 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
1282 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
1283 ssl_socket_data
.SetNextProto(GetParam());
1284 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl_socket_data
);
1286 HostPortPair
host_port_pair("www.google.com", 80);
1287 scoped_refptr
<HttpNetworkSession
>
1288 session(SpdySessionDependencies::SpdyCreateSession(&session_deps
));
1290 // Now request a stream.
1291 HttpRequestInfo request_info
;
1292 request_info
.method
= "GET";
1293 request_info
.url
= GURL("wss://www.google.com");
1294 request_info
.load_flags
= 0;
1296 SSLConfig ssl_config
;
1297 StreamRequestWaiter waiter1
;
1298 WebSocketStreamCreateHelper create_helper
;
1299 scoped_ptr
<HttpStreamRequest
> request1(
1300 session
->http_stream_factory_for_websocket()
1301 ->RequestWebSocketHandshakeStream(request_info
,
1308 waiter1
.WaitForStream();
1309 EXPECT_TRUE(waiter1
.stream_done());
1310 ASSERT_TRUE(nullptr != waiter1
.websocket_stream());
1311 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy
,
1312 waiter1
.websocket_stream()->type());
1313 EXPECT_TRUE(nullptr == waiter1
.stream());
1315 StreamRequestWaiter waiter2
;
1316 scoped_ptr
<HttpStreamRequest
> request2(
1317 session
->http_stream_factory_for_websocket()
1318 ->RequestWebSocketHandshakeStream(request_info
,
1325 waiter2
.WaitForStream();
1326 EXPECT_TRUE(waiter2
.stream_done());
1327 ASSERT_TRUE(nullptr != waiter2
.websocket_stream());
1328 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy
,
1329 waiter2
.websocket_stream()->type());
1330 EXPECT_TRUE(nullptr == waiter2
.stream());
1331 EXPECT_NE(waiter2
.websocket_stream(), waiter1
.websocket_stream());
1332 EXPECT_EQ(static_cast<WebSocketSpdyHandshakeStream
*>(
1333 waiter2
.websocket_stream())->spdy_session(),
1334 static_cast<WebSocketSpdyHandshakeStream
*>(
1335 waiter1
.websocket_stream())->spdy_session());
1337 EXPECT_EQ(0, GetSocketPoolGroupCount(
1338 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1339 EXPECT_EQ(0, GetSocketPoolGroupCount(
1340 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1341 EXPECT_EQ(1, GetSocketPoolGroupCount(
1342 session
->GetTransportSocketPool(
1343 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1344 EXPECT_EQ(1, GetSocketPoolGroupCount(
1345 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1346 EXPECT_TRUE(waiter1
.used_proxy_info().is_direct());
1349 // TODO(ricea): Re-enable once WebSocket over SPDY is implemented.
1350 TEST_P(HttpStreamFactoryTest
, DISABLED_OrphanedWebSocketStream
) {
1351 SpdySessionDependencies
session_deps(GetParam(),
1352 ProxyService::CreateDirect());
1353 session_deps
.use_alternate_protocols
= true;
1355 MockRead
mock_read(ASYNC
, OK
);
1356 SequencedSocketData
socket_data(&mock_read
, 1, nullptr, 0);
1357 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
1358 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
1360 MockRead
mock_read2(ASYNC
, OK
);
1361 SequencedSocketData
socket_data2(&mock_read2
, 1, nullptr, 0);
1362 socket_data2
.set_connect_data(MockConnect(ASYNC
, ERR_IO_PENDING
));
1363 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data2
);
1365 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
1366 ssl_socket_data
.SetNextProto(GetParam());
1367 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl_socket_data
);
1369 scoped_refptr
<HttpNetworkSession
> session(
1370 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
1372 // Now request a stream.
1373 HttpRequestInfo request_info
;
1374 request_info
.method
= "GET";
1375 request_info
.url
= GURL("ws://www.google.com:8888");
1376 request_info
.load_flags
= 0;
1378 base::Time expiration
= base::Time::Now() + base::TimeDelta::FromDays(1);
1379 session
->http_server_properties()->SetAlternativeService(
1380 HostPortPair("www.google.com", 8888),
1381 AlternativeService(NPN_HTTP_2
, "www.google.com", 9999), 1.0, expiration
);
1383 SSLConfig ssl_config
;
1384 StreamRequestWaiter waiter
;
1385 WebSocketStreamCreateHelper create_helper
;
1386 scoped_ptr
<HttpStreamRequest
> request(
1387 session
->http_stream_factory_for_websocket()
1388 ->RequestWebSocketHandshakeStream(request_info
,
1395 waiter
.WaitForStream();
1396 EXPECT_TRUE(waiter
.stream_done());
1397 EXPECT_TRUE(nullptr == waiter
.stream());
1398 ASSERT_TRUE(nullptr != waiter
.websocket_stream());
1399 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy
,
1400 waiter
.websocket_stream()->type());
1402 // Make sure that there was an alternative connection
1403 // which consumes extra connections.
1404 EXPECT_EQ(0, GetSocketPoolGroupCount(
1405 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1406 EXPECT_EQ(0, GetSocketPoolGroupCount(
1407 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1408 EXPECT_EQ(2, GetSocketPoolGroupCount(
1409 session
->GetTransportSocketPool(
1410 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1411 EXPECT_EQ(1, GetSocketPoolGroupCount(
1412 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1413 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
1415 // Make sure there is no orphaned job. it is already canceled.
1416 ASSERT_EQ(0u, static_cast<HttpStreamFactoryImpl
*>(
1417 session
->http_stream_factory_for_websocket())->num_orphaned_jobs());