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 virtual 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 virtual 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 virtual void CancelRequest(const std::string
& group_name
,
341 ClientSocketHandle
* handle
) override
{
344 virtual void ReleaseSocket(const std::string
& group_name
,
345 scoped_ptr
<StreamSocket
> socket
,
349 virtual void CloseIdleSockets() override
{
352 virtual int IdleSocketCount() const override
{
356 virtual int IdleSocketCountInGroup(
357 const std::string
& group_name
) const override
{
361 virtual LoadState
GetLoadState(
362 const std::string
& group_name
,
363 const ClientSocketHandle
* handle
) const override
{
365 return LOAD_STATE_IDLE
;
367 virtual base::TimeDelta
ConnectionTimeout() const override
{
368 return base::TimeDelta();
372 int last_num_streams_
;
375 typedef CapturePreconnectsSocketPool
<TransportClientSocketPool
>
376 CapturePreconnectsTransportSocketPool
;
377 typedef CapturePreconnectsSocketPool
<HttpProxyClientSocketPool
>
378 CapturePreconnectsHttpProxySocketPool
;
379 typedef CapturePreconnectsSocketPool
<SOCKSClientSocketPool
>
380 CapturePreconnectsSOCKSSocketPool
;
381 typedef CapturePreconnectsSocketPool
<SSLClientSocketPool
>
382 CapturePreconnectsSSLSocketPool
;
384 template <typename ParentPool
>
385 CapturePreconnectsSocketPool
<ParentPool
>::CapturePreconnectsSocketPool(
386 HostResolver
* host_resolver
,
387 CertVerifier
* /* cert_verifier */)
388 : ParentPool(0, 0, host_resolver
, nullptr, nullptr), last_num_streams_(-1) {
392 CapturePreconnectsHttpProxySocketPool::CapturePreconnectsSocketPool(
393 HostResolver
* /* host_resolver */,
394 CertVerifier
* /* cert_verifier */)
395 : HttpProxyClientSocketPool(0, 0, nullptr, nullptr, nullptr),
396 last_num_streams_(-1) {
400 CapturePreconnectsSSLSocketPool::CapturePreconnectsSocketPool(
401 HostResolver
* /* host_resolver */,
402 CertVerifier
* cert_verifier
)
403 : SSLClientSocketPool(0,
406 nullptr, // channel_id_store
407 nullptr, // transport_security_state
408 nullptr, // cert_transparency_verifier
409 nullptr, // cert_policy_enforcer
410 std::string(), // ssl_session_cache_shard
411 nullptr, // deterministic_socket_factory
412 nullptr, // transport_socket_pool
415 nullptr, // ssl_config_service
417 last_num_streams_(-1) {
420 class HttpStreamFactoryTest
: public ::testing::Test
,
421 public ::testing::WithParamInterface
<NextProto
> {
424 INSTANTIATE_TEST_CASE_P(NextProto
,
425 HttpStreamFactoryTest
,
426 testing::Values(kProtoSPDY31
,
430 TEST_P(HttpStreamFactoryTest
, PreconnectDirect
) {
431 for (size_t i
= 0; i
< arraysize(kTests
); ++i
) {
432 SpdySessionDependencies
session_deps(
433 GetParam(), ProxyService::CreateDirect());
434 scoped_refptr
<HttpNetworkSession
> session(
435 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
436 HttpNetworkSessionPeer
peer(session
);
437 CapturePreconnectsTransportSocketPool
* transport_conn_pool
=
438 new CapturePreconnectsTransportSocketPool(
439 session_deps
.host_resolver
.get(),
440 session_deps
.cert_verifier
.get());
441 CapturePreconnectsSSLSocketPool
* ssl_conn_pool
=
442 new CapturePreconnectsSSLSocketPool(
443 session_deps
.host_resolver
.get(),
444 session_deps
.cert_verifier
.get());
445 scoped_ptr
<MockClientSocketPoolManager
> mock_pool_manager(
446 new MockClientSocketPoolManager
);
447 mock_pool_manager
->SetTransportSocketPool(transport_conn_pool
);
448 mock_pool_manager
->SetSSLSocketPool(ssl_conn_pool
);
449 peer
.SetClientSocketPoolManager(mock_pool_manager
.Pass());
450 PreconnectHelper(kTests
[i
], session
.get());
452 EXPECT_EQ(kTests
[i
].num_streams
, ssl_conn_pool
->last_num_streams());
454 EXPECT_EQ(kTests
[i
].num_streams
, transport_conn_pool
->last_num_streams());
458 TEST_P(HttpStreamFactoryTest
, PreconnectHttpProxy
) {
459 for (size_t i
= 0; i
< arraysize(kTests
); ++i
) {
460 SpdySessionDependencies
session_deps(
461 GetParam(), ProxyService::CreateFixed("http_proxy"));
462 scoped_refptr
<HttpNetworkSession
> session(
463 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
464 HttpNetworkSessionPeer
peer(session
);
465 HostPortPair
proxy_host("http_proxy", 80);
466 CapturePreconnectsHttpProxySocketPool
* http_proxy_pool
=
467 new CapturePreconnectsHttpProxySocketPool(
468 session_deps
.host_resolver
.get(),
469 session_deps
.cert_verifier
.get());
470 CapturePreconnectsSSLSocketPool
* ssl_conn_pool
=
471 new CapturePreconnectsSSLSocketPool(
472 session_deps
.host_resolver
.get(),
473 session_deps
.cert_verifier
.get());
474 scoped_ptr
<MockClientSocketPoolManager
> mock_pool_manager(
475 new MockClientSocketPoolManager
);
476 mock_pool_manager
->SetSocketPoolForHTTPProxy(proxy_host
, http_proxy_pool
);
477 mock_pool_manager
->SetSocketPoolForSSLWithProxy(proxy_host
, ssl_conn_pool
);
478 peer
.SetClientSocketPoolManager(mock_pool_manager
.Pass());
479 PreconnectHelper(kTests
[i
], session
.get());
481 EXPECT_EQ(kTests
[i
].num_streams
, ssl_conn_pool
->last_num_streams());
483 EXPECT_EQ(kTests
[i
].num_streams
, http_proxy_pool
->last_num_streams());
487 TEST_P(HttpStreamFactoryTest
, PreconnectSocksProxy
) {
488 for (size_t i
= 0; i
< arraysize(kTests
); ++i
) {
489 SpdySessionDependencies
session_deps(
490 GetParam(), ProxyService::CreateFixed("socks4://socks_proxy:1080"));
491 scoped_refptr
<HttpNetworkSession
> session(
492 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
493 HttpNetworkSessionPeer
peer(session
);
494 HostPortPair
proxy_host("socks_proxy", 1080);
495 CapturePreconnectsSOCKSSocketPool
* socks_proxy_pool
=
496 new CapturePreconnectsSOCKSSocketPool(
497 session_deps
.host_resolver
.get(),
498 session_deps
.cert_verifier
.get());
499 CapturePreconnectsSSLSocketPool
* ssl_conn_pool
=
500 new CapturePreconnectsSSLSocketPool(
501 session_deps
.host_resolver
.get(),
502 session_deps
.cert_verifier
.get());
503 scoped_ptr
<MockClientSocketPoolManager
> mock_pool_manager(
504 new MockClientSocketPoolManager
);
505 mock_pool_manager
->SetSocketPoolForSOCKSProxy(proxy_host
, socks_proxy_pool
);
506 mock_pool_manager
->SetSocketPoolForSSLWithProxy(proxy_host
, ssl_conn_pool
);
507 peer
.SetClientSocketPoolManager(mock_pool_manager
.Pass());
508 PreconnectHelper(kTests
[i
], session
.get());
510 EXPECT_EQ(kTests
[i
].num_streams
, ssl_conn_pool
->last_num_streams());
512 EXPECT_EQ(kTests
[i
].num_streams
, socks_proxy_pool
->last_num_streams());
516 TEST_P(HttpStreamFactoryTest
, PreconnectDirectWithExistingSpdySession
) {
517 for (size_t i
= 0; i
< arraysize(kTests
); ++i
) {
518 SpdySessionDependencies
session_deps(
519 GetParam(), ProxyService::CreateDirect());
520 scoped_refptr
<HttpNetworkSession
> session(
521 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
522 HttpNetworkSessionPeer
peer(session
);
524 // Put a SpdySession in the pool.
525 HostPortPair
host_port_pair("www.google.com", 443);
526 SpdySessionKey
key(host_port_pair
, ProxyServer::Direct(),
527 PRIVACY_MODE_DISABLED
);
528 ignore_result(CreateFakeSpdySession(session
->spdy_session_pool(), key
));
530 CapturePreconnectsTransportSocketPool
* transport_conn_pool
=
531 new CapturePreconnectsTransportSocketPool(
532 session_deps
.host_resolver
.get(),
533 session_deps
.cert_verifier
.get());
534 CapturePreconnectsSSLSocketPool
* ssl_conn_pool
=
535 new CapturePreconnectsSSLSocketPool(
536 session_deps
.host_resolver
.get(),
537 session_deps
.cert_verifier
.get());
538 scoped_ptr
<MockClientSocketPoolManager
> mock_pool_manager(
539 new MockClientSocketPoolManager
);
540 mock_pool_manager
->SetTransportSocketPool(transport_conn_pool
);
541 mock_pool_manager
->SetSSLSocketPool(ssl_conn_pool
);
542 peer
.SetClientSocketPoolManager(mock_pool_manager
.Pass());
543 PreconnectHelper(kTests
[i
], session
.get());
544 // We shouldn't be preconnecting if we have an existing session, which is
545 // the case for https://www.google.com.
547 EXPECT_EQ(-1, ssl_conn_pool
->last_num_streams());
549 EXPECT_EQ(kTests
[i
].num_streams
,
550 transport_conn_pool
->last_num_streams());
554 // Verify that preconnects to unsafe ports are cancelled before they reach
556 TEST_P(HttpStreamFactoryTest
, PreconnectUnsafePort
) {
557 ASSERT_FALSE(IsPortAllowedByDefault(7));
558 ASSERT_FALSE(IsPortAllowedByOverride(7));
560 SpdySessionDependencies
session_deps(
561 GetParam(), ProxyService::CreateDirect());
562 scoped_refptr
<HttpNetworkSession
> session(
563 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
564 HttpNetworkSessionPeer
peer(session
);
565 CapturePreconnectsTransportSocketPool
* transport_conn_pool
=
566 new CapturePreconnectsTransportSocketPool(
567 session_deps
.host_resolver
.get(),
568 session_deps
.cert_verifier
.get());
569 scoped_ptr
<MockClientSocketPoolManager
> mock_pool_manager(
570 new MockClientSocketPoolManager
);
571 mock_pool_manager
->SetTransportSocketPool(transport_conn_pool
);
572 peer
.SetClientSocketPoolManager(mock_pool_manager
.Pass());
574 PreconnectHelperForURL(1, GURL("http://www.google.com:7"), session
.get());
576 EXPECT_EQ(-1, transport_conn_pool
->last_num_streams());
579 TEST_P(HttpStreamFactoryTest
, JobNotifiesProxy
) {
580 const char* kProxyString
= "PROXY bad:99; PROXY maybe:80; DIRECT";
581 SpdySessionDependencies
session_deps(
582 GetParam(), ProxyService::CreateFixedFromPacResult(kProxyString
));
584 // First connection attempt fails
585 StaticSocketDataProvider socket_data1
;
586 socket_data1
.set_connect_data(MockConnect(ASYNC
, ERR_ADDRESS_UNREACHABLE
));
587 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data1
);
589 // Second connection attempt succeeds
590 StaticSocketDataProvider socket_data2
;
591 socket_data2
.set_connect_data(MockConnect(ASYNC
, OK
));
592 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data2
);
594 scoped_refptr
<HttpNetworkSession
> session(
595 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
597 // Now request a stream. It should succeed using the second proxy in the
599 HttpRequestInfo request_info
;
600 request_info
.method
= "GET";
601 request_info
.url
= GURL("http://www.google.com");
603 SSLConfig ssl_config
;
604 StreamRequestWaiter waiter
;
605 scoped_ptr
<HttpStreamRequest
> request(
606 session
->http_stream_factory()->RequestStream(
607 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
,
608 &waiter
, BoundNetLog()));
609 waiter
.WaitForStream();
611 // The proxy that failed should now be known to the proxy_service as bad.
612 const ProxyRetryInfoMap
& retry_info
=
613 session
->proxy_service()->proxy_retry_info();
614 EXPECT_EQ(1u, retry_info
.size());
615 ProxyRetryInfoMap::const_iterator iter
= retry_info
.find("bad:99");
616 EXPECT_TRUE(iter
!= retry_info
.end());
619 TEST_P(HttpStreamFactoryTest
, UnreachableQuicProxyMarkedAsBad
) {
620 for (int i
= 1; i
<= 2; i
++) {
622 i
== 1 ? ERR_QUIC_PROTOCOL_ERROR
: ERR_QUIC_HANDSHAKE_FAILED
;
624 scoped_ptr
<ProxyService
> proxy_service
;
626 ProxyService::CreateFixedFromPacResult("QUIC bad:99; DIRECT"));
628 HttpNetworkSession::Params params
;
629 params
.enable_quic
= true;
630 params
.enable_quic_for_proxies
= true;
631 scoped_refptr
<SSLConfigServiceDefaults
> ssl_config_service(
632 new SSLConfigServiceDefaults
);
633 HttpServerPropertiesImpl http_server_properties
;
634 MockClientSocketFactory socket_factory
;
635 params
.client_socket_factory
= &socket_factory
;
636 MockHostResolver host_resolver
;
637 params
.host_resolver
= &host_resolver
;
638 TransportSecurityState transport_security_state
;
639 params
.transport_security_state
= &transport_security_state
;
640 params
.proxy_service
= proxy_service
.get();
641 params
.ssl_config_service
= ssl_config_service
.get();
642 params
.http_server_properties
= http_server_properties
.GetWeakPtr();
644 scoped_refptr
<HttpNetworkSession
> session
;
645 session
= new HttpNetworkSession(params
);
646 session
->quic_stream_factory()->set_require_confirmation(false);
648 StaticSocketDataProvider socket_data1
;
649 socket_data1
.set_connect_data(MockConnect(ASYNC
, mock_error
));
650 socket_factory
.AddSocketDataProvider(&socket_data1
);
652 // Second connection attempt succeeds.
653 StaticSocketDataProvider socket_data2
;
654 socket_data2
.set_connect_data(MockConnect(ASYNC
, OK
));
655 socket_factory
.AddSocketDataProvider(&socket_data2
);
657 // Now request a stream. It should succeed using the second proxy in the
659 HttpRequestInfo request_info
;
660 request_info
.method
= "GET";
661 request_info
.url
= GURL("http://www.google.com");
663 SSLConfig ssl_config
;
664 StreamRequestWaiter waiter
;
665 scoped_ptr
<HttpStreamRequest
> request(
666 session
->http_stream_factory()->RequestStream(
667 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
, &waiter
,
669 waiter
.WaitForStream();
671 // The proxy that failed should now be known to the proxy_service as bad.
672 const ProxyRetryInfoMap
& retry_info
=
673 session
->proxy_service()->proxy_retry_info();
674 // proxy_headers_handler.proxy_info_used.proxy_retry_info();
675 EXPECT_EQ(1u, retry_info
.size()) << i
;
676 // EXPECT_TRUE(waiter.used_proxy_info().is_direct());
678 ProxyRetryInfoMap::const_iterator iter
= retry_info
.find("quic://bad:99");
679 EXPECT_TRUE(iter
!= retry_info
.end()) << i
;
683 TEST_P(HttpStreamFactoryTest
, PrivacyModeDisablesChannelId
) {
684 SpdySessionDependencies
session_deps(
685 GetParam(), ProxyService::CreateDirect());
687 StaticSocketDataProvider socket_data
;
688 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
689 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
691 SSLSocketDataProvider
ssl(ASYNC
, OK
);
692 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl
);
694 scoped_refptr
<HttpNetworkSession
> session(
695 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
697 // Set an existing SpdySession in the pool.
698 HostPortPair
host_port_pair("www.google.com", 443);
699 SpdySessionKey
key(host_port_pair
, ProxyServer::Direct(),
700 PRIVACY_MODE_ENABLED
);
702 HttpRequestInfo request_info
;
703 request_info
.method
= "GET";
704 request_info
.url
= GURL("https://www.google.com");
705 request_info
.load_flags
= 0;
706 request_info
.privacy_mode
= PRIVACY_MODE_DISABLED
;
708 SSLConfig ssl_config
;
709 StreamRequestWaiter waiter
;
710 scoped_ptr
<HttpStreamRequest
> request(
711 session
->http_stream_factory()->RequestStream(
712 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
,
713 &waiter
, BoundNetLog()));
714 waiter
.WaitForStream();
716 // The stream shouldn't come from spdy as we are using different privacy mode
717 EXPECT_FALSE(request
->using_spdy());
719 SSLConfig used_ssl_config
= waiter
.used_ssl_config();
720 EXPECT_EQ(used_ssl_config
.channel_id_enabled
, ssl_config
.channel_id_enabled
);
724 // Return count of distinct groups in given socket pool.
725 int GetSocketPoolGroupCount(ClientSocketPool
* pool
) {
727 scoped_ptr
<base::DictionaryValue
> dict(pool
->GetInfoAsValue("", "", false));
728 EXPECT_TRUE(dict
!= nullptr);
729 base::DictionaryValue
* groups
= nullptr;
730 if (dict
->GetDictionary("groups", &groups
) && (groups
!= nullptr)) {
731 count
= static_cast<int>(groups
->size());
737 TEST_P(HttpStreamFactoryTest
, PrivacyModeUsesDifferentSocketPoolGroup
) {
738 SpdySessionDependencies
session_deps(
739 GetParam(), ProxyService::CreateDirect());
741 StaticSocketDataProvider socket_data
;
742 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
743 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
745 SSLSocketDataProvider
ssl(ASYNC
, OK
);
746 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl
);
748 scoped_refptr
<HttpNetworkSession
> session(
749 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
750 SSLClientSocketPool
* ssl_pool
= session
->GetSSLSocketPool(
751 HttpNetworkSession::NORMAL_SOCKET_POOL
);
753 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool
), 0);
755 HttpRequestInfo request_info
;
756 request_info
.method
= "GET";
757 request_info
.url
= GURL("https://www.google.com");
758 request_info
.load_flags
= 0;
759 request_info
.privacy_mode
= PRIVACY_MODE_DISABLED
;
761 SSLConfig ssl_config
;
762 StreamRequestWaiter waiter
;
764 scoped_ptr
<HttpStreamRequest
> request1(
765 session
->http_stream_factory()->RequestStream(
766 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
,
767 &waiter
, BoundNetLog()));
768 waiter
.WaitForStream();
770 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool
), 1);
772 scoped_ptr
<HttpStreamRequest
> request2(
773 session
->http_stream_factory()->RequestStream(
774 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
,
775 &waiter
, BoundNetLog()));
776 waiter
.WaitForStream();
778 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool
), 1);
780 request_info
.privacy_mode
= PRIVACY_MODE_ENABLED
;
781 scoped_ptr
<HttpStreamRequest
> request3(
782 session
->http_stream_factory()->RequestStream(
783 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
,
784 &waiter
, BoundNetLog()));
785 waiter
.WaitForStream();
787 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool
), 2);
790 TEST_P(HttpStreamFactoryTest
, GetLoadState
) {
791 SpdySessionDependencies
session_deps(
792 GetParam(), ProxyService::CreateDirect());
794 StaticSocketDataProvider socket_data
;
795 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
796 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
798 scoped_refptr
<HttpNetworkSession
> session(
799 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
801 HttpRequestInfo request_info
;
802 request_info
.method
= "GET";
803 request_info
.url
= GURL("http://www.google.com");
805 SSLConfig ssl_config
;
806 StreamRequestWaiter waiter
;
807 scoped_ptr
<HttpStreamRequest
> request(
808 session
->http_stream_factory()->RequestStream(
809 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
,
810 &waiter
, BoundNetLog()));
812 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST
, request
->GetLoadState());
814 waiter
.WaitForStream();
817 TEST_P(HttpStreamFactoryTest
, RequestHttpStream
) {
818 SpdySessionDependencies
session_deps(
819 GetParam(), ProxyService::CreateDirect());
821 StaticSocketDataProvider socket_data
;
822 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
823 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
825 scoped_refptr
<HttpNetworkSession
> session(
826 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
828 // Now request a stream. It should succeed using the second proxy in the
830 HttpRequestInfo request_info
;
831 request_info
.method
= "GET";
832 request_info
.url
= GURL("http://www.google.com");
833 request_info
.load_flags
= 0;
835 SSLConfig ssl_config
;
836 StreamRequestWaiter waiter
;
837 scoped_ptr
<HttpStreamRequest
> request(
838 session
->http_stream_factory()->RequestStream(
845 waiter
.WaitForStream();
846 EXPECT_TRUE(waiter
.stream_done());
847 ASSERT_TRUE(nullptr != waiter
.stream());
848 EXPECT_TRUE(nullptr == waiter
.websocket_stream());
849 EXPECT_FALSE(waiter
.stream()->IsSpdyHttpStream());
851 EXPECT_EQ(1, GetSocketPoolGroupCount(
852 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
853 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSSLSocketPool(
854 HttpNetworkSession::NORMAL_SOCKET_POOL
)));
855 EXPECT_EQ(0, GetSocketPoolGroupCount(
856 session
->GetTransportSocketPool(
857 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
858 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSSLSocketPool(
859 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
860 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
863 TEST_P(HttpStreamFactoryTest
, RequestHttpStreamOverSSL
) {
864 SpdySessionDependencies
session_deps(
865 GetParam(), ProxyService::CreateDirect());
867 MockRead
mock_read(ASYNC
, OK
);
868 StaticSocketDataProvider
socket_data(&mock_read
, 1, nullptr, 0);
869 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
870 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
872 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
873 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl_socket_data
);
875 scoped_refptr
<HttpNetworkSession
> session(
876 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
878 // Now request a stream.
879 HttpRequestInfo request_info
;
880 request_info
.method
= "GET";
881 request_info
.url
= GURL("https://www.google.com");
882 request_info
.load_flags
= 0;
884 SSLConfig ssl_config
;
885 StreamRequestWaiter waiter
;
886 scoped_ptr
<HttpStreamRequest
> request(
887 session
->http_stream_factory()->RequestStream(
894 waiter
.WaitForStream();
895 EXPECT_TRUE(waiter
.stream_done());
896 ASSERT_TRUE(nullptr != waiter
.stream());
897 EXPECT_TRUE(nullptr == waiter
.websocket_stream());
898 EXPECT_FALSE(waiter
.stream()->IsSpdyHttpStream());
899 EXPECT_EQ(1, GetSocketPoolGroupCount(
900 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
901 EXPECT_EQ(1, GetSocketPoolGroupCount(
902 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
903 EXPECT_EQ(0, GetSocketPoolGroupCount(
904 session
->GetTransportSocketPool(
905 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
906 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSSLSocketPool(
907 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
908 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
911 TEST_P(HttpStreamFactoryTest
, RequestHttpStreamOverProxy
) {
912 SpdySessionDependencies
session_deps(
913 GetParam(), ProxyService::CreateFixed("myproxy:8888"));
915 StaticSocketDataProvider socket_data
;
916 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
917 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
919 scoped_refptr
<HttpNetworkSession
> session(
920 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
922 // Now request a stream. It should succeed using the second proxy in the
924 HttpRequestInfo request_info
;
925 request_info
.method
= "GET";
926 request_info
.url
= GURL("http://www.google.com");
927 request_info
.load_flags
= 0;
929 SSLConfig ssl_config
;
930 StreamRequestWaiter waiter
;
931 scoped_ptr
<HttpStreamRequest
> request(
932 session
->http_stream_factory()->RequestStream(
939 waiter
.WaitForStream();
940 EXPECT_TRUE(waiter
.stream_done());
941 ASSERT_TRUE(nullptr != waiter
.stream());
942 EXPECT_TRUE(nullptr == waiter
.websocket_stream());
943 EXPECT_FALSE(waiter
.stream()->IsSpdyHttpStream());
944 EXPECT_EQ(0, GetSocketPoolGroupCount(
945 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
946 EXPECT_EQ(0, GetSocketPoolGroupCount(
947 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
948 EXPECT_EQ(1, GetSocketPoolGroupCount(session
->GetSocketPoolForHTTPProxy(
949 HttpNetworkSession::NORMAL_SOCKET_POOL
,
950 HostPortPair("myproxy", 8888))));
951 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSocketPoolForSSLWithProxy(
952 HttpNetworkSession::NORMAL_SOCKET_POOL
,
953 HostPortPair("myproxy", 8888))));
954 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSocketPoolForHTTPProxy(
955 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
,
956 HostPortPair("myproxy", 8888))));
957 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSocketPoolForSSLWithProxy(
958 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
,
959 HostPortPair("myproxy", 8888))));
960 EXPECT_FALSE(waiter
.used_proxy_info().is_direct());
963 TEST_P(HttpStreamFactoryTest
, RequestWebSocketBasicHandshakeStream
) {
964 SpdySessionDependencies
session_deps(
965 GetParam(), ProxyService::CreateDirect());
967 StaticSocketDataProvider socket_data
;
968 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
969 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
971 scoped_refptr
<HttpNetworkSession
> session(
972 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
974 // Now request a stream.
975 HttpRequestInfo request_info
;
976 request_info
.method
= "GET";
977 request_info
.url
= GURL("ws://www.google.com");
978 request_info
.load_flags
= 0;
980 SSLConfig ssl_config
;
981 StreamRequestWaiter waiter
;
982 WebSocketStreamCreateHelper create_helper
;
983 scoped_ptr
<HttpStreamRequest
> request(
984 session
->http_stream_factory_for_websocket()
985 ->RequestWebSocketHandshakeStream(request_info
,
992 waiter
.WaitForStream();
993 EXPECT_TRUE(waiter
.stream_done());
994 EXPECT_TRUE(nullptr == waiter
.stream());
995 ASSERT_TRUE(nullptr != waiter
.websocket_stream());
996 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic
,
997 waiter
.websocket_stream()->type());
998 EXPECT_EQ(0, GetSocketPoolGroupCount(
999 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1000 EXPECT_EQ(0, GetSocketPoolGroupCount(
1001 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1002 EXPECT_EQ(0, GetSocketPoolGroupCount(
1003 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1004 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
1007 TEST_P(HttpStreamFactoryTest
, RequestWebSocketBasicHandshakeStreamOverSSL
) {
1008 SpdySessionDependencies
session_deps(
1009 GetParam(), ProxyService::CreateDirect());
1011 MockRead
mock_read(ASYNC
, OK
);
1012 StaticSocketDataProvider
socket_data(&mock_read
, 1, nullptr, 0);
1013 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
1014 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
1016 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
1017 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl_socket_data
);
1019 scoped_refptr
<HttpNetworkSession
> session(
1020 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
1022 // Now request a stream.
1023 HttpRequestInfo request_info
;
1024 request_info
.method
= "GET";
1025 request_info
.url
= GURL("wss://www.google.com");
1026 request_info
.load_flags
= 0;
1028 SSLConfig ssl_config
;
1029 StreamRequestWaiter waiter
;
1030 WebSocketStreamCreateHelper create_helper
;
1031 scoped_ptr
<HttpStreamRequest
> request(
1032 session
->http_stream_factory_for_websocket()
1033 ->RequestWebSocketHandshakeStream(request_info
,
1040 waiter
.WaitForStream();
1041 EXPECT_TRUE(waiter
.stream_done());
1042 EXPECT_TRUE(nullptr == waiter
.stream());
1043 ASSERT_TRUE(nullptr != waiter
.websocket_stream());
1044 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic
,
1045 waiter
.websocket_stream()->type());
1046 EXPECT_EQ(0, GetSocketPoolGroupCount(
1047 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1048 EXPECT_EQ(0, GetSocketPoolGroupCount(
1049 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1050 EXPECT_EQ(1, GetSocketPoolGroupCount(
1051 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1052 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
1055 TEST_P(HttpStreamFactoryTest
, RequestWebSocketBasicHandshakeStreamOverProxy
) {
1056 SpdySessionDependencies
session_deps(
1057 GetParam(), ProxyService::CreateFixed("myproxy:8888"));
1059 MockRead
read(SYNCHRONOUS
, "HTTP/1.0 200 Connection established\r\n\r\n");
1060 StaticSocketDataProvider
socket_data(&read
, 1, 0, 0);
1061 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
1062 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
1064 scoped_refptr
<HttpNetworkSession
> session(
1065 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
1067 // Now request a stream.
1068 HttpRequestInfo request_info
;
1069 request_info
.method
= "GET";
1070 request_info
.url
= GURL("ws://www.google.com");
1071 request_info
.load_flags
= 0;
1073 SSLConfig ssl_config
;
1074 StreamRequestWaiter waiter
;
1075 WebSocketStreamCreateHelper create_helper
;
1076 scoped_ptr
<HttpStreamRequest
> request(
1077 session
->http_stream_factory_for_websocket()
1078 ->RequestWebSocketHandshakeStream(request_info
,
1085 waiter
.WaitForStream();
1086 EXPECT_TRUE(waiter
.stream_done());
1087 EXPECT_TRUE(nullptr == waiter
.stream());
1088 ASSERT_TRUE(nullptr != waiter
.websocket_stream());
1089 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic
,
1090 waiter
.websocket_stream()->type());
1091 EXPECT_EQ(0, GetSocketPoolGroupCount(
1092 session
->GetTransportSocketPool(
1093 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1094 EXPECT_EQ(0, GetSocketPoolGroupCount(
1095 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1096 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSocketPoolForHTTPProxy(
1097 HttpNetworkSession::NORMAL_SOCKET_POOL
,
1098 HostPortPair("myproxy", 8888))));
1099 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSocketPoolForSSLWithProxy(
1100 HttpNetworkSession::NORMAL_SOCKET_POOL
,
1101 HostPortPair("myproxy", 8888))));
1102 EXPECT_EQ(1, GetSocketPoolGroupCount(session
->GetSocketPoolForHTTPProxy(
1103 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
,
1104 HostPortPair("myproxy", 8888))));
1105 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSocketPoolForSSLWithProxy(
1106 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
,
1107 HostPortPair("myproxy", 8888))));
1108 EXPECT_FALSE(waiter
.used_proxy_info().is_direct());
1111 TEST_P(HttpStreamFactoryTest
, RequestSpdyHttpStream
) {
1112 SpdySessionDependencies
session_deps(GetParam(),
1113 ProxyService::CreateDirect());
1115 MockRead
mock_read(ASYNC
, OK
);
1116 DeterministicSocketData
socket_data(&mock_read
, 1, nullptr, 0);
1117 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
1118 session_deps
.deterministic_socket_factory
->AddSocketDataProvider(
1121 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
1122 ssl_socket_data
.SetNextProto(GetParam());
1123 session_deps
.deterministic_socket_factory
->AddSSLSocketDataProvider(
1126 HostPortPair
host_port_pair("www.google.com", 443);
1127 scoped_refptr
<HttpNetworkSession
>
1128 session(SpdySessionDependencies::SpdyCreateSessionDeterministic(
1131 // Now request a stream.
1132 HttpRequestInfo request_info
;
1133 request_info
.method
= "GET";
1134 request_info
.url
= GURL("https://www.google.com");
1135 request_info
.load_flags
= 0;
1137 SSLConfig ssl_config
;
1138 StreamRequestWaiter waiter
;
1139 scoped_ptr
<HttpStreamRequest
> request(
1140 session
->http_stream_factory()->RequestStream(
1147 waiter
.WaitForStream();
1148 EXPECT_TRUE(waiter
.stream_done());
1149 EXPECT_TRUE(nullptr == waiter
.websocket_stream());
1150 ASSERT_TRUE(nullptr != waiter
.stream());
1151 EXPECT_TRUE(waiter
.stream()->IsSpdyHttpStream());
1152 EXPECT_EQ(1, GetSocketPoolGroupCount(
1153 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1154 EXPECT_EQ(1, GetSocketPoolGroupCount(
1155 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1156 EXPECT_EQ(0, GetSocketPoolGroupCount(
1157 session
->GetTransportSocketPool(
1158 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1159 EXPECT_EQ(0, GetSocketPoolGroupCount(
1160 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1161 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
1164 // TODO(ricea): This test can be removed once the new WebSocket stack supports
1165 // SPDY. Currently, even if we connect to a SPDY-supporting server, we need to
1167 TEST_P(HttpStreamFactoryTest
, RequestWebSocketSpdyHandshakeStreamButGetSSL
) {
1168 SpdySessionDependencies
session_deps(GetParam(),
1169 ProxyService::CreateDirect());
1171 MockRead
mock_read(SYNCHRONOUS
, ERR_IO_PENDING
);
1172 StaticSocketDataProvider
socket_data(&mock_read
, 1, nullptr, 0);
1173 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
1174 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
1176 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
1177 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl_socket_data
);
1179 HostPortPair
host_port_pair("www.google.com", 80);
1180 scoped_refptr
<HttpNetworkSession
>
1181 session(SpdySessionDependencies::SpdyCreateSession(&session_deps
));
1183 // Now request a stream.
1184 HttpRequestInfo request_info
;
1185 request_info
.method
= "GET";
1186 request_info
.url
= GURL("wss://www.google.com");
1187 request_info
.load_flags
= 0;
1189 SSLConfig ssl_config
;
1190 StreamRequestWaiter waiter1
;
1191 WebSocketStreamCreateHelper create_helper
;
1192 scoped_ptr
<HttpStreamRequest
> request1(
1193 session
->http_stream_factory_for_websocket()
1194 ->RequestWebSocketHandshakeStream(request_info
,
1201 waiter1
.WaitForStream();
1202 EXPECT_TRUE(waiter1
.stream_done());
1203 ASSERT_TRUE(nullptr != waiter1
.websocket_stream());
1204 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic
,
1205 waiter1
.websocket_stream()->type());
1206 EXPECT_TRUE(nullptr == waiter1
.stream());
1208 EXPECT_EQ(0, GetSocketPoolGroupCount(
1209 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1210 EXPECT_EQ(0, GetSocketPoolGroupCount(
1211 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1212 EXPECT_EQ(1, GetSocketPoolGroupCount(
1213 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1214 EXPECT_TRUE(waiter1
.used_proxy_info().is_direct());
1217 // TODO(ricea): Re-enable once WebSocket-over-SPDY is implemented.
1218 TEST_P(HttpStreamFactoryTest
, DISABLED_RequestWebSocketSpdyHandshakeStream
) {
1219 SpdySessionDependencies
session_deps(GetParam(),
1220 ProxyService::CreateDirect());
1222 MockRead
mock_read(SYNCHRONOUS
, ERR_IO_PENDING
);
1223 StaticSocketDataProvider
socket_data(&mock_read
, 1, nullptr, 0);
1224 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
1225 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
1227 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
1228 ssl_socket_data
.SetNextProto(GetParam());
1229 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl_socket_data
);
1231 HostPortPair
host_port_pair("www.google.com", 80);
1232 scoped_refptr
<HttpNetworkSession
>
1233 session(SpdySessionDependencies::SpdyCreateSession(&session_deps
));
1235 // Now request a stream.
1236 HttpRequestInfo request_info
;
1237 request_info
.method
= "GET";
1238 request_info
.url
= GURL("wss://www.google.com");
1239 request_info
.load_flags
= 0;
1241 SSLConfig ssl_config
;
1242 StreamRequestWaiter waiter1
;
1243 WebSocketStreamCreateHelper create_helper
;
1244 scoped_ptr
<HttpStreamRequest
> request1(
1245 session
->http_stream_factory_for_websocket()
1246 ->RequestWebSocketHandshakeStream(request_info
,
1253 waiter1
.WaitForStream();
1254 EXPECT_TRUE(waiter1
.stream_done());
1255 ASSERT_TRUE(nullptr != waiter1
.websocket_stream());
1256 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy
,
1257 waiter1
.websocket_stream()->type());
1258 EXPECT_TRUE(nullptr == waiter1
.stream());
1260 StreamRequestWaiter waiter2
;
1261 scoped_ptr
<HttpStreamRequest
> request2(
1262 session
->http_stream_factory_for_websocket()
1263 ->RequestWebSocketHandshakeStream(request_info
,
1270 waiter2
.WaitForStream();
1271 EXPECT_TRUE(waiter2
.stream_done());
1272 ASSERT_TRUE(nullptr != waiter2
.websocket_stream());
1273 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy
,
1274 waiter2
.websocket_stream()->type());
1275 EXPECT_TRUE(nullptr == waiter2
.stream());
1276 EXPECT_NE(waiter2
.websocket_stream(), waiter1
.websocket_stream());
1277 EXPECT_EQ(static_cast<WebSocketSpdyHandshakeStream
*>(
1278 waiter2
.websocket_stream())->spdy_session(),
1279 static_cast<WebSocketSpdyHandshakeStream
*>(
1280 waiter1
.websocket_stream())->spdy_session());
1282 EXPECT_EQ(0, GetSocketPoolGroupCount(
1283 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1284 EXPECT_EQ(0, GetSocketPoolGroupCount(
1285 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1286 EXPECT_EQ(1, GetSocketPoolGroupCount(
1287 session
->GetTransportSocketPool(
1288 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1289 EXPECT_EQ(1, GetSocketPoolGroupCount(
1290 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1291 EXPECT_TRUE(waiter1
.used_proxy_info().is_direct());
1294 // TODO(ricea): Re-enable once WebSocket over SPDY is implemented.
1295 TEST_P(HttpStreamFactoryTest
, DISABLED_OrphanedWebSocketStream
) {
1296 SpdySessionDependencies
session_deps(GetParam(),
1297 ProxyService::CreateDirect());
1298 session_deps
.use_alternate_protocols
= true;
1300 MockRead
mock_read(ASYNC
, OK
);
1301 DeterministicSocketData
socket_data(&mock_read
, 1, nullptr, 0);
1302 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
1303 session_deps
.deterministic_socket_factory
->AddSocketDataProvider(
1306 MockRead
mock_read2(ASYNC
, OK
);
1307 DeterministicSocketData
socket_data2(&mock_read2
, 1, nullptr, 0);
1308 socket_data2
.set_connect_data(MockConnect(ASYNC
, ERR_IO_PENDING
));
1309 session_deps
.deterministic_socket_factory
->AddSocketDataProvider(
1312 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
1313 ssl_socket_data
.SetNextProto(GetParam());
1314 session_deps
.deterministic_socket_factory
->AddSSLSocketDataProvider(
1317 scoped_refptr
<HttpNetworkSession
>
1318 session(SpdySessionDependencies::SpdyCreateSessionDeterministic(
1321 // Now request a stream.
1322 HttpRequestInfo request_info
;
1323 request_info
.method
= "GET";
1324 request_info
.url
= GURL("ws://www.google.com:8888");
1325 request_info
.load_flags
= 0;
1327 session
->http_server_properties()->SetAlternativeService(
1328 HostPortPair("www.google.com", 8888),
1329 AlternativeService(NPN_SPDY_4
, "www.google.com", 9999), 1.0);
1331 SSLConfig ssl_config
;
1332 StreamRequestWaiter waiter
;
1333 WebSocketStreamCreateHelper create_helper
;
1334 scoped_ptr
<HttpStreamRequest
> request(
1335 session
->http_stream_factory_for_websocket()
1336 ->RequestWebSocketHandshakeStream(request_info
,
1343 waiter
.WaitForStream();
1344 EXPECT_TRUE(waiter
.stream_done());
1345 EXPECT_TRUE(nullptr == waiter
.stream());
1346 ASSERT_TRUE(nullptr != waiter
.websocket_stream());
1347 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy
,
1348 waiter
.websocket_stream()->type());
1350 // Make sure that there was an alternative connection
1351 // which consumes extra connections.
1352 EXPECT_EQ(0, GetSocketPoolGroupCount(
1353 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1354 EXPECT_EQ(0, GetSocketPoolGroupCount(
1355 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1356 EXPECT_EQ(2, GetSocketPoolGroupCount(
1357 session
->GetTransportSocketPool(
1358 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1359 EXPECT_EQ(1, GetSocketPoolGroupCount(
1360 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1361 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
1363 // Make sure there is no orphaned job. it is already canceled.
1364 ASSERT_EQ(0u, static_cast<HttpStreamFactoryImpl
*>(
1365 session
->http_stream_factory_for_websocket())->num_orphaned_jobs());