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
,
169 const SSLConfig
& used_ssl_config
,
170 SSLFailureState ssl_failure_state
) override
{}
172 void OnCertificateError(int status
,
173 const SSLConfig
& used_ssl_config
,
174 const SSLInfo
& ssl_info
) override
{}
176 void OnNeedsProxyAuth(const HttpResponseInfo
& proxy_response
,
177 const SSLConfig
& used_ssl_config
,
178 const ProxyInfo
& used_proxy_info
,
179 HttpAuthController
* auth_controller
) override
{}
181 void OnNeedsClientAuth(const SSLConfig
& used_ssl_config
,
182 SSLCertRequestInfo
* cert_info
) override
{}
184 void OnHttpsProxyTunnelResponse(const HttpResponseInfo
& response_info
,
185 const SSLConfig
& used_ssl_config
,
186 const ProxyInfo
& used_proxy_info
,
187 HttpStream
* stream
) override
{}
189 void WaitForStream() {
190 while (!stream_done_
) {
191 waiting_for_stream_
= true;
192 base::MessageLoop::current()->Run();
193 waiting_for_stream_
= false;
197 const SSLConfig
& used_ssl_config() const {
198 return used_ssl_config_
;
201 const ProxyInfo
& used_proxy_info() const {
202 return used_proxy_info_
;
205 HttpStream
* stream() {
206 return stream_
.get();
209 MockWebSocketHandshakeStream
* websocket_stream() {
210 return static_cast<MockWebSocketHandshakeStream
*>(websocket_stream_
.get());
213 bool stream_done() const { return stream_done_
; }
216 bool waiting_for_stream_
;
218 scoped_ptr
<HttpStream
> stream_
;
219 scoped_ptr
<WebSocketHandshakeStreamBase
> websocket_stream_
;
220 SSLConfig used_ssl_config_
;
221 ProxyInfo used_proxy_info_
;
223 DISALLOW_COPY_AND_ASSIGN(StreamRequestWaiter
);
226 class WebSocketSpdyHandshakeStream
: public MockWebSocketHandshakeStream
{
228 explicit WebSocketSpdyHandshakeStream(
229 const base::WeakPtr
<SpdySession
>& spdy_session
)
230 : MockWebSocketHandshakeStream(kStreamTypeSpdy
),
231 spdy_session_(spdy_session
) {}
233 ~WebSocketSpdyHandshakeStream() override
{}
235 SpdySession
* spdy_session() { return spdy_session_
.get(); }
238 base::WeakPtr
<SpdySession
> spdy_session_
;
241 class WebSocketBasicHandshakeStream
: public MockWebSocketHandshakeStream
{
243 explicit WebSocketBasicHandshakeStream(
244 scoped_ptr
<ClientSocketHandle
> connection
)
245 : MockWebSocketHandshakeStream(kStreamTypeBasic
),
246 connection_(connection
.Pass()) {}
248 ~WebSocketBasicHandshakeStream() override
{
249 connection_
->socket()->Disconnect();
252 ClientSocketHandle
* connection() { return connection_
.get(); }
255 scoped_ptr
<ClientSocketHandle
> connection_
;
258 class WebSocketStreamCreateHelper
259 : public WebSocketHandshakeStreamBase::CreateHelper
{
261 ~WebSocketStreamCreateHelper() override
{}
263 WebSocketHandshakeStreamBase
* CreateBasicStream(
264 scoped_ptr
<ClientSocketHandle
> connection
,
265 bool using_proxy
) override
{
266 return new WebSocketBasicHandshakeStream(connection
.Pass());
269 WebSocketHandshakeStreamBase
* CreateSpdyStream(
270 const base::WeakPtr
<SpdySession
>& spdy_session
,
271 bool use_relative_url
) override
{
272 return new WebSocketSpdyHandshakeStream(spdy_session
);
281 TestCase kTests
[] = {
288 void PreconnectHelperForURL(int num_streams
,
290 HttpNetworkSession
* session
) {
291 HttpNetworkSessionPeer
peer(session
);
292 MockHttpStreamFactoryImplForPreconnect
* mock_factory
=
293 new MockHttpStreamFactoryImplForPreconnect(session
, false);
294 peer
.SetHttpStreamFactory(scoped_ptr
<HttpStreamFactory
>(mock_factory
));
295 SSLConfig ssl_config
;
296 session
->ssl_config_service()->GetSSLConfig(&ssl_config
);
298 HttpRequestInfo request
;
299 request
.method
= "GET";
301 request
.load_flags
= 0;
303 session
->http_stream_factory()->PreconnectStreams(
304 num_streams
, request
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
);
305 mock_factory
->WaitForPreconnects();
308 void PreconnectHelper(const TestCase
& test
,
309 HttpNetworkSession
* session
) {
310 GURL url
= test
.ssl
? GURL("https://www.google.com") :
311 GURL("http://www.google.com");
312 PreconnectHelperForURL(test
.num_streams
, url
, session
);
315 template<typename ParentPool
>
316 class CapturePreconnectsSocketPool
: public ParentPool
{
318 CapturePreconnectsSocketPool(HostResolver
* host_resolver
,
319 CertVerifier
* cert_verifier
);
321 int last_num_streams() const {
322 return last_num_streams_
;
325 int RequestSocket(const std::string
& group_name
,
326 const void* socket_params
,
327 RequestPriority priority
,
328 ClientSocketHandle
* handle
,
329 const CompletionCallback
& callback
,
330 const BoundNetLog
& net_log
) override
{
332 return ERR_UNEXPECTED
;
335 void RequestSockets(const std::string
& group_name
,
336 const void* socket_params
,
338 const BoundNetLog
& net_log
) override
{
339 last_num_streams_
= num_sockets
;
342 void CancelRequest(const std::string
& group_name
,
343 ClientSocketHandle
* handle
) override
{
346 void ReleaseSocket(const std::string
& group_name
,
347 scoped_ptr
<StreamSocket
> socket
,
351 void CloseIdleSockets() override
{ ADD_FAILURE(); }
352 int IdleSocketCount() const override
{
356 int IdleSocketCountInGroup(const std::string
& group_name
) const override
{
360 LoadState
GetLoadState(const std::string
& group_name
,
361 const ClientSocketHandle
* handle
) const override
{
363 return LOAD_STATE_IDLE
;
365 base::TimeDelta
ConnectionTimeout() const override
{
366 return base::TimeDelta();
370 int last_num_streams_
;
373 typedef CapturePreconnectsSocketPool
<TransportClientSocketPool
>
374 CapturePreconnectsTransportSocketPool
;
375 typedef CapturePreconnectsSocketPool
<HttpProxyClientSocketPool
>
376 CapturePreconnectsHttpProxySocketPool
;
377 typedef CapturePreconnectsSocketPool
<SOCKSClientSocketPool
>
378 CapturePreconnectsSOCKSSocketPool
;
379 typedef CapturePreconnectsSocketPool
<SSLClientSocketPool
>
380 CapturePreconnectsSSLSocketPool
;
382 template <typename ParentPool
>
383 CapturePreconnectsSocketPool
<ParentPool
>::CapturePreconnectsSocketPool(
384 HostResolver
* host_resolver
,
385 CertVerifier
* /* cert_verifier */)
386 : ParentPool(0, 0, host_resolver
, nullptr, nullptr), last_num_streams_(-1) {
390 CapturePreconnectsHttpProxySocketPool::CapturePreconnectsSocketPool(
391 HostResolver
* /* host_resolver */,
392 CertVerifier
* /* cert_verifier */)
393 : HttpProxyClientSocketPool(0, 0, nullptr, nullptr, nullptr),
394 last_num_streams_(-1) {
398 CapturePreconnectsSSLSocketPool::CapturePreconnectsSocketPool(
399 HostResolver
* /* host_resolver */,
400 CertVerifier
* cert_verifier
)
401 : SSLClientSocketPool(0,
404 nullptr, // channel_id_store
405 nullptr, // transport_security_state
406 nullptr, // cert_transparency_verifier
407 nullptr, // cert_policy_enforcer
408 std::string(), // ssl_session_cache_shard
409 nullptr, // deterministic_socket_factory
410 nullptr, // transport_socket_pool
413 nullptr, // ssl_config_service
415 last_num_streams_(-1) {
418 class HttpStreamFactoryTest
: public ::testing::Test
,
419 public ::testing::WithParamInterface
<NextProto
> {
422 INSTANTIATE_TEST_CASE_P(NextProto
,
423 HttpStreamFactoryTest
,
424 testing::Values(kProtoSPDY31
,
428 TEST_P(HttpStreamFactoryTest
, PreconnectDirect
) {
429 for (size_t i
= 0; i
< arraysize(kTests
); ++i
) {
430 SpdySessionDependencies
session_deps(
431 GetParam(), ProxyService::CreateDirect());
432 scoped_refptr
<HttpNetworkSession
> session(
433 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
434 HttpNetworkSessionPeer
peer(session
);
435 CapturePreconnectsTransportSocketPool
* transport_conn_pool
=
436 new CapturePreconnectsTransportSocketPool(
437 session_deps
.host_resolver
.get(),
438 session_deps
.cert_verifier
.get());
439 CapturePreconnectsSSLSocketPool
* ssl_conn_pool
=
440 new CapturePreconnectsSSLSocketPool(
441 session_deps
.host_resolver
.get(),
442 session_deps
.cert_verifier
.get());
443 scoped_ptr
<MockClientSocketPoolManager
> mock_pool_manager(
444 new MockClientSocketPoolManager
);
445 mock_pool_manager
->SetTransportSocketPool(transport_conn_pool
);
446 mock_pool_manager
->SetSSLSocketPool(ssl_conn_pool
);
447 peer
.SetClientSocketPoolManager(mock_pool_manager
.Pass());
448 PreconnectHelper(kTests
[i
], session
.get());
450 EXPECT_EQ(kTests
[i
].num_streams
, ssl_conn_pool
->last_num_streams());
452 EXPECT_EQ(kTests
[i
].num_streams
, transport_conn_pool
->last_num_streams());
456 TEST_P(HttpStreamFactoryTest
, PreconnectHttpProxy
) {
457 for (size_t i
= 0; i
< arraysize(kTests
); ++i
) {
458 SpdySessionDependencies
session_deps(
459 GetParam(), ProxyService::CreateFixed("http_proxy"));
460 scoped_refptr
<HttpNetworkSession
> session(
461 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
462 HttpNetworkSessionPeer
peer(session
);
463 HostPortPair
proxy_host("http_proxy", 80);
464 CapturePreconnectsHttpProxySocketPool
* http_proxy_pool
=
465 new CapturePreconnectsHttpProxySocketPool(
466 session_deps
.host_resolver
.get(),
467 session_deps
.cert_verifier
.get());
468 CapturePreconnectsSSLSocketPool
* ssl_conn_pool
=
469 new CapturePreconnectsSSLSocketPool(
470 session_deps
.host_resolver
.get(),
471 session_deps
.cert_verifier
.get());
472 scoped_ptr
<MockClientSocketPoolManager
> mock_pool_manager(
473 new MockClientSocketPoolManager
);
474 mock_pool_manager
->SetSocketPoolForHTTPProxy(proxy_host
, http_proxy_pool
);
475 mock_pool_manager
->SetSocketPoolForSSLWithProxy(proxy_host
, ssl_conn_pool
);
476 peer
.SetClientSocketPoolManager(mock_pool_manager
.Pass());
477 PreconnectHelper(kTests
[i
], session
.get());
479 EXPECT_EQ(kTests
[i
].num_streams
, ssl_conn_pool
->last_num_streams());
481 EXPECT_EQ(kTests
[i
].num_streams
, http_proxy_pool
->last_num_streams());
485 TEST_P(HttpStreamFactoryTest
, PreconnectSocksProxy
) {
486 for (size_t i
= 0; i
< arraysize(kTests
); ++i
) {
487 SpdySessionDependencies
session_deps(
488 GetParam(), ProxyService::CreateFixed("socks4://socks_proxy:1080"));
489 scoped_refptr
<HttpNetworkSession
> session(
490 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
491 HttpNetworkSessionPeer
peer(session
);
492 HostPortPair
proxy_host("socks_proxy", 1080);
493 CapturePreconnectsSOCKSSocketPool
* socks_proxy_pool
=
494 new CapturePreconnectsSOCKSSocketPool(
495 session_deps
.host_resolver
.get(),
496 session_deps
.cert_verifier
.get());
497 CapturePreconnectsSSLSocketPool
* ssl_conn_pool
=
498 new CapturePreconnectsSSLSocketPool(
499 session_deps
.host_resolver
.get(),
500 session_deps
.cert_verifier
.get());
501 scoped_ptr
<MockClientSocketPoolManager
> mock_pool_manager(
502 new MockClientSocketPoolManager
);
503 mock_pool_manager
->SetSocketPoolForSOCKSProxy(proxy_host
, socks_proxy_pool
);
504 mock_pool_manager
->SetSocketPoolForSSLWithProxy(proxy_host
, ssl_conn_pool
);
505 peer
.SetClientSocketPoolManager(mock_pool_manager
.Pass());
506 PreconnectHelper(kTests
[i
], session
.get());
508 EXPECT_EQ(kTests
[i
].num_streams
, ssl_conn_pool
->last_num_streams());
510 EXPECT_EQ(kTests
[i
].num_streams
, socks_proxy_pool
->last_num_streams());
514 TEST_P(HttpStreamFactoryTest
, PreconnectDirectWithExistingSpdySession
) {
515 for (size_t i
= 0; i
< arraysize(kTests
); ++i
) {
516 SpdySessionDependencies
session_deps(
517 GetParam(), ProxyService::CreateDirect());
518 scoped_refptr
<HttpNetworkSession
> session(
519 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
520 HttpNetworkSessionPeer
peer(session
);
522 // Put a SpdySession in the pool.
523 HostPortPair
host_port_pair("www.google.com", 443);
524 SpdySessionKey
key(host_port_pair
, ProxyServer::Direct(),
525 PRIVACY_MODE_DISABLED
);
526 ignore_result(CreateFakeSpdySession(session
->spdy_session_pool(), key
));
528 CapturePreconnectsTransportSocketPool
* transport_conn_pool
=
529 new CapturePreconnectsTransportSocketPool(
530 session_deps
.host_resolver
.get(),
531 session_deps
.cert_verifier
.get());
532 CapturePreconnectsSSLSocketPool
* ssl_conn_pool
=
533 new CapturePreconnectsSSLSocketPool(
534 session_deps
.host_resolver
.get(),
535 session_deps
.cert_verifier
.get());
536 scoped_ptr
<MockClientSocketPoolManager
> mock_pool_manager(
537 new MockClientSocketPoolManager
);
538 mock_pool_manager
->SetTransportSocketPool(transport_conn_pool
);
539 mock_pool_manager
->SetSSLSocketPool(ssl_conn_pool
);
540 peer
.SetClientSocketPoolManager(mock_pool_manager
.Pass());
541 PreconnectHelper(kTests
[i
], session
.get());
542 // We shouldn't be preconnecting if we have an existing session, which is
543 // the case for https://www.google.com.
545 EXPECT_EQ(-1, ssl_conn_pool
->last_num_streams());
547 EXPECT_EQ(kTests
[i
].num_streams
,
548 transport_conn_pool
->last_num_streams());
552 // Verify that preconnects to unsafe ports are cancelled before they reach
554 TEST_P(HttpStreamFactoryTest
, PreconnectUnsafePort
) {
555 ASSERT_FALSE(IsPortAllowedByDefault(7));
556 ASSERT_FALSE(IsPortAllowedByOverride(7));
558 SpdySessionDependencies
session_deps(
559 GetParam(), ProxyService::CreateDirect());
560 scoped_refptr
<HttpNetworkSession
> session(
561 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
562 HttpNetworkSessionPeer
peer(session
);
563 CapturePreconnectsTransportSocketPool
* transport_conn_pool
=
564 new CapturePreconnectsTransportSocketPool(
565 session_deps
.host_resolver
.get(),
566 session_deps
.cert_verifier
.get());
567 scoped_ptr
<MockClientSocketPoolManager
> mock_pool_manager(
568 new MockClientSocketPoolManager
);
569 mock_pool_manager
->SetTransportSocketPool(transport_conn_pool
);
570 peer
.SetClientSocketPoolManager(mock_pool_manager
.Pass());
572 PreconnectHelperForURL(1, GURL("http://www.google.com:7"), session
.get());
574 EXPECT_EQ(-1, transport_conn_pool
->last_num_streams());
577 TEST_P(HttpStreamFactoryTest
, JobNotifiesProxy
) {
578 const char* kProxyString
= "PROXY bad:99; PROXY maybe:80; DIRECT";
579 SpdySessionDependencies
session_deps(
580 GetParam(), ProxyService::CreateFixedFromPacResult(kProxyString
));
582 // First connection attempt fails
583 StaticSocketDataProvider socket_data1
;
584 socket_data1
.set_connect_data(MockConnect(ASYNC
, ERR_ADDRESS_UNREACHABLE
));
585 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data1
);
587 // Second connection attempt succeeds
588 StaticSocketDataProvider socket_data2
;
589 socket_data2
.set_connect_data(MockConnect(ASYNC
, OK
));
590 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data2
);
592 scoped_refptr
<HttpNetworkSession
> session(
593 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
595 // Now request a stream. It should succeed using the second proxy in the
597 HttpRequestInfo request_info
;
598 request_info
.method
= "GET";
599 request_info
.url
= GURL("http://www.google.com");
601 SSLConfig ssl_config
;
602 StreamRequestWaiter waiter
;
603 scoped_ptr
<HttpStreamRequest
> request(
604 session
->http_stream_factory()->RequestStream(
605 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
,
606 &waiter
, BoundNetLog()));
607 waiter
.WaitForStream();
609 // The proxy that failed should now be known to the proxy_service as bad.
610 const ProxyRetryInfoMap
& retry_info
=
611 session
->proxy_service()->proxy_retry_info();
612 EXPECT_EQ(1u, retry_info
.size());
613 ProxyRetryInfoMap::const_iterator iter
= retry_info
.find("bad:99");
614 EXPECT_TRUE(iter
!= retry_info
.end());
617 TEST_P(HttpStreamFactoryTest
, UnreachableQuicProxyMarkedAsBad
) {
618 for (int i
= 1; i
<= 2; i
++) {
620 i
== 1 ? ERR_QUIC_PROTOCOL_ERROR
: ERR_QUIC_HANDSHAKE_FAILED
;
622 scoped_ptr
<ProxyService
> proxy_service
;
624 ProxyService::CreateFixedFromPacResult("QUIC bad:99; DIRECT"));
626 HttpNetworkSession::Params params
;
627 params
.enable_quic
= true;
628 params
.enable_quic_for_proxies
= true;
629 scoped_refptr
<SSLConfigServiceDefaults
> ssl_config_service(
630 new SSLConfigServiceDefaults
);
631 HttpServerPropertiesImpl http_server_properties
;
632 MockClientSocketFactory socket_factory
;
633 params
.client_socket_factory
= &socket_factory
;
634 MockHostResolver host_resolver
;
635 params
.host_resolver
= &host_resolver
;
636 TransportSecurityState transport_security_state
;
637 params
.transport_security_state
= &transport_security_state
;
638 params
.proxy_service
= proxy_service
.get();
639 params
.ssl_config_service
= ssl_config_service
.get();
640 params
.http_server_properties
= http_server_properties
.GetWeakPtr();
642 scoped_refptr
<HttpNetworkSession
> session
;
643 session
= new HttpNetworkSession(params
);
644 session
->quic_stream_factory()->set_require_confirmation(false);
646 StaticSocketDataProvider socket_data1
;
647 socket_data1
.set_connect_data(MockConnect(ASYNC
, mock_error
));
648 socket_factory
.AddSocketDataProvider(&socket_data1
);
650 // Second connection attempt succeeds.
651 StaticSocketDataProvider socket_data2
;
652 socket_data2
.set_connect_data(MockConnect(ASYNC
, OK
));
653 socket_factory
.AddSocketDataProvider(&socket_data2
);
655 // Now request a stream. It should succeed using the second proxy in the
657 HttpRequestInfo request_info
;
658 request_info
.method
= "GET";
659 request_info
.url
= GURL("http://www.google.com");
661 SSLConfig ssl_config
;
662 StreamRequestWaiter waiter
;
663 scoped_ptr
<HttpStreamRequest
> request(
664 session
->http_stream_factory()->RequestStream(
665 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
, &waiter
,
667 waiter
.WaitForStream();
669 // The proxy that failed should now be known to the proxy_service as bad.
670 const ProxyRetryInfoMap
& retry_info
=
671 session
->proxy_service()->proxy_retry_info();
672 // proxy_headers_handler.proxy_info_used.proxy_retry_info();
673 EXPECT_EQ(1u, retry_info
.size()) << i
;
674 // EXPECT_TRUE(waiter.used_proxy_info().is_direct());
676 ProxyRetryInfoMap::const_iterator iter
= retry_info
.find("quic://bad:99");
677 EXPECT_TRUE(iter
!= retry_info
.end()) << i
;
681 TEST_P(HttpStreamFactoryTest
, PrivacyModeDisablesChannelId
) {
682 SpdySessionDependencies
session_deps(
683 GetParam(), ProxyService::CreateDirect());
685 StaticSocketDataProvider socket_data
;
686 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
687 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
689 SSLSocketDataProvider
ssl(ASYNC
, OK
);
690 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl
);
692 scoped_refptr
<HttpNetworkSession
> session(
693 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
695 // Set an existing SpdySession in the pool.
696 HostPortPair
host_port_pair("www.google.com", 443);
697 SpdySessionKey
key(host_port_pair
, ProxyServer::Direct(),
698 PRIVACY_MODE_ENABLED
);
700 HttpRequestInfo request_info
;
701 request_info
.method
= "GET";
702 request_info
.url
= GURL("https://www.google.com");
703 request_info
.load_flags
= 0;
704 request_info
.privacy_mode
= PRIVACY_MODE_DISABLED
;
706 SSLConfig ssl_config
;
707 StreamRequestWaiter waiter
;
708 scoped_ptr
<HttpStreamRequest
> request(
709 session
->http_stream_factory()->RequestStream(
710 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
,
711 &waiter
, BoundNetLog()));
712 waiter
.WaitForStream();
714 // The stream shouldn't come from spdy as we are using different privacy mode
715 EXPECT_FALSE(request
->using_spdy());
717 SSLConfig used_ssl_config
= waiter
.used_ssl_config();
718 EXPECT_EQ(used_ssl_config
.channel_id_enabled
, ssl_config
.channel_id_enabled
);
722 // Return count of distinct groups in given socket pool.
723 int GetSocketPoolGroupCount(ClientSocketPool
* pool
) {
725 scoped_ptr
<base::DictionaryValue
> dict(pool
->GetInfoAsValue("", "", false));
726 EXPECT_TRUE(dict
!= nullptr);
727 base::DictionaryValue
* groups
= nullptr;
728 if (dict
->GetDictionary("groups", &groups
) && (groups
!= nullptr)) {
729 count
= static_cast<int>(groups
->size());
735 TEST_P(HttpStreamFactoryTest
, PrivacyModeUsesDifferentSocketPoolGroup
) {
736 SpdySessionDependencies
session_deps(
737 GetParam(), ProxyService::CreateDirect());
739 StaticSocketDataProvider socket_data
;
740 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
741 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
743 SSLSocketDataProvider
ssl(ASYNC
, OK
);
744 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl
);
746 scoped_refptr
<HttpNetworkSession
> session(
747 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
748 SSLClientSocketPool
* ssl_pool
= session
->GetSSLSocketPool(
749 HttpNetworkSession::NORMAL_SOCKET_POOL
);
751 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool
), 0);
753 HttpRequestInfo request_info
;
754 request_info
.method
= "GET";
755 request_info
.url
= GURL("https://www.google.com");
756 request_info
.load_flags
= 0;
757 request_info
.privacy_mode
= PRIVACY_MODE_DISABLED
;
759 SSLConfig ssl_config
;
760 StreamRequestWaiter waiter
;
762 scoped_ptr
<HttpStreamRequest
> request1(
763 session
->http_stream_factory()->RequestStream(
764 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
,
765 &waiter
, BoundNetLog()));
766 waiter
.WaitForStream();
768 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool
), 1);
770 scoped_ptr
<HttpStreamRequest
> request2(
771 session
->http_stream_factory()->RequestStream(
772 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
,
773 &waiter
, BoundNetLog()));
774 waiter
.WaitForStream();
776 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool
), 1);
778 request_info
.privacy_mode
= PRIVACY_MODE_ENABLED
;
779 scoped_ptr
<HttpStreamRequest
> request3(
780 session
->http_stream_factory()->RequestStream(
781 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
,
782 &waiter
, BoundNetLog()));
783 waiter
.WaitForStream();
785 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool
), 2);
788 TEST_P(HttpStreamFactoryTest
, GetLoadState
) {
789 SpdySessionDependencies
session_deps(
790 GetParam(), ProxyService::CreateDirect());
792 StaticSocketDataProvider socket_data
;
793 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
794 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
796 scoped_refptr
<HttpNetworkSession
> session(
797 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
799 HttpRequestInfo request_info
;
800 request_info
.method
= "GET";
801 request_info
.url
= GURL("http://www.google.com");
803 SSLConfig ssl_config
;
804 StreamRequestWaiter waiter
;
805 scoped_ptr
<HttpStreamRequest
> request(
806 session
->http_stream_factory()->RequestStream(
807 request_info
, DEFAULT_PRIORITY
, ssl_config
, ssl_config
,
808 &waiter
, BoundNetLog()));
810 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST
, request
->GetLoadState());
812 waiter
.WaitForStream();
815 TEST_P(HttpStreamFactoryTest
, RequestHttpStream
) {
816 SpdySessionDependencies
session_deps(
817 GetParam(), ProxyService::CreateDirect());
819 StaticSocketDataProvider socket_data
;
820 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
821 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
823 scoped_refptr
<HttpNetworkSession
> session(
824 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
826 // Now request a stream. It should succeed using the second proxy in the
828 HttpRequestInfo request_info
;
829 request_info
.method
= "GET";
830 request_info
.url
= GURL("http://www.google.com");
831 request_info
.load_flags
= 0;
833 SSLConfig ssl_config
;
834 StreamRequestWaiter waiter
;
835 scoped_ptr
<HttpStreamRequest
> request(
836 session
->http_stream_factory()->RequestStream(
843 waiter
.WaitForStream();
844 EXPECT_TRUE(waiter
.stream_done());
845 ASSERT_TRUE(nullptr != waiter
.stream());
846 EXPECT_TRUE(nullptr == waiter
.websocket_stream());
847 EXPECT_FALSE(waiter
.stream()->IsSpdyHttpStream());
849 EXPECT_EQ(1, GetSocketPoolGroupCount(
850 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
851 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSSLSocketPool(
852 HttpNetworkSession::NORMAL_SOCKET_POOL
)));
853 EXPECT_EQ(0, GetSocketPoolGroupCount(
854 session
->GetTransportSocketPool(
855 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
856 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSSLSocketPool(
857 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
858 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
861 TEST_P(HttpStreamFactoryTest
, RequestHttpStreamOverSSL
) {
862 SpdySessionDependencies
session_deps(
863 GetParam(), ProxyService::CreateDirect());
865 MockRead
mock_read(ASYNC
, OK
);
866 StaticSocketDataProvider
socket_data(&mock_read
, 1, nullptr, 0);
867 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
868 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
870 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
871 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl_socket_data
);
873 scoped_refptr
<HttpNetworkSession
> session(
874 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
876 // Now request a stream.
877 HttpRequestInfo request_info
;
878 request_info
.method
= "GET";
879 request_info
.url
= GURL("https://www.google.com");
880 request_info
.load_flags
= 0;
882 SSLConfig ssl_config
;
883 StreamRequestWaiter waiter
;
884 scoped_ptr
<HttpStreamRequest
> request(
885 session
->http_stream_factory()->RequestStream(
892 waiter
.WaitForStream();
893 EXPECT_TRUE(waiter
.stream_done());
894 ASSERT_TRUE(nullptr != waiter
.stream());
895 EXPECT_TRUE(nullptr == waiter
.websocket_stream());
896 EXPECT_FALSE(waiter
.stream()->IsSpdyHttpStream());
897 EXPECT_EQ(1, GetSocketPoolGroupCount(
898 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
899 EXPECT_EQ(1, GetSocketPoolGroupCount(
900 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
901 EXPECT_EQ(0, GetSocketPoolGroupCount(
902 session
->GetTransportSocketPool(
903 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
904 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSSLSocketPool(
905 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
906 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
909 TEST_P(HttpStreamFactoryTest
, RequestHttpStreamOverProxy
) {
910 SpdySessionDependencies
session_deps(
911 GetParam(), ProxyService::CreateFixed("myproxy:8888"));
913 StaticSocketDataProvider socket_data
;
914 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
915 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
917 scoped_refptr
<HttpNetworkSession
> session(
918 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
920 // Now request a stream. It should succeed using the second proxy in the
922 HttpRequestInfo request_info
;
923 request_info
.method
= "GET";
924 request_info
.url
= GURL("http://www.google.com");
925 request_info
.load_flags
= 0;
927 SSLConfig ssl_config
;
928 StreamRequestWaiter waiter
;
929 scoped_ptr
<HttpStreamRequest
> request(
930 session
->http_stream_factory()->RequestStream(
937 waiter
.WaitForStream();
938 EXPECT_TRUE(waiter
.stream_done());
939 ASSERT_TRUE(nullptr != waiter
.stream());
940 EXPECT_TRUE(nullptr == waiter
.websocket_stream());
941 EXPECT_FALSE(waiter
.stream()->IsSpdyHttpStream());
942 EXPECT_EQ(0, GetSocketPoolGroupCount(
943 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
944 EXPECT_EQ(0, GetSocketPoolGroupCount(
945 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
946 EXPECT_EQ(1, GetSocketPoolGroupCount(session
->GetSocketPoolForHTTPProxy(
947 HttpNetworkSession::NORMAL_SOCKET_POOL
,
948 HostPortPair("myproxy", 8888))));
949 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSocketPoolForSSLWithProxy(
950 HttpNetworkSession::NORMAL_SOCKET_POOL
,
951 HostPortPair("myproxy", 8888))));
952 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSocketPoolForHTTPProxy(
953 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
,
954 HostPortPair("myproxy", 8888))));
955 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSocketPoolForSSLWithProxy(
956 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
,
957 HostPortPair("myproxy", 8888))));
958 EXPECT_FALSE(waiter
.used_proxy_info().is_direct());
961 TEST_P(HttpStreamFactoryTest
, RequestWebSocketBasicHandshakeStream
) {
962 SpdySessionDependencies
session_deps(
963 GetParam(), ProxyService::CreateDirect());
965 StaticSocketDataProvider socket_data
;
966 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
967 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
969 scoped_refptr
<HttpNetworkSession
> session(
970 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
972 // Now request a stream.
973 HttpRequestInfo request_info
;
974 request_info
.method
= "GET";
975 request_info
.url
= GURL("ws://www.google.com");
976 request_info
.load_flags
= 0;
978 SSLConfig ssl_config
;
979 StreamRequestWaiter waiter
;
980 WebSocketStreamCreateHelper create_helper
;
981 scoped_ptr
<HttpStreamRequest
> request(
982 session
->http_stream_factory_for_websocket()
983 ->RequestWebSocketHandshakeStream(request_info
,
990 waiter
.WaitForStream();
991 EXPECT_TRUE(waiter
.stream_done());
992 EXPECT_TRUE(nullptr == waiter
.stream());
993 ASSERT_TRUE(nullptr != waiter
.websocket_stream());
994 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic
,
995 waiter
.websocket_stream()->type());
996 EXPECT_EQ(0, GetSocketPoolGroupCount(
997 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
998 EXPECT_EQ(0, GetSocketPoolGroupCount(
999 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1000 EXPECT_EQ(0, GetSocketPoolGroupCount(
1001 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1002 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
1005 TEST_P(HttpStreamFactoryTest
, RequestWebSocketBasicHandshakeStreamOverSSL
) {
1006 SpdySessionDependencies
session_deps(
1007 GetParam(), ProxyService::CreateDirect());
1009 MockRead
mock_read(ASYNC
, OK
);
1010 StaticSocketDataProvider
socket_data(&mock_read
, 1, nullptr, 0);
1011 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
1012 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
1014 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
1015 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl_socket_data
);
1017 scoped_refptr
<HttpNetworkSession
> session(
1018 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
1020 // Now request a stream.
1021 HttpRequestInfo request_info
;
1022 request_info
.method
= "GET";
1023 request_info
.url
= GURL("wss://www.google.com");
1024 request_info
.load_flags
= 0;
1026 SSLConfig ssl_config
;
1027 StreamRequestWaiter waiter
;
1028 WebSocketStreamCreateHelper create_helper
;
1029 scoped_ptr
<HttpStreamRequest
> request(
1030 session
->http_stream_factory_for_websocket()
1031 ->RequestWebSocketHandshakeStream(request_info
,
1038 waiter
.WaitForStream();
1039 EXPECT_TRUE(waiter
.stream_done());
1040 EXPECT_TRUE(nullptr == waiter
.stream());
1041 ASSERT_TRUE(nullptr != waiter
.websocket_stream());
1042 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic
,
1043 waiter
.websocket_stream()->type());
1044 EXPECT_EQ(0, GetSocketPoolGroupCount(
1045 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1046 EXPECT_EQ(0, GetSocketPoolGroupCount(
1047 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1048 EXPECT_EQ(1, GetSocketPoolGroupCount(
1049 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1050 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
1053 TEST_P(HttpStreamFactoryTest
, RequestWebSocketBasicHandshakeStreamOverProxy
) {
1054 SpdySessionDependencies
session_deps(
1055 GetParam(), ProxyService::CreateFixed("myproxy:8888"));
1057 MockRead
read(SYNCHRONOUS
, "HTTP/1.0 200 Connection established\r\n\r\n");
1058 StaticSocketDataProvider
socket_data(&read
, 1, 0, 0);
1059 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
1060 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
1062 scoped_refptr
<HttpNetworkSession
> session(
1063 SpdySessionDependencies::SpdyCreateSession(&session_deps
));
1065 // Now request a stream.
1066 HttpRequestInfo request_info
;
1067 request_info
.method
= "GET";
1068 request_info
.url
= GURL("ws://www.google.com");
1069 request_info
.load_flags
= 0;
1071 SSLConfig ssl_config
;
1072 StreamRequestWaiter waiter
;
1073 WebSocketStreamCreateHelper create_helper
;
1074 scoped_ptr
<HttpStreamRequest
> request(
1075 session
->http_stream_factory_for_websocket()
1076 ->RequestWebSocketHandshakeStream(request_info
,
1083 waiter
.WaitForStream();
1084 EXPECT_TRUE(waiter
.stream_done());
1085 EXPECT_TRUE(nullptr == waiter
.stream());
1086 ASSERT_TRUE(nullptr != waiter
.websocket_stream());
1087 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic
,
1088 waiter
.websocket_stream()->type());
1089 EXPECT_EQ(0, GetSocketPoolGroupCount(
1090 session
->GetTransportSocketPool(
1091 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1092 EXPECT_EQ(0, GetSocketPoolGroupCount(
1093 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1094 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSocketPoolForHTTPProxy(
1095 HttpNetworkSession::NORMAL_SOCKET_POOL
,
1096 HostPortPair("myproxy", 8888))));
1097 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSocketPoolForSSLWithProxy(
1098 HttpNetworkSession::NORMAL_SOCKET_POOL
,
1099 HostPortPair("myproxy", 8888))));
1100 EXPECT_EQ(1, GetSocketPoolGroupCount(session
->GetSocketPoolForHTTPProxy(
1101 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
,
1102 HostPortPair("myproxy", 8888))));
1103 EXPECT_EQ(0, GetSocketPoolGroupCount(session
->GetSocketPoolForSSLWithProxy(
1104 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
,
1105 HostPortPair("myproxy", 8888))));
1106 EXPECT_FALSE(waiter
.used_proxy_info().is_direct());
1109 TEST_P(HttpStreamFactoryTest
, RequestSpdyHttpStream
) {
1110 SpdySessionDependencies
session_deps(GetParam(),
1111 ProxyService::CreateDirect());
1113 MockRead
mock_read(ASYNC
, OK
);
1114 DeterministicSocketData
socket_data(&mock_read
, 1, nullptr, 0);
1115 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
1116 session_deps
.deterministic_socket_factory
->AddSocketDataProvider(
1119 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
1120 ssl_socket_data
.SetNextProto(GetParam());
1121 session_deps
.deterministic_socket_factory
->AddSSLSocketDataProvider(
1124 HostPortPair
host_port_pair("www.google.com", 443);
1125 scoped_refptr
<HttpNetworkSession
>
1126 session(SpdySessionDependencies::SpdyCreateSessionDeterministic(
1129 // Now request a stream.
1130 HttpRequestInfo request_info
;
1131 request_info
.method
= "GET";
1132 request_info
.url
= GURL("https://www.google.com");
1133 request_info
.load_flags
= 0;
1135 SSLConfig ssl_config
;
1136 StreamRequestWaiter waiter
;
1137 scoped_ptr
<HttpStreamRequest
> request(
1138 session
->http_stream_factory()->RequestStream(
1145 waiter
.WaitForStream();
1146 EXPECT_TRUE(waiter
.stream_done());
1147 EXPECT_TRUE(nullptr == waiter
.websocket_stream());
1148 ASSERT_TRUE(nullptr != waiter
.stream());
1149 EXPECT_TRUE(waiter
.stream()->IsSpdyHttpStream());
1150 EXPECT_EQ(1, GetSocketPoolGroupCount(
1151 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1152 EXPECT_EQ(1, GetSocketPoolGroupCount(
1153 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1154 EXPECT_EQ(0, GetSocketPoolGroupCount(
1155 session
->GetTransportSocketPool(
1156 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1157 EXPECT_EQ(0, GetSocketPoolGroupCount(
1158 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1159 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
1162 // TODO(ricea): This test can be removed once the new WebSocket stack supports
1163 // SPDY. Currently, even if we connect to a SPDY-supporting server, we need to
1165 TEST_P(HttpStreamFactoryTest
, RequestWebSocketSpdyHandshakeStreamButGetSSL
) {
1166 SpdySessionDependencies
session_deps(GetParam(),
1167 ProxyService::CreateDirect());
1169 MockRead
mock_read(SYNCHRONOUS
, ERR_IO_PENDING
);
1170 StaticSocketDataProvider
socket_data(&mock_read
, 1, nullptr, 0);
1171 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
1172 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
1174 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
1175 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl_socket_data
);
1177 HostPortPair
host_port_pair("www.google.com", 80);
1178 scoped_refptr
<HttpNetworkSession
>
1179 session(SpdySessionDependencies::SpdyCreateSession(&session_deps
));
1181 // Now request a stream.
1182 HttpRequestInfo request_info
;
1183 request_info
.method
= "GET";
1184 request_info
.url
= GURL("wss://www.google.com");
1185 request_info
.load_flags
= 0;
1187 SSLConfig ssl_config
;
1188 StreamRequestWaiter waiter1
;
1189 WebSocketStreamCreateHelper create_helper
;
1190 scoped_ptr
<HttpStreamRequest
> request1(
1191 session
->http_stream_factory_for_websocket()
1192 ->RequestWebSocketHandshakeStream(request_info
,
1199 waiter1
.WaitForStream();
1200 EXPECT_TRUE(waiter1
.stream_done());
1201 ASSERT_TRUE(nullptr != waiter1
.websocket_stream());
1202 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic
,
1203 waiter1
.websocket_stream()->type());
1204 EXPECT_TRUE(nullptr == waiter1
.stream());
1206 EXPECT_EQ(0, GetSocketPoolGroupCount(
1207 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1208 EXPECT_EQ(0, GetSocketPoolGroupCount(
1209 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1210 EXPECT_EQ(1, GetSocketPoolGroupCount(
1211 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1212 EXPECT_TRUE(waiter1
.used_proxy_info().is_direct());
1215 // TODO(ricea): Re-enable once WebSocket-over-SPDY is implemented.
1216 TEST_P(HttpStreamFactoryTest
, DISABLED_RequestWebSocketSpdyHandshakeStream
) {
1217 SpdySessionDependencies
session_deps(GetParam(),
1218 ProxyService::CreateDirect());
1220 MockRead
mock_read(SYNCHRONOUS
, ERR_IO_PENDING
);
1221 StaticSocketDataProvider
socket_data(&mock_read
, 1, nullptr, 0);
1222 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
1223 session_deps
.socket_factory
->AddSocketDataProvider(&socket_data
);
1225 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
1226 ssl_socket_data
.SetNextProto(GetParam());
1227 session_deps
.socket_factory
->AddSSLSocketDataProvider(&ssl_socket_data
);
1229 HostPortPair
host_port_pair("www.google.com", 80);
1230 scoped_refptr
<HttpNetworkSession
>
1231 session(SpdySessionDependencies::SpdyCreateSession(&session_deps
));
1233 // Now request a stream.
1234 HttpRequestInfo request_info
;
1235 request_info
.method
= "GET";
1236 request_info
.url
= GURL("wss://www.google.com");
1237 request_info
.load_flags
= 0;
1239 SSLConfig ssl_config
;
1240 StreamRequestWaiter waiter1
;
1241 WebSocketStreamCreateHelper create_helper
;
1242 scoped_ptr
<HttpStreamRequest
> request1(
1243 session
->http_stream_factory_for_websocket()
1244 ->RequestWebSocketHandshakeStream(request_info
,
1251 waiter1
.WaitForStream();
1252 EXPECT_TRUE(waiter1
.stream_done());
1253 ASSERT_TRUE(nullptr != waiter1
.websocket_stream());
1254 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy
,
1255 waiter1
.websocket_stream()->type());
1256 EXPECT_TRUE(nullptr == waiter1
.stream());
1258 StreamRequestWaiter waiter2
;
1259 scoped_ptr
<HttpStreamRequest
> request2(
1260 session
->http_stream_factory_for_websocket()
1261 ->RequestWebSocketHandshakeStream(request_info
,
1268 waiter2
.WaitForStream();
1269 EXPECT_TRUE(waiter2
.stream_done());
1270 ASSERT_TRUE(nullptr != waiter2
.websocket_stream());
1271 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy
,
1272 waiter2
.websocket_stream()->type());
1273 EXPECT_TRUE(nullptr == waiter2
.stream());
1274 EXPECT_NE(waiter2
.websocket_stream(), waiter1
.websocket_stream());
1275 EXPECT_EQ(static_cast<WebSocketSpdyHandshakeStream
*>(
1276 waiter2
.websocket_stream())->spdy_session(),
1277 static_cast<WebSocketSpdyHandshakeStream
*>(
1278 waiter1
.websocket_stream())->spdy_session());
1280 EXPECT_EQ(0, GetSocketPoolGroupCount(
1281 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1282 EXPECT_EQ(0, GetSocketPoolGroupCount(
1283 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1284 EXPECT_EQ(1, GetSocketPoolGroupCount(
1285 session
->GetTransportSocketPool(
1286 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1287 EXPECT_EQ(1, GetSocketPoolGroupCount(
1288 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1289 EXPECT_TRUE(waiter1
.used_proxy_info().is_direct());
1292 // TODO(ricea): Re-enable once WebSocket over SPDY is implemented.
1293 TEST_P(HttpStreamFactoryTest
, DISABLED_OrphanedWebSocketStream
) {
1294 SpdySessionDependencies
session_deps(GetParam(),
1295 ProxyService::CreateDirect());
1296 session_deps
.use_alternate_protocols
= true;
1298 MockRead
mock_read(ASYNC
, OK
);
1299 DeterministicSocketData
socket_data(&mock_read
, 1, nullptr, 0);
1300 socket_data
.set_connect_data(MockConnect(ASYNC
, OK
));
1301 session_deps
.deterministic_socket_factory
->AddSocketDataProvider(
1304 MockRead
mock_read2(ASYNC
, OK
);
1305 DeterministicSocketData
socket_data2(&mock_read2
, 1, nullptr, 0);
1306 socket_data2
.set_connect_data(MockConnect(ASYNC
, ERR_IO_PENDING
));
1307 session_deps
.deterministic_socket_factory
->AddSocketDataProvider(
1310 SSLSocketDataProvider
ssl_socket_data(ASYNC
, OK
);
1311 ssl_socket_data
.SetNextProto(GetParam());
1312 session_deps
.deterministic_socket_factory
->AddSSLSocketDataProvider(
1315 scoped_refptr
<HttpNetworkSession
>
1316 session(SpdySessionDependencies::SpdyCreateSessionDeterministic(
1319 // Now request a stream.
1320 HttpRequestInfo request_info
;
1321 request_info
.method
= "GET";
1322 request_info
.url
= GURL("ws://www.google.com:8888");
1323 request_info
.load_flags
= 0;
1325 session
->http_server_properties()->SetAlternativeService(
1326 HostPortPair("www.google.com", 8888),
1327 AlternativeService(NPN_SPDY_4
, "www.google.com", 9999), 1.0);
1329 SSLConfig ssl_config
;
1330 StreamRequestWaiter waiter
;
1331 WebSocketStreamCreateHelper create_helper
;
1332 scoped_ptr
<HttpStreamRequest
> request(
1333 session
->http_stream_factory_for_websocket()
1334 ->RequestWebSocketHandshakeStream(request_info
,
1341 waiter
.WaitForStream();
1342 EXPECT_TRUE(waiter
.stream_done());
1343 EXPECT_TRUE(nullptr == waiter
.stream());
1344 ASSERT_TRUE(nullptr != waiter
.websocket_stream());
1345 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy
,
1346 waiter
.websocket_stream()->type());
1348 // Make sure that there was an alternative connection
1349 // which consumes extra connections.
1350 EXPECT_EQ(0, GetSocketPoolGroupCount(
1351 session
->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1352 EXPECT_EQ(0, GetSocketPoolGroupCount(
1353 session
->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL
)));
1354 EXPECT_EQ(2, GetSocketPoolGroupCount(
1355 session
->GetTransportSocketPool(
1356 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1357 EXPECT_EQ(1, GetSocketPoolGroupCount(
1358 session
->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL
)));
1359 EXPECT_TRUE(waiter
.used_proxy_info().is_direct());
1361 // Make sure there is no orphaned job. it is already canceled.
1362 ASSERT_EQ(0u, static_cast<HttpStreamFactoryImpl
*>(
1363 session
->http_stream_factory_for_websocket())->num_orphaned_jobs());