Rename cc::ResourceProvider::ResourceId to cc::ResourceId and move it to its own...
[chromium-blink-merge.git] / net / http / http_stream_factory_impl_unittest.cc
blob6b20b9a712014a1fa8ebe2cdb5d1a35d593f2488
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"
7 #include <string>
8 #include <vector>
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"
42 namespace net {
44 namespace {
46 class MockWebSocketHandshakeStream : public WebSocketHandshakeStreamBase {
47 public:
48 enum StreamType {
49 kStreamTypeBasic,
50 kStreamTypeSpdy,
53 explicit MockWebSocketHandshakeStream(StreamType type) : type_(type) {}
55 ~MockWebSocketHandshakeStream() override {}
57 StreamType type() const {
58 return type_;
61 // HttpStream methods
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,
77 int buf_len,
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 {
89 return false;
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>();
103 private:
104 const StreamType type_;
107 // HttpStreamFactoryImpl subclass that can wait until a preconnect is complete.
108 class MockHttpStreamFactoryImplForPreconnect : public HttpStreamFactoryImpl {
109 public:
110 MockHttpStreamFactoryImplForPreconnect(HttpNetworkSession* session,
111 bool for_websockets)
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;
125 private:
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 {
138 public:
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 {
148 stream_done_ = true;
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 {
160 stream_done_ = true;
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_; }
215 private:
216 bool waiting_for_stream_;
217 bool stream_done_;
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 {
227 public:
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(); }
237 private:
238 base::WeakPtr<SpdySession> spdy_session_;
241 class WebSocketBasicHandshakeStream : public MockWebSocketHandshakeStream {
242 public:
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(); }
254 private:
255 scoped_ptr<ClientSocketHandle> connection_;
258 class WebSocketStreamCreateHelper
259 : public WebSocketHandshakeStreamBase::CreateHelper {
260 public:
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);
276 struct TestCase {
277 int num_streams;
278 bool ssl;
281 TestCase kTests[] = {
282 { 1, false },
283 { 2, false },
284 { 1, true},
285 { 2, true},
288 void PreconnectHelperForURL(int num_streams,
289 const GURL& url,
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";
300 request.url = url;
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 {
317 public:
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 {
331 ADD_FAILURE();
332 return ERR_UNEXPECTED;
335 void RequestSockets(const std::string& group_name,
336 const void* socket_params,
337 int num_sockets,
338 const BoundNetLog& net_log) override {
339 last_num_streams_ = num_sockets;
342 void CancelRequest(const std::string& group_name,
343 ClientSocketHandle* handle) override {
344 ADD_FAILURE();
346 void ReleaseSocket(const std::string& group_name,
347 scoped_ptr<StreamSocket> socket,
348 int id) override {
349 ADD_FAILURE();
351 void CloseIdleSockets() override { ADD_FAILURE(); }
352 int IdleSocketCount() const override {
353 ADD_FAILURE();
354 return 0;
356 int IdleSocketCountInGroup(const std::string& group_name) const override {
357 ADD_FAILURE();
358 return 0;
360 LoadState GetLoadState(const std::string& group_name,
361 const ClientSocketHandle* handle) const override {
362 ADD_FAILURE();
363 return LOAD_STATE_IDLE;
365 base::TimeDelta ConnectionTimeout() const override {
366 return base::TimeDelta();
369 private:
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) {
389 template <>
390 CapturePreconnectsHttpProxySocketPool::CapturePreconnectsSocketPool(
391 HostResolver* /* host_resolver */,
392 CertVerifier* /* cert_verifier */)
393 : HttpProxyClientSocketPool(0, 0, nullptr, nullptr, nullptr),
394 last_num_streams_(-1) {
397 template <>
398 CapturePreconnectsSSLSocketPool::CapturePreconnectsSocketPool(
399 HostResolver* /* host_resolver */,
400 CertVerifier* cert_verifier)
401 : SSLClientSocketPool(0,
403 cert_verifier,
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
411 nullptr,
412 nullptr,
413 nullptr, // ssl_config_service
414 nullptr), // net_log
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,
425 kProtoSPDY4_14,
426 kProtoSPDY4));
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());
449 if (kTests[i].ssl)
450 EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams());
451 else
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());
478 if (kTests[i].ssl)
479 EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams());
480 else
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());
507 if (kTests[i].ssl)
508 EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams());
509 else
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.
544 if (kTests[i].ssl)
545 EXPECT_EQ(-1, ssl_conn_pool->last_num_streams());
546 else
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
553 // the SocketPool.
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
596 // list.
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++) {
619 int mock_error =
620 i == 1 ? ERR_QUIC_PROTOCOL_ERROR : ERR_QUIC_HANDSHAKE_FAILED;
622 scoped_ptr<ProxyService> proxy_service;
623 proxy_service.reset(
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
656 // list.
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,
666 BoundNetLog()));
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);
721 namespace {
722 // Return count of distinct groups in given socket pool.
723 int GetSocketPoolGroupCount(ClientSocketPool* pool) {
724 int count = 0;
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());
731 return count;
733 } // namespace
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
827 // list.
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(
837 request_info,
838 DEFAULT_PRIORITY,
839 ssl_config,
840 ssl_config,
841 &waiter,
842 BoundNetLog()));
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(
886 request_info,
887 DEFAULT_PRIORITY,
888 ssl_config,
889 ssl_config,
890 &waiter,
891 BoundNetLog()));
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
921 // list.
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(
931 request_info,
932 DEFAULT_PRIORITY,
933 ssl_config,
934 ssl_config,
935 &waiter,
936 BoundNetLog()));
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,
984 DEFAULT_PRIORITY,
985 ssl_config,
986 ssl_config,
987 &waiter,
988 &create_helper,
989 BoundNetLog()));
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,
1032 DEFAULT_PRIORITY,
1033 ssl_config,
1034 ssl_config,
1035 &waiter,
1036 &create_helper,
1037 BoundNetLog()));
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,
1077 DEFAULT_PRIORITY,
1078 ssl_config,
1079 ssl_config,
1080 &waiter,
1081 &create_helper,
1082 BoundNetLog()));
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(
1117 &socket_data);
1119 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
1120 ssl_socket_data.SetNextProto(GetParam());
1121 session_deps.deterministic_socket_factory->AddSSLSocketDataProvider(
1122 &ssl_socket_data);
1124 HostPortPair host_port_pair("www.google.com", 443);
1125 scoped_refptr<HttpNetworkSession>
1126 session(SpdySessionDependencies::SpdyCreateSessionDeterministic(
1127 &session_deps));
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(
1139 request_info,
1140 DEFAULT_PRIORITY,
1141 ssl_config,
1142 ssl_config,
1143 &waiter,
1144 BoundNetLog()));
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
1164 // use plain SSL.
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,
1193 DEFAULT_PRIORITY,
1194 ssl_config,
1195 ssl_config,
1196 &waiter1,
1197 &create_helper,
1198 BoundNetLog()));
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,
1245 DEFAULT_PRIORITY,
1246 ssl_config,
1247 ssl_config,
1248 &waiter1,
1249 &create_helper,
1250 BoundNetLog()));
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,
1262 DEFAULT_PRIORITY,
1263 ssl_config,
1264 ssl_config,
1265 &waiter2,
1266 &create_helper,
1267 BoundNetLog()));
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(
1302 &socket_data);
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(
1308 &socket_data2);
1310 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
1311 ssl_socket_data.SetNextProto(GetParam());
1312 session_deps.deterministic_socket_factory->AddSSLSocketDataProvider(
1313 &ssl_socket_data);
1315 scoped_refptr<HttpNetworkSession>
1316 session(SpdySessionDependencies::SpdyCreateSessionDeterministic(
1317 &session_deps));
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,
1335 DEFAULT_PRIORITY,
1336 ssl_config,
1337 ssl_config,
1338 &waiter,
1339 &create_helper,
1340 BoundNetLog()));
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());
1366 } // namespace
1368 } // namespace net