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/test_completion_callback.h"
13 #include "net/cert/mock_cert_verifier.h"
14 #include "net/dns/mock_host_resolver.h"
15 #include "net/http/http_auth_handler_factory.h"
16 #include "net/http/http_network_session.h"
17 #include "net/http/http_network_session_peer.h"
18 #include "net/http/http_network_transaction.h"
19 #include "net/http/http_request_info.h"
20 #include "net/http/http_server_properties.h"
21 #include "net/http/http_server_properties_impl.h"
22 #include "net/http/http_stream.h"
23 #include "net/http/transport_security_state.h"
24 #include "net/log/net_log.h"
25 #include "net/proxy/proxy_info.h"
26 #include "net/proxy/proxy_service.h"
27 #include "net/socket/client_socket_handle.h"
28 #include "net/socket/mock_client_socket_pool_manager.h"
29 #include "net/socket/next_proto.h"
30 #include "net/socket/socket_test_util.h"
31 #include "net/spdy/spdy_session.h"
32 #include "net/spdy/spdy_session_pool.h"
33 #include "net/spdy/spdy_test_util_common.h"
34 #include "net/ssl/ssl_config_service.h"
35 #include "net/ssl/ssl_config_service_defaults.h"
36 // This file can be included from net/http even though
37 // it is in net/websockets because it doesn't
38 // introduce any link dependency to net/websockets.
39 #include "net/websockets/websocket_handshake_stream_base.h"
40 #include "testing/gtest/include/gtest/gtest.h"
46 class MockWebSocketHandshakeStream
: public WebSocketHandshakeStreamBase
{
53 explicit MockWebSocketHandshakeStream(StreamType type
) : type_(type
) {}
55 ~MockWebSocketHandshakeStream() override
{}
57 StreamType
type() const {
62 int InitializeStream(const HttpRequestInfo
* request_info
,
63 RequestPriority priority
,
64 const BoundNetLog
& net_log
,
65 const CompletionCallback
& callback
) override
{
66 return ERR_IO_PENDING
;
68 int SendRequest(const HttpRequestHeaders
& request_headers
,
69 HttpResponseInfo
* response
,
70 const CompletionCallback
& callback
) override
{
71 return ERR_IO_PENDING
;
73 int ReadResponseHeaders(const CompletionCallback
& callback
) override
{
74 return ERR_IO_PENDING
;
76 int ReadResponseBody(IOBuffer
* buf
,
78 const CompletionCallback
& callback
) override
{
79 return ERR_IO_PENDING
;
81 void Close(bool not_reusable
) override
{}
82 bool IsResponseBodyComplete() const override
{ return false; }
83 bool CanFindEndOfResponse() const override
{ return false; }
84 bool IsConnectionReused() const override
{ return false; }
85 void SetConnectionReused() override
{}
86 bool IsConnectionReusable() const override
{ return false; }
87 int64
GetTotalReceivedBytes() const override
{ return 0; }
88 bool GetLoadTimingInfo(LoadTimingInfo
* load_timing_info
) const override
{
91 void GetSSLInfo(SSLInfo
* ssl_info
) override
{}
92 void GetSSLCertRequestInfo(SSLCertRequestInfo
* cert_request_info
) override
{}
93 bool IsSpdyHttpStream() const override
{ return false; }
94 void Drain(HttpNetworkSession
* session
) override
{}
95 void SetPriority(RequestPriority priority
) override
{}
96 UploadProgress
GetUploadProgress() const override
{ return UploadProgress(); }
97 HttpStream
* RenewStreamForAuth() override
{ return nullptr; }
99 scoped_ptr
<WebSocketStream
> Upgrade() override
{
100 return scoped_ptr
<WebSocketStream
>();
104 const StreamType type_
;
107 // HttpStreamFactoryImpl subclass that can wait until a preconnect is complete.
108 class MockHttpStreamFactoryImplForPreconnect
: public HttpStreamFactoryImpl
{
110 MockHttpStreamFactoryImplForPreconnect(HttpNetworkSession
* session
,
112 : HttpStreamFactoryImpl(session
, for_websockets
),
113 preconnect_done_(false),
114 waiting_for_preconnect_(false) {}
117 void WaitForPreconnects() {
118 while (!preconnect_done_
) {
119 waiting_for_preconnect_
= true;
120 base::MessageLoop::current()->Run();
121 waiting_for_preconnect_
= false;
126 // HttpStreamFactoryImpl methods.
127 void OnPreconnectsCompleteInternal() override
{
128 preconnect_done_
= true;
129 if (waiting_for_preconnect_
)
130 base::MessageLoop::current()->Quit();
133 bool preconnect_done_
;
134 bool waiting_for_preconnect_
;
137 class StreamRequestWaiter
: public HttpStreamRequest::Delegate
{
139 StreamRequestWaiter()
140 : waiting_for_stream_(false),
141 stream_done_(false) {}
143 // HttpStreamRequest::Delegate
145 void OnStreamReady(const SSLConfig
& used_ssl_config
,
146 const ProxyInfo
& used_proxy_info
,
147 HttpStream
* stream
) override
{
149 if (waiting_for_stream_
)
150 base::MessageLoop::current()->Quit();
151 stream_
.reset(stream
);
152 used_ssl_config_
= used_ssl_config
;
153 used_proxy_info_
= used_proxy_info
;
156 void OnWebSocketHandshakeStreamReady(
157 const SSLConfig
& used_ssl_config
,
158 const ProxyInfo
& used_proxy_info
,
159 WebSocketHandshakeStreamBase
* stream
) override
{
161 if (waiting_for_stream_
)
162 base::MessageLoop::current()->Quit();
163 websocket_stream_
.reset(stream
);
164 used_ssl_config_
= used_ssl_config
;
165 used_proxy_info_
= used_proxy_info
;
168 void OnStreamFailed(int status
, const SSLConfig
& used_ssl_config
) override
{}
170 void OnCertificateError(int status
,
171 const SSLConfig
& used_ssl_config
,
172 const SSLInfo
& ssl_info
) override
{}
174 void OnNeedsProxyAuth(const HttpResponseInfo
& proxy_response
,
175 const SSLConfig
& used_ssl_config
,
176 const ProxyInfo
& used_proxy_info
,
177 HttpAuthController
* auth_controller
) override
{}
179 void OnNeedsClientAuth(const SSLConfig
& used_ssl_config
,
180 SSLCertRequestInfo
* cert_info
) override
{}
182 void OnHttpsProxyTunnelResponse(const HttpResponseInfo
& response_info
,
183 const SSLConfig
& used_ssl_config
,
184 const ProxyInfo
& used_proxy_info
,
185 HttpStream
* stream
) override
{}
187 void WaitForStream() {
188 while (!stream_done_
) {
189 waiting_for_stream_
= true;
190 base::MessageLoop::current()->Run();
191 waiting_for_stream_
= false;
195 const SSLConfig
& used_ssl_config() const {
196 return used_ssl_config_
;
199 const ProxyInfo
& used_proxy_info() const {
200 return used_proxy_info_
;
203 HttpStream
* stream() {
204 return stream_
.get();
207 MockWebSocketHandshakeStream
* websocket_stream() {
208 return static_cast<MockWebSocketHandshakeStream
*>(websocket_stream_
.get());
211 bool stream_done() const { return stream_done_
; }
214 bool waiting_for_stream_
;
216 scoped_ptr
<HttpStream
> stream_
;
217 scoped_ptr
<WebSocketHandshakeStreamBase
> websocket_stream_
;
218 SSLConfig used_ssl_config_
;
219 ProxyInfo used_proxy_info_
;
221 DISALLOW_COPY_AND_ASSIGN(StreamRequestWaiter
);
224 class WebSocketSpdyHandshakeStream
: public MockWebSocketHandshakeStream
{
226 explicit WebSocketSpdyHandshakeStream(
227 const base::WeakPtr
<SpdySession
>& spdy_session
)
228 : MockWebSocketHandshakeStream(kStreamTypeSpdy
),
229 spdy_session_(spdy_session
) {}
231 ~WebSocketSpdyHandshakeStream() override
{}
233 SpdySession
* spdy_session() { return spdy_session_
.get(); }
236 base::WeakPtr
<SpdySession
> spdy_session_
;
239 class WebSocketBasicHandshakeStream
: public MockWebSocketHandshakeStream
{
241 explicit WebSocketBasicHandshakeStream(
242 scoped_ptr
<ClientSocketHandle
> connection
)
243 : MockWebSocketHandshakeStream(kStreamTypeBasic
),
244 connection_(connection
.Pass()) {}
246 ~WebSocketBasicHandshakeStream() override
{
247 connection_
->socket()->Disconnect();
250 ClientSocketHandle
* connection() { return connection_
.get(); }
253 scoped_ptr
<ClientSocketHandle
> connection_
;
256 class WebSocketStreamCreateHelper
257 : public WebSocketHandshakeStreamBase::CreateHelper
{
259 ~WebSocketStreamCreateHelper() override
{}
261 WebSocketHandshakeStreamBase
* CreateBasicStream(
262 scoped_ptr
<ClientSocketHandle
> connection
,
263 bool using_proxy
) override
{
264 return new WebSocketBasicHandshakeStream(connection
.Pass());
267 WebSocketHandshakeStreamBase
* CreateSpdyStream(
268 const base::WeakPtr
<SpdySession
>& spdy_session
,
269 bool use_relative_url
) override
{
270 return new WebSocketSpdyHandshakeStream(spdy_session
);
279 TestCase kTests
[] = {
286 void PreconnectHelperForURL(int num_streams
,
288 HttpNetworkSession
* session
) {
289 HttpNetworkSessionPeer
peer(session
);
290 MockHttpStreamFactoryImplForPreconnect
* mock_factory
=
291 new MockHttpStreamFactoryImplForPreconnect(session
, false);
292 peer
.SetHttpStreamFactory(scoped_ptr
<HttpStreamFactory
>(mock_factory
));
293 SSLConfig ssl_config
;
294 session
->ssl_config_service()->GetSSLConfig(&ssl_config
);
296 HttpRequestInfo request
;
297 request
.method
= "GET";
299 request
.load_flags
= 0;
301 session
->http_stream_factory()->PreconnectStreams(
302 num_streams
, request
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
);
303 mock_factory
->WaitForPreconnects();
306 void PreconnectHelper(const TestCase
& test
,
307 HttpNetworkSession
* session
) {
308 GURL url
= test
.ssl
? GURL("https://www.google.com") :
309 GURL("http://www.google.com");
310 PreconnectHelperForURL(test
.num_streams
, url
, session
);
313 template<typename ParentPool
>
314 class CapturePreconnectsSocketPool
: public ParentPool
{
316 CapturePreconnectsSocketPool(HostResolver
* host_resolver
,
317 CertVerifier
* cert_verifier
);
319 int last_num_streams() const {
320 return last_num_streams_
;
323 int RequestSocket(const std::string
& group_name
,
324 const void* socket_params
,
325 RequestPriority priority
,
326 ClientSocketHandle
* handle
,
327 const CompletionCallback
& callback
,
328 const BoundNetLog
& net_log
) override
{
330 return ERR_UNEXPECTED
;
333 void RequestSockets(const std::string
& group_name
,
334 const void* socket_params
,
336 const BoundNetLog
& net_log
) override
{
337 last_num_streams_
= num_sockets
;
340 void CancelRequest(const std::string
& group_name
,
341 ClientSocketHandle
* handle
) override
{
344 void ReleaseSocket(const std::string
& group_name
,
345 scoped_ptr
<StreamSocket
> socket
,
349 void CloseIdleSockets() override
{ ADD_FAILURE(); }
350 int IdleSocketCount() const override
{
354 int IdleSocketCountInGroup(const std::string
& group_name
) const override
{
358 LoadState
GetLoadState(const std::string
& group_name
,
359 const ClientSocketHandle
* handle
) const override
{
361 return LOAD_STATE_IDLE
;
363 base::TimeDelta
ConnectionTimeout() const override
{
364 return base::TimeDelta();
368 int last_num_streams_
;
371 typedef CapturePreconnectsSocketPool
<TransportClientSocketPool
>
372 CapturePreconnectsTransportSocketPool
;
373 typedef CapturePreconnectsSocketPool
<HttpProxyClientSocketPool
>
374 CapturePreconnectsHttpProxySocketPool
;
375 typedef CapturePreconnectsSocketPool
<SOCKSClientSocketPool
>
376 CapturePreconnectsSOCKSSocketPool
;
377 typedef CapturePreconnectsSocketPool
<SSLClientSocketPool
>
378 CapturePreconnectsSSLSocketPool
;
380 template <typename ParentPool
>
381 CapturePreconnectsSocketPool
<ParentPool
>::CapturePreconnectsSocketPool(
382 HostResolver
* host_resolver
,
383 CertVerifier
* /* cert_verifier */)
384 : ParentPool(0, 0, host_resolver
, nullptr, nullptr), last_num_streams_(-1) {
388 CapturePreconnectsHttpProxySocketPool::CapturePreconnectsSocketPool(
389 HostResolver
* /* host_resolver */,
390 CertVerifier
* /* cert_verifier */)
391 : HttpProxyClientSocketPool(0, 0, nullptr, nullptr, nullptr),
392 last_num_streams_(-1) {
396 CapturePreconnectsSSLSocketPool::CapturePreconnectsSocketPool(
397 HostResolver
* /* host_resolver */,
398 CertVerifier
* cert_verifier
)
399 : SSLClientSocketPool(0,
402 nullptr, // channel_id_store
403 nullptr, // transport_security_state
404 nullptr, // cert_transparency_verifier
405 nullptr, // cert_policy_enforcer
406 std::string(), // ssl_session_cache_shard
407 nullptr, // deterministic_socket_factory
408 nullptr, // transport_socket_pool
411 nullptr, // ssl_config_service
413 last_num_streams_(-1) {
416 class HttpStreamFactoryTest
: public ::testing::Test
,
417 public ::testing::WithParamInterface
<NextProto
> {
420 INSTANTIATE_TEST_CASE_P(NextProto
,
421 HttpStreamFactoryTest
,
422 testing::Values(kProtoSPDY31
,
426 TEST_P(HttpStreamFactoryTest
, PreconnectDirect
) {
427 for (size_t i
= 0; i
< arraysize(kTests
); ++i
) {
428 SpdySessionDependencies
session_deps(
429 GetParam(), ProxyService::CreateDirect());
430 scoped_refptr
<HttpNetworkSession
> session(
431 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
432 HttpNetworkSessionPeer
peer(session
);
433 CapturePreconnectsTransportSocketPool
* transport_conn_pool
=
434 new CapturePreconnectsTransportSocketPool(
435 session_deps
.host_resolver
.get(),
436 session_deps
.cert_verifier
.get());
437 CapturePreconnectsSSLSocketPool
* ssl_conn_pool
=
438 new CapturePreconnectsSSLSocketPool(
439 session_deps
.host_resolver
.get(),
440 session_deps
.cert_verifier
.get());
441 scoped_ptr
<MockClientSocketPoolManager
> mock_pool_manager(
442 new MockClientSocketPoolManager
);
443 mock_pool_manager
->SetTransportSocketPool(transport_conn_pool
);
444 mock_pool_manager
->SetSSLSocketPool(ssl_conn_pool
);
445 peer
.SetClientSocketPoolManager(mock_pool_manager
.Pass());
446 PreconnectHelper(kTests
[i
], session
.get());
448 EXPECT_EQ(kTests
[i
].num_streams
, ssl_conn_pool
->last_num_streams());
450 EXPECT_EQ(kTests
[i
].num_streams
, transport_conn_pool
->last_num_streams());
454 TEST_P(HttpStreamFactoryTest
, PreconnectHttpProxy
) {
455 for (size_t i
= 0; i
< arraysize(kTests
); ++i
) {
456 SpdySessionDependencies
session_deps(
457 GetParam(), ProxyService::CreateFixed("http_proxy"));
458 scoped_refptr
<HttpNetworkSession
> session(
459 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
460 HttpNetworkSessionPeer
peer(session
);
461 HostPortPair
proxy_host("http_proxy", 80);
462 CapturePreconnectsHttpProxySocketPool
* http_proxy_pool
=
463 new CapturePreconnectsHttpProxySocketPool(
464 session_deps
.host_resolver
.get(),
465 session_deps
.cert_verifier
.get());
466 CapturePreconnectsSSLSocketPool
* ssl_conn_pool
=
467 new CapturePreconnectsSSLSocketPool(
468 session_deps
.host_resolver
.get(),
469 session_deps
.cert_verifier
.get());
470 scoped_ptr
<MockClientSocketPoolManager
> mock_pool_manager(
471 new MockClientSocketPoolManager
);
472 mock_pool_manager
->SetSocketPoolForHTTPProxy(proxy_host
, http_proxy_pool
);
473 mock_pool_manager
->SetSocketPoolForSSLWithProxy(proxy_host
, ssl_conn_pool
);
474 peer
.SetClientSocketPoolManager(mock_pool_manager
.Pass());
475 PreconnectHelper(kTests
[i
], session
.get());
477 EXPECT_EQ(kTests
[i
].num_streams
, ssl_conn_pool
->last_num_streams());
479 EXPECT_EQ(kTests
[i
].num_streams
, http_proxy_pool
->last_num_streams());
483 TEST_P(HttpStreamFactoryTest
, PreconnectSocksProxy
) {
484 for (size_t i
= 0; i
< arraysize(kTests
); ++i
) {
485 SpdySessionDependencies
session_deps(
486 GetParam(), ProxyService::CreateFixed("socks4://socks_proxy:1080"));
487 scoped_refptr
<HttpNetworkSession
> session(
488 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
489 HttpNetworkSessionPeer
peer(session
);
490 HostPortPair
proxy_host("socks_proxy", 1080);
491 CapturePreconnectsSOCKSSocketPool
* socks_proxy_pool
=
492 new CapturePreconnectsSOCKSSocketPool(
493 session_deps
.host_resolver
.get(),
494 session_deps
.cert_verifier
.get());
495 CapturePreconnectsSSLSocketPool
* ssl_conn_pool
=
496 new CapturePreconnectsSSLSocketPool(
497 session_deps
.host_resolver
.get(),
498 session_deps
.cert_verifier
.get());
499 scoped_ptr
<MockClientSocketPoolManager
> mock_pool_manager(
500 new MockClientSocketPoolManager
);
501 mock_pool_manager
->SetSocketPoolForSOCKSProxy(proxy_host
, socks_proxy_pool
);
502 mock_pool_manager
->SetSocketPoolForSSLWithProxy(proxy_host
, ssl_conn_pool
);
503 peer
.SetClientSocketPoolManager(mock_pool_manager
.Pass());
504 PreconnectHelper(kTests
[i
], session
.get());
506 EXPECT_EQ(kTests
[i
].num_streams
, ssl_conn_pool
->last_num_streams());
508 EXPECT_EQ(kTests
[i
].num_streams
, socks_proxy_pool
->last_num_streams());
512 TEST_P(HttpStreamFactoryTest
, PreconnectDirectWithExistingSpdySession
) {
513 for (size_t i
= 0; i
< arraysize(kTests
); ++i
) {
514 SpdySessionDependencies
session_deps(
515 GetParam(), ProxyService::CreateDirect());
516 scoped_refptr
<HttpNetworkSession
> session(
517 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
518 HttpNetworkSessionPeer
peer(session
);
520 // Put a SpdySession in the pool.
521 HostPortPair
host_port_pair("www.google.com", 443);
522 SpdySessionKey
key(host_port_pair
, ProxyServer::Direct(),
523 PRIVACY_MODE_DISABLED
);
524 ignore_result(CreateFakeSpdySession(session
->spdy_session_pool(), key
));
526 CapturePreconnectsTransportSocketPool
* transport_conn_pool
=
527 new CapturePreconnectsTransportSocketPool(
528 session_deps
.host_resolver
.get(),
529 session_deps
.cert_verifier
.get());
530 CapturePreconnectsSSLSocketPool
* ssl_conn_pool
=
531 new CapturePreconnectsSSLSocketPool(
532 session_deps
.host_resolver
.get(),
533 session_deps
.cert_verifier
.get());
534 scoped_ptr
<MockClientSocketPoolManager
> mock_pool_manager(
535 new MockClientSocketPoolManager
);
536 mock_pool_manager
->SetTransportSocketPool(transport_conn_pool
);
537 mock_pool_manager
->SetSSLSocketPool(ssl_conn_pool
);
538 peer
.SetClientSocketPoolManager(mock_pool_manager
.Pass());
539 PreconnectHelper(kTests
[i
], session
.get());
540 // We shouldn't be preconnecting if we have an existing session, which is
541 // the case for https://www.google.com.
543 EXPECT_EQ(-1, ssl_conn_pool
->last_num_streams());
545 EXPECT_EQ(kTests
[i
].num_streams
,
546 transport_conn_pool
->last_num_streams());
550 // Verify that preconnects to unsafe ports are cancelled before they reach
552 TEST_P(HttpStreamFactoryTest
, PreconnectUnsafePort
) {
553 ASSERT_FALSE(IsPortAllowedByDefault(7));
554 ASSERT_FALSE(IsPortAllowedByOverride(7));
556 SpdySessionDependencies
session_deps(
557 GetParam(), ProxyService::CreateDirect());
558 scoped_refptr
<HttpNetworkSession
> session(
559 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
560 HttpNetworkSessionPeer
peer(session
);
561 CapturePreconnectsTransportSocketPool
* transport_conn_pool
=
562 new CapturePreconnectsTransportSocketPool(
563 session_deps
.host_resolver
.get(),
564 session_deps
.cert_verifier
.get());
565 scoped_ptr
<MockClientSocketPoolManager
> mock_pool_manager(
566 new MockClientSocketPoolManager
);
567 mock_pool_manager
->SetTransportSocketPool(transport_conn_pool
);
568 peer
.SetClientSocketPoolManager(mock_pool_manager
.Pass());
570 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 // proxy_headers_handler.proxy_info_used.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
;
679 TEST_P(HttpStreamFactoryTest
, PrivacyModeDisablesChannelId
) {
680 SpdySessionDependencies
session_deps(
681 GetParam(), ProxyService::CreateDirect());
683 StaticSocketDataProvider socket_data
;
684 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
685 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
687 SSLSocketDataProvider
ssl(ASYNC
, OK
);
688 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl
);
690 scoped_refptr
<HttpNetworkSession
> session(
691 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
693 // Set an existing SpdySession in the pool.
694 HostPortPair
host_port_pair("www.google.com", 443);
695 SpdySessionKey
key(host_port_pair
, ProxyServer::Direct(),
696 PRIVACY_MODE_ENABLED
);
698 HttpRequestInfo request_info
;
699 request_info
.method
= "GET";
700 request_info
.url
= GURL("https://www.google.com");
701 request_info
.load_flags
= 0;
702 request_info
.privacy_mode
= PRIVACY_MODE_DISABLED
;
704 SSLConfig ssl_config
;
705 StreamRequestWaiter waiter
;
706 scoped_ptr
<HttpStreamRequest
> request(
707 session
->http_stream_factory()->RequestStream(
708 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
,
709 &waiter
, BoundNetLog()));
710 waiter
.WaitForStream();
712 // The stream shouldn't come from spdy as we are using different privacy mode
713 EXPECT_FALSE(request
->using_spdy());
715 SSLConfig used_ssl_config
= waiter
.used_ssl_config();
716 EXPECT_EQ(used_ssl_config
.channel_id_enabled
, ssl_config
.channel_id_enabled
);
720 // Return count of distinct groups in given socket pool.
721 int GetSocketPoolGroupCount(ClientSocketPool
* pool
) {
723 scoped_ptr
<base::DictionaryValue
> dict(pool
->GetInfoAsValue("", "", false));
724 EXPECT_TRUE(dict
!= nullptr);
725 base::DictionaryValue
* groups
= nullptr;
726 if (dict
->GetDictionary("groups", &groups
) && (groups
!= nullptr)) {
727 count
= static_cast<int>(groups
->size());
733 TEST_P(HttpStreamFactoryTest
, PrivacyModeUsesDifferentSocketPoolGroup
) {
734 SpdySessionDependencies
session_deps(
735 GetParam(), ProxyService::CreateDirect());
737 StaticSocketDataProvider socket_data
;
738 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
739 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
741 SSLSocketDataProvider
ssl(ASYNC
, OK
);
742 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl
);
744 scoped_refptr
<HttpNetworkSession
> session(
745 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
746 SSLClientSocketPool
* ssl_pool
= session
->GetSSLSocketPool(
747 HttpNetworkSession::NORMAL_SOCKET_POOL
);
749 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool
), 0);
751 HttpRequestInfo request_info
;
752 request_info
.method
= "GET";
753 request_info
.url
= GURL("https://www.google.com");
754 request_info
.load_flags
= 0;
755 request_info
.privacy_mode
= PRIVACY_MODE_DISABLED
;
757 SSLConfig ssl_config
;
758 StreamRequestWaiter waiter
;
760 scoped_ptr
<HttpStreamRequest
> request1(
761 session
->http_stream_factory()->RequestStream(
762 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
,
763 &waiter
, BoundNetLog()));
764 waiter
.WaitForStream();
766 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool
), 1);
768 scoped_ptr
<HttpStreamRequest
> request2(
769 session
->http_stream_factory()->RequestStream(
770 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
,
771 &waiter
, BoundNetLog()));
772 waiter
.WaitForStream();
774 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool
), 1);
776 request_info
.privacy_mode
= PRIVACY_MODE_ENABLED
;
777 scoped_ptr
<HttpStreamRequest
> request3(
778 session
->http_stream_factory()->RequestStream(
779 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
,
780 &waiter
, BoundNetLog()));
781 waiter
.WaitForStream();
783 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool
), 2);
786 TEST_P(HttpStreamFactoryTest
, GetLoadState
) {
787 SpdySessionDependencies
session_deps(
788 GetParam(), ProxyService::CreateDirect());
790 StaticSocketDataProvider socket_data
;
791 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
792 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
794 scoped_refptr
<HttpNetworkSession
> session(
795 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
797 HttpRequestInfo request_info
;
798 request_info
.method
= "GET";
799 request_info
.url
= GURL("http://www.google.com");
801 SSLConfig ssl_config
;
802 StreamRequestWaiter waiter
;
803 scoped_ptr
<HttpStreamRequest
> request(
804 session
->http_stream_factory()->RequestStream(
805 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
,
806 &waiter
, BoundNetLog()));
808 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST
, request
->GetLoadState());
810 waiter
.WaitForStream();
813 TEST_P(HttpStreamFactoryTest
, RequestHttpStream
) {
814 SpdySessionDependencies
session_deps(
815 GetParam(), ProxyService::CreateDirect());
817 StaticSocketDataProvider socket_data
;
818 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
819 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
821 scoped_refptr
<HttpNetworkSession
> session(
822 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
824 // Now request a stream. It should succeed using the second proxy in the
826 HttpRequestInfo request_info
;
827 request_info
.method
= "GET";
828 request_info
.url
= GURL("http://www.google.com");
829 request_info
.load_flags
= 0;
831 SSLConfig ssl_config
;
832 StreamRequestWaiter waiter
;
833 scoped_ptr
<HttpStreamRequest
> request(
834 session
->http_stream_factory()->RequestStream(
841 waiter
.WaitForStream();
842 EXPECT_TRUE(waiter
.stream_done());
843 ASSERT_TRUE(nullptr != waiter
.stream());
844 EXPECT_TRUE(nullptr == waiter
.websocket_stream());
845 EXPECT_FALSE(waiter
.stream()->IsSpdyHttpStream());
847 EXPECT_EQ(1, GetSocketPoolGroupCount(
848 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
849 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSSLSocketPool(
850 HttpNetworkSession::NORMAL_SOCKET_POOL
)));
851 EXPECT_EQ(0, GetSocketPoolGroupCount(
852 session
->GetTransportSocketPool(
853 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
854 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSSLSocketPool(
855 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
856 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
859 TEST_P(HttpStreamFactoryTest
, RequestHttpStreamOverSSL
) {
860 SpdySessionDependencies
session_deps(
861 GetParam(), ProxyService::CreateDirect());
863 MockRead
mock_read(ASYNC
, OK
);
864 StaticSocketDataProvider
socket_data(&mock_read
, 1, nullptr, 0);
865 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
866 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
868 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
869 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl_socket_data
);
871 scoped_refptr
<HttpNetworkSession
> session(
872 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
874 // Now request a stream.
875 HttpRequestInfo request_info
;
876 request_info
.method
= "GET";
877 request_info
.url
= GURL("https://www.google.com");
878 request_info
.load_flags
= 0;
880 SSLConfig ssl_config
;
881 StreamRequestWaiter waiter
;
882 scoped_ptr
<HttpStreamRequest
> request(
883 session
->http_stream_factory()->RequestStream(
890 waiter
.WaitForStream();
891 EXPECT_TRUE(waiter
.stream_done());
892 ASSERT_TRUE(nullptr != waiter
.stream());
893 EXPECT_TRUE(nullptr == waiter
.websocket_stream());
894 EXPECT_FALSE(waiter
.stream()->IsSpdyHttpStream());
895 EXPECT_EQ(1, GetSocketPoolGroupCount(
896 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
897 EXPECT_EQ(1, GetSocketPoolGroupCount(
898 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
899 EXPECT_EQ(0, GetSocketPoolGroupCount(
900 session
->GetTransportSocketPool(
901 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
902 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSSLSocketPool(
903 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
904 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
907 TEST_P(HttpStreamFactoryTest
, RequestHttpStreamOverProxy
) {
908 SpdySessionDependencies
session_deps(
909 GetParam(), ProxyService::CreateFixed("myproxy:8888"));
911 StaticSocketDataProvider socket_data
;
912 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
913 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
915 scoped_refptr
<HttpNetworkSession
> session(
916 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
918 // Now request a stream. It should succeed using the second proxy in the
920 HttpRequestInfo request_info
;
921 request_info
.method
= "GET";
922 request_info
.url
= GURL("http://www.google.com");
923 request_info
.load_flags
= 0;
925 SSLConfig ssl_config
;
926 StreamRequestWaiter waiter
;
927 scoped_ptr
<HttpStreamRequest
> request(
928 session
->http_stream_factory()->RequestStream(
935 waiter
.WaitForStream();
936 EXPECT_TRUE(waiter
.stream_done());
937 ASSERT_TRUE(nullptr != waiter
.stream());
938 EXPECT_TRUE(nullptr == waiter
.websocket_stream());
939 EXPECT_FALSE(waiter
.stream()->IsSpdyHttpStream());
940 EXPECT_EQ(0, GetSocketPoolGroupCount(
941 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
942 EXPECT_EQ(0, GetSocketPoolGroupCount(
943 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
944 EXPECT_EQ(1, GetSocketPoolGroupCount(session
->GetSocketPoolForHTTPProxy(
945 HttpNetworkSession::NORMAL_SOCKET_POOL
,
946 HostPortPair("myproxy", 8888))));
947 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSocketPoolForSSLWithProxy(
948 HttpNetworkSession::NORMAL_SOCKET_POOL
,
949 HostPortPair("myproxy", 8888))));
950 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSocketPoolForHTTPProxy(
951 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
,
952 HostPortPair("myproxy", 8888))));
953 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSocketPoolForSSLWithProxy(
954 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
,
955 HostPortPair("myproxy", 8888))));
956 EXPECT_FALSE(waiter
.used_proxy_info().is_direct());
959 TEST_P(HttpStreamFactoryTest
, RequestWebSocketBasicHandshakeStream
) {
960 SpdySessionDependencies
session_deps(
961 GetParam(), ProxyService::CreateDirect());
963 StaticSocketDataProvider socket_data
;
964 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
965 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
967 scoped_refptr
<HttpNetworkSession
> session(
968 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
970 // Now request a stream.
971 HttpRequestInfo request_info
;
972 request_info
.method
= "GET";
973 request_info
.url
= GURL("ws://www.google.com");
974 request_info
.load_flags
= 0;
976 SSLConfig ssl_config
;
977 StreamRequestWaiter waiter
;
978 WebSocketStreamCreateHelper create_helper
;
979 scoped_ptr
<HttpStreamRequest
> request(
980 session
->http_stream_factory_for_websocket()
981 ->RequestWebSocketHandshakeStream(request_info
,
988 waiter
.WaitForStream();
989 EXPECT_TRUE(waiter
.stream_done());
990 EXPECT_TRUE(nullptr == waiter
.stream());
991 ASSERT_TRUE(nullptr != waiter
.websocket_stream());
992 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic
,
993 waiter
.websocket_stream()->type());
994 EXPECT_EQ(0, GetSocketPoolGroupCount(
995 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
996 EXPECT_EQ(0, GetSocketPoolGroupCount(
997 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
998 EXPECT_EQ(0, GetSocketPoolGroupCount(
999 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1000 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
1003 TEST_P(HttpStreamFactoryTest
, RequestWebSocketBasicHandshakeStreamOverSSL
) {
1004 SpdySessionDependencies
session_deps(
1005 GetParam(), ProxyService::CreateDirect());
1007 MockRead
mock_read(ASYNC
, OK
);
1008 StaticSocketDataProvider
socket_data(&mock_read
, 1, nullptr, 0);
1009 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
1010 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
1012 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
1013 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl_socket_data
);
1015 scoped_refptr
<HttpNetworkSession
> session(
1016 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
1018 // Now request a stream.
1019 HttpRequestInfo request_info
;
1020 request_info
.method
= "GET";
1021 request_info
.url
= GURL("wss://www.google.com");
1022 request_info
.load_flags
= 0;
1024 SSLConfig ssl_config
;
1025 StreamRequestWaiter waiter
;
1026 WebSocketStreamCreateHelper create_helper
;
1027 scoped_ptr
<HttpStreamRequest
> request(
1028 session
->http_stream_factory_for_websocket()
1029 ->RequestWebSocketHandshakeStream(request_info
,
1036 waiter
.WaitForStream();
1037 EXPECT_TRUE(waiter
.stream_done());
1038 EXPECT_TRUE(nullptr == waiter
.stream());
1039 ASSERT_TRUE(nullptr != waiter
.websocket_stream());
1040 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic
,
1041 waiter
.websocket_stream()->type());
1042 EXPECT_EQ(0, GetSocketPoolGroupCount(
1043 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1044 EXPECT_EQ(0, GetSocketPoolGroupCount(
1045 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1046 EXPECT_EQ(1, GetSocketPoolGroupCount(
1047 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1048 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
1051 TEST_P(HttpStreamFactoryTest
, RequestWebSocketBasicHandshakeStreamOverProxy
) {
1052 SpdySessionDependencies
session_deps(
1053 GetParam(), ProxyService::CreateFixed("myproxy:8888"));
1055 MockRead
read(SYNCHRONOUS
, "HTTP/1.0 200 Connection established\r\n\r\n");
1056 StaticSocketDataProvider
socket_data(&read
, 1, 0, 0);
1057 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
1058 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
1060 scoped_refptr
<HttpNetworkSession
> session(
1061 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
1063 // Now request a stream.
1064 HttpRequestInfo request_info
;
1065 request_info
.method
= "GET";
1066 request_info
.url
= GURL("ws://www.google.com");
1067 request_info
.load_flags
= 0;
1069 SSLConfig ssl_config
;
1070 StreamRequestWaiter waiter
;
1071 WebSocketStreamCreateHelper create_helper
;
1072 scoped_ptr
<HttpStreamRequest
> request(
1073 session
->http_stream_factory_for_websocket()
1074 ->RequestWebSocketHandshakeStream(request_info
,
1081 waiter
.WaitForStream();
1082 EXPECT_TRUE(waiter
.stream_done());
1083 EXPECT_TRUE(nullptr == waiter
.stream());
1084 ASSERT_TRUE(nullptr != waiter
.websocket_stream());
1085 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic
,
1086 waiter
.websocket_stream()->type());
1087 EXPECT_EQ(0, GetSocketPoolGroupCount(
1088 session
->GetTransportSocketPool(
1089 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1090 EXPECT_EQ(0, GetSocketPoolGroupCount(
1091 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1092 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSocketPoolForHTTPProxy(
1093 HttpNetworkSession::NORMAL_SOCKET_POOL
,
1094 HostPortPair("myproxy", 8888))));
1095 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSocketPoolForSSLWithProxy(
1096 HttpNetworkSession::NORMAL_SOCKET_POOL
,
1097 HostPortPair("myproxy", 8888))));
1098 EXPECT_EQ(1, GetSocketPoolGroupCount(session
->GetSocketPoolForHTTPProxy(
1099 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
,
1100 HostPortPair("myproxy", 8888))));
1101 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSocketPoolForSSLWithProxy(
1102 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
,
1103 HostPortPair("myproxy", 8888))));
1104 EXPECT_FALSE(waiter
.used_proxy_info().is_direct());
1107 TEST_P(HttpStreamFactoryTest
, RequestSpdyHttpStream
) {
1108 SpdySessionDependencies
session_deps(GetParam(),
1109 ProxyService::CreateDirect());
1111 MockRead
mock_read(ASYNC
, OK
);
1112 DeterministicSocketData
socket_data(&mock_read
, 1, nullptr, 0);
1113 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
1114 session_deps
.deterministic_socket_factory
->AddSocketDataProvider(
1117 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
1118 ssl_socket_data
.SetNextProto(GetParam());
1119 session_deps
.deterministic_socket_factory
->AddSSLSocketDataProvider(
1122 HostPortPair
host_port_pair("www.google.com", 443);
1123 scoped_refptr
<HttpNetworkSession
>
1124 session(SpdySessionDependencies::SpdyCreateSessionDeterministic(
1127 // Now request a stream.
1128 HttpRequestInfo request_info
;
1129 request_info
.method
= "GET";
1130 request_info
.url
= GURL("https://www.google.com");
1131 request_info
.load_flags
= 0;
1133 SSLConfig ssl_config
;
1134 StreamRequestWaiter waiter
;
1135 scoped_ptr
<HttpStreamRequest
> request(
1136 session
->http_stream_factory()->RequestStream(
1143 waiter
.WaitForStream();
1144 EXPECT_TRUE(waiter
.stream_done());
1145 EXPECT_TRUE(nullptr == waiter
.websocket_stream());
1146 ASSERT_TRUE(nullptr != waiter
.stream());
1147 EXPECT_TRUE(waiter
.stream()->IsSpdyHttpStream());
1148 EXPECT_EQ(1, GetSocketPoolGroupCount(
1149 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1150 EXPECT_EQ(1, GetSocketPoolGroupCount(
1151 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1152 EXPECT_EQ(0, GetSocketPoolGroupCount(
1153 session
->GetTransportSocketPool(
1154 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1155 EXPECT_EQ(0, GetSocketPoolGroupCount(
1156 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1157 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
1160 // TODO(ricea): This test can be removed once the new WebSocket stack supports
1161 // SPDY. Currently, even if we connect to a SPDY-supporting server, we need to
1163 TEST_P(HttpStreamFactoryTest
, RequestWebSocketSpdyHandshakeStreamButGetSSL
) {
1164 SpdySessionDependencies
session_deps(GetParam(),
1165 ProxyService::CreateDirect());
1167 MockRead
mock_read(SYNCHRONOUS
, ERR_IO_PENDING
);
1168 StaticSocketDataProvider
socket_data(&mock_read
, 1, nullptr, 0);
1169 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
1170 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
1172 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
1173 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl_socket_data
);
1175 HostPortPair
host_port_pair("www.google.com", 80);
1176 scoped_refptr
<HttpNetworkSession
>
1177 session(SpdySessionDependencies::SpdyCreateSession(&session_deps
));
1179 // Now request a stream.
1180 HttpRequestInfo request_info
;
1181 request_info
.method
= "GET";
1182 request_info
.url
= GURL("wss://www.google.com");
1183 request_info
.load_flags
= 0;
1185 SSLConfig ssl_config
;
1186 StreamRequestWaiter waiter1
;
1187 WebSocketStreamCreateHelper create_helper
;
1188 scoped_ptr
<HttpStreamRequest
> request1(
1189 session
->http_stream_factory_for_websocket()
1190 ->RequestWebSocketHandshakeStream(request_info
,
1197 waiter1
.WaitForStream();
1198 EXPECT_TRUE(waiter1
.stream_done());
1199 ASSERT_TRUE(nullptr != waiter1
.websocket_stream());
1200 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic
,
1201 waiter1
.websocket_stream()->type());
1202 EXPECT_TRUE(nullptr == waiter1
.stream());
1204 EXPECT_EQ(0, GetSocketPoolGroupCount(
1205 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1206 EXPECT_EQ(0, GetSocketPoolGroupCount(
1207 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1208 EXPECT_EQ(1, GetSocketPoolGroupCount(
1209 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1210 EXPECT_TRUE(waiter1
.used_proxy_info().is_direct());
1213 // TODO(ricea): Re-enable once WebSocket-over-SPDY is implemented.
1214 TEST_P(HttpStreamFactoryTest
, DISABLED_RequestWebSocketSpdyHandshakeStream
) {
1215 SpdySessionDependencies
session_deps(GetParam(),
1216 ProxyService::CreateDirect());
1218 MockRead
mock_read(SYNCHRONOUS
, ERR_IO_PENDING
);
1219 StaticSocketDataProvider
socket_data(&mock_read
, 1, nullptr, 0);
1220 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
1221 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
1223 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
1224 ssl_socket_data
.SetNextProto(GetParam());
1225 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl_socket_data
);
1227 HostPortPair
host_port_pair("www.google.com", 80);
1228 scoped_refptr
<HttpNetworkSession
>
1229 session(SpdySessionDependencies::SpdyCreateSession(&session_deps
));
1231 // Now request a stream.
1232 HttpRequestInfo request_info
;
1233 request_info
.method
= "GET";
1234 request_info
.url
= GURL("wss://www.google.com");
1235 request_info
.load_flags
= 0;
1237 SSLConfig ssl_config
;
1238 StreamRequestWaiter waiter1
;
1239 WebSocketStreamCreateHelper create_helper
;
1240 scoped_ptr
<HttpStreamRequest
> request1(
1241 session
->http_stream_factory_for_websocket()
1242 ->RequestWebSocketHandshakeStream(request_info
,
1249 waiter1
.WaitForStream();
1250 EXPECT_TRUE(waiter1
.stream_done());
1251 ASSERT_TRUE(nullptr != waiter1
.websocket_stream());
1252 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy
,
1253 waiter1
.websocket_stream()->type());
1254 EXPECT_TRUE(nullptr == waiter1
.stream());
1256 StreamRequestWaiter waiter2
;
1257 scoped_ptr
<HttpStreamRequest
> request2(
1258 session
->http_stream_factory_for_websocket()
1259 ->RequestWebSocketHandshakeStream(request_info
,
1266 waiter2
.WaitForStream();
1267 EXPECT_TRUE(waiter2
.stream_done());
1268 ASSERT_TRUE(nullptr != waiter2
.websocket_stream());
1269 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy
,
1270 waiter2
.websocket_stream()->type());
1271 EXPECT_TRUE(nullptr == waiter2
.stream());
1272 EXPECT_NE(waiter2
.websocket_stream(), waiter1
.websocket_stream());
1273 EXPECT_EQ(static_cast<WebSocketSpdyHandshakeStream
*>(
1274 waiter2
.websocket_stream())->spdy_session(),
1275 static_cast<WebSocketSpdyHandshakeStream
*>(
1276 waiter1
.websocket_stream())->spdy_session());
1278 EXPECT_EQ(0, GetSocketPoolGroupCount(
1279 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1280 EXPECT_EQ(0, GetSocketPoolGroupCount(
1281 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1282 EXPECT_EQ(1, GetSocketPoolGroupCount(
1283 session
->GetTransportSocketPool(
1284 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1285 EXPECT_EQ(1, GetSocketPoolGroupCount(
1286 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1287 EXPECT_TRUE(waiter1
.used_proxy_info().is_direct());
1290 // TODO(ricea): Re-enable once WebSocket over SPDY is implemented.
1291 TEST_P(HttpStreamFactoryTest
, DISABLED_OrphanedWebSocketStream
) {
1292 SpdySessionDependencies
session_deps(GetParam(),
1293 ProxyService::CreateDirect());
1294 session_deps
.use_alternate_protocols
= true;
1296 MockRead
mock_read(ASYNC
, OK
);
1297 DeterministicSocketData
socket_data(&mock_read
, 1, nullptr, 0);
1298 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
1299 session_deps
.deterministic_socket_factory
->AddSocketDataProvider(
1302 MockRead
mock_read2(ASYNC
, OK
);
1303 DeterministicSocketData
socket_data2(&mock_read2
, 1, nullptr, 0);
1304 socket_data2
.set_connect_data(MockConnect(ASYNC
, ERR_IO_PENDING
));
1305 session_deps
.deterministic_socket_factory
->AddSocketDataProvider(
1308 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
1309 ssl_socket_data
.SetNextProto(GetParam());
1310 session_deps
.deterministic_socket_factory
->AddSSLSocketDataProvider(
1313 scoped_refptr
<HttpNetworkSession
>
1314 session(SpdySessionDependencies::SpdyCreateSessionDeterministic(
1317 // Now request a stream.
1318 HttpRequestInfo request_info
;
1319 request_info
.method
= "GET";
1320 request_info
.url
= GURL("ws://www.google.com:8888");
1321 request_info
.load_flags
= 0;
1323 session
->http_server_properties()->SetAlternativeService(
1324 HostPortPair("www.google.com", 8888),
1325 AlternativeService(NPN_SPDY_4
, "www.google.com", 9999), 1.0);
1327 SSLConfig ssl_config
;
1328 StreamRequestWaiter waiter
;
1329 WebSocketStreamCreateHelper create_helper
;
1330 scoped_ptr
<HttpStreamRequest
> request(
1331 session
->http_stream_factory_for_websocket()
1332 ->RequestWebSocketHandshakeStream(request_info
,
1339 waiter
.WaitForStream();
1340 EXPECT_TRUE(waiter
.stream_done());
1341 EXPECT_TRUE(nullptr == waiter
.stream());
1342 ASSERT_TRUE(nullptr != waiter
.websocket_stream());
1343 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy
,
1344 waiter
.websocket_stream()->type());
1346 // Make sure that there was an alternative connection
1347 // which consumes extra connections.
1348 EXPECT_EQ(0, GetSocketPoolGroupCount(
1349 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1350 EXPECT_EQ(0, GetSocketPoolGroupCount(
1351 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1352 EXPECT_EQ(2, GetSocketPoolGroupCount(
1353 session
->GetTransportSocketPool(
1354 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1355 EXPECT_EQ(1, GetSocketPoolGroupCount(
1356 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1357 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
1359 // Make sure there is no orphaned job. it is already canceled.
1360 ASSERT_EQ(0u, static_cast<HttpStreamFactoryImpl
*>(
1361 session
->http_stream_factory_for_websocket())->num_orphaned_jobs());