Make Ctrl + T from apps focus the new tab's omnibox on Linux and ChromeOS.
[chromium-blink-merge.git] / net / http / http_stream_factory_impl_unittest.cc
blob1c0b982dade3fdd7c5e11294fee947365818dee6
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, const SSLConfig& used_ssl_config) override {}
170 void OnCertificateError(int status,
171 const SSLConfig& used_ssl_config,
172 const SSLInfo& ssl_info) override {}
174 void OnNeedsProxyAuth(const HttpResponseInfo& proxy_response,
175 const SSLConfig& used_ssl_config,
176 const ProxyInfo& used_proxy_info,
177 HttpAuthController* auth_controller) override {}
179 void OnNeedsClientAuth(const SSLConfig& used_ssl_config,
180 SSLCertRequestInfo* cert_info) override {}
182 void OnHttpsProxyTunnelResponse(const HttpResponseInfo& response_info,
183 const SSLConfig& used_ssl_config,
184 const ProxyInfo& used_proxy_info,
185 HttpStream* stream) override {}
187 void WaitForStream() {
188 while (!stream_done_) {
189 waiting_for_stream_ = true;
190 base::MessageLoop::current()->Run();
191 waiting_for_stream_ = false;
195 const SSLConfig& used_ssl_config() const {
196 return used_ssl_config_;
199 const ProxyInfo& used_proxy_info() const {
200 return used_proxy_info_;
203 HttpStream* stream() {
204 return stream_.get();
207 MockWebSocketHandshakeStream* websocket_stream() {
208 return static_cast<MockWebSocketHandshakeStream*>(websocket_stream_.get());
211 bool stream_done() const { return stream_done_; }
213 private:
214 bool waiting_for_stream_;
215 bool stream_done_;
216 scoped_ptr<HttpStream> stream_;
217 scoped_ptr<WebSocketHandshakeStreamBase> websocket_stream_;
218 SSLConfig used_ssl_config_;
219 ProxyInfo used_proxy_info_;
221 DISALLOW_COPY_AND_ASSIGN(StreamRequestWaiter);
224 class WebSocketSpdyHandshakeStream : public MockWebSocketHandshakeStream {
225 public:
226 explicit WebSocketSpdyHandshakeStream(
227 const base::WeakPtr<SpdySession>& spdy_session)
228 : MockWebSocketHandshakeStream(kStreamTypeSpdy),
229 spdy_session_(spdy_session) {}
231 ~WebSocketSpdyHandshakeStream() override {}
233 SpdySession* spdy_session() { return spdy_session_.get(); }
235 private:
236 base::WeakPtr<SpdySession> spdy_session_;
239 class WebSocketBasicHandshakeStream : public MockWebSocketHandshakeStream {
240 public:
241 explicit WebSocketBasicHandshakeStream(
242 scoped_ptr<ClientSocketHandle> connection)
243 : MockWebSocketHandshakeStream(kStreamTypeBasic),
244 connection_(connection.Pass()) {}
246 ~WebSocketBasicHandshakeStream() override {
247 connection_->socket()->Disconnect();
250 ClientSocketHandle* connection() { return connection_.get(); }
252 private:
253 scoped_ptr<ClientSocketHandle> connection_;
256 class WebSocketStreamCreateHelper
257 : public WebSocketHandshakeStreamBase::CreateHelper {
258 public:
259 ~WebSocketStreamCreateHelper() override {}
261 WebSocketHandshakeStreamBase* CreateBasicStream(
262 scoped_ptr<ClientSocketHandle> connection,
263 bool using_proxy) override {
264 return new WebSocketBasicHandshakeStream(connection.Pass());
267 WebSocketHandshakeStreamBase* CreateSpdyStream(
268 const base::WeakPtr<SpdySession>& spdy_session,
269 bool use_relative_url) override {
270 return new WebSocketSpdyHandshakeStream(spdy_session);
274 struct TestCase {
275 int num_streams;
276 bool ssl;
279 TestCase kTests[] = {
280 { 1, false },
281 { 2, false },
282 { 1, true},
283 { 2, true},
286 void PreconnectHelperForURL(int num_streams,
287 const GURL& url,
288 HttpNetworkSession* session) {
289 HttpNetworkSessionPeer peer(session);
290 MockHttpStreamFactoryImplForPreconnect* mock_factory =
291 new MockHttpStreamFactoryImplForPreconnect(session, false);
292 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(mock_factory));
293 SSLConfig ssl_config;
294 session->ssl_config_service()->GetSSLConfig(&ssl_config);
296 HttpRequestInfo request;
297 request.method = "GET";
298 request.url = url;
299 request.load_flags = 0;
301 session->http_stream_factory()->PreconnectStreams(
302 num_streams, request, DEFAULT_PRIORITY, ssl_config, ssl_config);
303 mock_factory->WaitForPreconnects();
306 void PreconnectHelper(const TestCase& test,
307 HttpNetworkSession* session) {
308 GURL url = test.ssl ? GURL("https://www.google.com") :
309 GURL("http://www.google.com");
310 PreconnectHelperForURL(test.num_streams, url, session);
313 template<typename ParentPool>
314 class CapturePreconnectsSocketPool : public ParentPool {
315 public:
316 CapturePreconnectsSocketPool(HostResolver* host_resolver,
317 CertVerifier* cert_verifier);
319 int last_num_streams() const {
320 return last_num_streams_;
323 int RequestSocket(const std::string& group_name,
324 const void* socket_params,
325 RequestPriority priority,
326 ClientSocketHandle* handle,
327 const CompletionCallback& callback,
328 const BoundNetLog& net_log) override {
329 ADD_FAILURE();
330 return ERR_UNEXPECTED;
333 void RequestSockets(const std::string& group_name,
334 const void* socket_params,
335 int num_sockets,
336 const BoundNetLog& net_log) override {
337 last_num_streams_ = num_sockets;
340 void CancelRequest(const std::string& group_name,
341 ClientSocketHandle* handle) override {
342 ADD_FAILURE();
344 void ReleaseSocket(const std::string& group_name,
345 scoped_ptr<StreamSocket> socket,
346 int id) override {
347 ADD_FAILURE();
349 void CloseIdleSockets() override { ADD_FAILURE(); }
350 int IdleSocketCount() const override {
351 ADD_FAILURE();
352 return 0;
354 int IdleSocketCountInGroup(const std::string& group_name) const override {
355 ADD_FAILURE();
356 return 0;
358 LoadState GetLoadState(const std::string& group_name,
359 const ClientSocketHandle* handle) const override {
360 ADD_FAILURE();
361 return LOAD_STATE_IDLE;
363 base::TimeDelta ConnectionTimeout() const override {
364 return base::TimeDelta();
367 private:
368 int last_num_streams_;
371 typedef CapturePreconnectsSocketPool<TransportClientSocketPool>
372 CapturePreconnectsTransportSocketPool;
373 typedef CapturePreconnectsSocketPool<HttpProxyClientSocketPool>
374 CapturePreconnectsHttpProxySocketPool;
375 typedef CapturePreconnectsSocketPool<SOCKSClientSocketPool>
376 CapturePreconnectsSOCKSSocketPool;
377 typedef CapturePreconnectsSocketPool<SSLClientSocketPool>
378 CapturePreconnectsSSLSocketPool;
380 template <typename ParentPool>
381 CapturePreconnectsSocketPool<ParentPool>::CapturePreconnectsSocketPool(
382 HostResolver* host_resolver,
383 CertVerifier* /* cert_verifier */)
384 : ParentPool(0, 0, host_resolver, nullptr, nullptr), last_num_streams_(-1) {
387 template <>
388 CapturePreconnectsHttpProxySocketPool::CapturePreconnectsSocketPool(
389 HostResolver* /* host_resolver */,
390 CertVerifier* /* cert_verifier */)
391 : HttpProxyClientSocketPool(0, 0, nullptr, nullptr, nullptr),
392 last_num_streams_(-1) {
395 template <>
396 CapturePreconnectsSSLSocketPool::CapturePreconnectsSocketPool(
397 HostResolver* /* host_resolver */,
398 CertVerifier* cert_verifier)
399 : SSLClientSocketPool(0,
401 cert_verifier,
402 nullptr, // channel_id_store
403 nullptr, // transport_security_state
404 nullptr, // cert_transparency_verifier
405 nullptr, // cert_policy_enforcer
406 std::string(), // ssl_session_cache_shard
407 nullptr, // deterministic_socket_factory
408 nullptr, // transport_socket_pool
409 nullptr,
410 nullptr,
411 nullptr, // ssl_config_service
412 nullptr), // net_log
413 last_num_streams_(-1) {
416 class HttpStreamFactoryTest : public ::testing::Test,
417 public ::testing::WithParamInterface<NextProto> {
420 INSTANTIATE_TEST_CASE_P(NextProto,
421 HttpStreamFactoryTest,
422 testing::Values(kProtoSPDY31,
423 kProtoSPDY4_14,
424 kProtoSPDY4));
426 TEST_P(HttpStreamFactoryTest, PreconnectDirect) {
427 for (size_t i = 0; i < arraysize(kTests); ++i) {
428 SpdySessionDependencies session_deps(
429 GetParam(), ProxyService::CreateDirect());
430 scoped_refptr<HttpNetworkSession> session(
431 SpdySessionDependencies::SpdyCreateSession(&session_deps));
432 HttpNetworkSessionPeer peer(session);
433 CapturePreconnectsTransportSocketPool* transport_conn_pool =
434 new CapturePreconnectsTransportSocketPool(
435 session_deps.host_resolver.get(),
436 session_deps.cert_verifier.get());
437 CapturePreconnectsSSLSocketPool* ssl_conn_pool =
438 new CapturePreconnectsSSLSocketPool(
439 session_deps.host_resolver.get(),
440 session_deps.cert_verifier.get());
441 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
442 new MockClientSocketPoolManager);
443 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
444 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
445 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
446 PreconnectHelper(kTests[i], session.get());
447 if (kTests[i].ssl)
448 EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams());
449 else
450 EXPECT_EQ(kTests[i].num_streams, transport_conn_pool->last_num_streams());
454 TEST_P(HttpStreamFactoryTest, PreconnectHttpProxy) {
455 for (size_t i = 0; i < arraysize(kTests); ++i) {
456 SpdySessionDependencies session_deps(
457 GetParam(), ProxyService::CreateFixed("http_proxy"));
458 scoped_refptr<HttpNetworkSession> session(
459 SpdySessionDependencies::SpdyCreateSession(&session_deps));
460 HttpNetworkSessionPeer peer(session);
461 HostPortPair proxy_host("http_proxy", 80);
462 CapturePreconnectsHttpProxySocketPool* http_proxy_pool =
463 new CapturePreconnectsHttpProxySocketPool(
464 session_deps.host_resolver.get(),
465 session_deps.cert_verifier.get());
466 CapturePreconnectsSSLSocketPool* ssl_conn_pool =
467 new CapturePreconnectsSSLSocketPool(
468 session_deps.host_resolver.get(),
469 session_deps.cert_verifier.get());
470 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
471 new MockClientSocketPoolManager);
472 mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
473 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
474 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
475 PreconnectHelper(kTests[i], session.get());
476 if (kTests[i].ssl)
477 EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams());
478 else
479 EXPECT_EQ(kTests[i].num_streams, http_proxy_pool->last_num_streams());
483 TEST_P(HttpStreamFactoryTest, PreconnectSocksProxy) {
484 for (size_t i = 0; i < arraysize(kTests); ++i) {
485 SpdySessionDependencies session_deps(
486 GetParam(), ProxyService::CreateFixed("socks4://socks_proxy:1080"));
487 scoped_refptr<HttpNetworkSession> session(
488 SpdySessionDependencies::SpdyCreateSession(&session_deps));
489 HttpNetworkSessionPeer peer(session);
490 HostPortPair proxy_host("socks_proxy", 1080);
491 CapturePreconnectsSOCKSSocketPool* socks_proxy_pool =
492 new CapturePreconnectsSOCKSSocketPool(
493 session_deps.host_resolver.get(),
494 session_deps.cert_verifier.get());
495 CapturePreconnectsSSLSocketPool* ssl_conn_pool =
496 new CapturePreconnectsSSLSocketPool(
497 session_deps.host_resolver.get(),
498 session_deps.cert_verifier.get());
499 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
500 new MockClientSocketPoolManager);
501 mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_proxy_pool);
502 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
503 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
504 PreconnectHelper(kTests[i], session.get());
505 if (kTests[i].ssl)
506 EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams());
507 else
508 EXPECT_EQ(kTests[i].num_streams, socks_proxy_pool->last_num_streams());
512 TEST_P(HttpStreamFactoryTest, PreconnectDirectWithExistingSpdySession) {
513 for (size_t i = 0; i < arraysize(kTests); ++i) {
514 SpdySessionDependencies session_deps(
515 GetParam(), ProxyService::CreateDirect());
516 scoped_refptr<HttpNetworkSession> session(
517 SpdySessionDependencies::SpdyCreateSession(&session_deps));
518 HttpNetworkSessionPeer peer(session);
520 // Put a SpdySession in the pool.
521 HostPortPair host_port_pair("www.google.com", 443);
522 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
523 PRIVACY_MODE_DISABLED);
524 ignore_result(CreateFakeSpdySession(session->spdy_session_pool(), key));
526 CapturePreconnectsTransportSocketPool* transport_conn_pool =
527 new CapturePreconnectsTransportSocketPool(
528 session_deps.host_resolver.get(),
529 session_deps.cert_verifier.get());
530 CapturePreconnectsSSLSocketPool* ssl_conn_pool =
531 new CapturePreconnectsSSLSocketPool(
532 session_deps.host_resolver.get(),
533 session_deps.cert_verifier.get());
534 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
535 new MockClientSocketPoolManager);
536 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
537 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
538 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
539 PreconnectHelper(kTests[i], session.get());
540 // We shouldn't be preconnecting if we have an existing session, which is
541 // the case for https://www.google.com.
542 if (kTests[i].ssl)
543 EXPECT_EQ(-1, ssl_conn_pool->last_num_streams());
544 else
545 EXPECT_EQ(kTests[i].num_streams,
546 transport_conn_pool->last_num_streams());
550 // Verify that preconnects to unsafe ports are cancelled before they reach
551 // the SocketPool.
552 TEST_P(HttpStreamFactoryTest, PreconnectUnsafePort) {
553 ASSERT_FALSE(IsPortAllowedByDefault(7));
554 ASSERT_FALSE(IsPortAllowedByOverride(7));
556 SpdySessionDependencies session_deps(
557 GetParam(), ProxyService::CreateDirect());
558 scoped_refptr<HttpNetworkSession> session(
559 SpdySessionDependencies::SpdyCreateSession(&session_deps));
560 HttpNetworkSessionPeer peer(session);
561 CapturePreconnectsTransportSocketPool* transport_conn_pool =
562 new CapturePreconnectsTransportSocketPool(
563 session_deps.host_resolver.get(),
564 session_deps.cert_verifier.get());
565 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
566 new MockClientSocketPoolManager);
567 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
568 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
570 PreconnectHelperForURL(1, GURL("http://www.google.com:7"), session.get());
572 EXPECT_EQ(-1, transport_conn_pool->last_num_streams());
575 TEST_P(HttpStreamFactoryTest, JobNotifiesProxy) {
576 const char* kProxyString = "PROXY bad:99; PROXY maybe:80; DIRECT";
577 SpdySessionDependencies session_deps(
578 GetParam(), ProxyService::CreateFixedFromPacResult(kProxyString));
580 // First connection attempt fails
581 StaticSocketDataProvider socket_data1;
582 socket_data1.set_connect_data(MockConnect(ASYNC, ERR_ADDRESS_UNREACHABLE));
583 session_deps.socket_factory->AddSocketDataProvider(&socket_data1);
585 // Second connection attempt succeeds
586 StaticSocketDataProvider socket_data2;
587 socket_data2.set_connect_data(MockConnect(ASYNC, OK));
588 session_deps.socket_factory->AddSocketDataProvider(&socket_data2);
590 scoped_refptr<HttpNetworkSession> session(
591 SpdySessionDependencies::SpdyCreateSession(&session_deps));
593 // Now request a stream. It should succeed using the second proxy in the
594 // list.
595 HttpRequestInfo request_info;
596 request_info.method = "GET";
597 request_info.url = GURL("http://www.google.com");
599 SSLConfig ssl_config;
600 StreamRequestWaiter waiter;
601 scoped_ptr<HttpStreamRequest> request(
602 session->http_stream_factory()->RequestStream(
603 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config,
604 &waiter, BoundNetLog()));
605 waiter.WaitForStream();
607 // The proxy that failed should now be known to the proxy_service as bad.
608 const ProxyRetryInfoMap& retry_info =
609 session->proxy_service()->proxy_retry_info();
610 EXPECT_EQ(1u, retry_info.size());
611 ProxyRetryInfoMap::const_iterator iter = retry_info.find("bad:99");
612 EXPECT_TRUE(iter != retry_info.end());
615 TEST_P(HttpStreamFactoryTest, UnreachableQuicProxyMarkedAsBad) {
616 for (int i = 1; i <= 2; i++) {
617 int mock_error =
618 i == 1 ? ERR_QUIC_PROTOCOL_ERROR : ERR_QUIC_HANDSHAKE_FAILED;
620 scoped_ptr<ProxyService> proxy_service;
621 proxy_service.reset(
622 ProxyService::CreateFixedFromPacResult("QUIC bad:99; DIRECT"));
624 HttpNetworkSession::Params params;
625 params.enable_quic = true;
626 params.enable_quic_for_proxies = true;
627 scoped_refptr<SSLConfigServiceDefaults> ssl_config_service(
628 new SSLConfigServiceDefaults);
629 HttpServerPropertiesImpl http_server_properties;
630 MockClientSocketFactory socket_factory;
631 params.client_socket_factory = &socket_factory;
632 MockHostResolver host_resolver;
633 params.host_resolver = &host_resolver;
634 TransportSecurityState transport_security_state;
635 params.transport_security_state = &transport_security_state;
636 params.proxy_service = proxy_service.get();
637 params.ssl_config_service = ssl_config_service.get();
638 params.http_server_properties = http_server_properties.GetWeakPtr();
640 scoped_refptr<HttpNetworkSession> session;
641 session = new HttpNetworkSession(params);
642 session->quic_stream_factory()->set_require_confirmation(false);
644 StaticSocketDataProvider socket_data1;
645 socket_data1.set_connect_data(MockConnect(ASYNC, mock_error));
646 socket_factory.AddSocketDataProvider(&socket_data1);
648 // Second connection attempt succeeds.
649 StaticSocketDataProvider socket_data2;
650 socket_data2.set_connect_data(MockConnect(ASYNC, OK));
651 socket_factory.AddSocketDataProvider(&socket_data2);
653 // Now request a stream. It should succeed using the second proxy in the
654 // list.
655 HttpRequestInfo request_info;
656 request_info.method = "GET";
657 request_info.url = GURL("http://www.google.com");
659 SSLConfig ssl_config;
660 StreamRequestWaiter waiter;
661 scoped_ptr<HttpStreamRequest> request(
662 session->http_stream_factory()->RequestStream(
663 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter,
664 BoundNetLog()));
665 waiter.WaitForStream();
667 // The proxy that failed should now be known to the proxy_service as bad.
668 const ProxyRetryInfoMap& retry_info =
669 session->proxy_service()->proxy_retry_info();
670 // proxy_headers_handler.proxy_info_used.proxy_retry_info();
671 EXPECT_EQ(1u, retry_info.size()) << i;
672 // EXPECT_TRUE(waiter.used_proxy_info().is_direct());
674 ProxyRetryInfoMap::const_iterator iter = retry_info.find("quic://bad:99");
675 EXPECT_TRUE(iter != retry_info.end()) << i;
679 TEST_P(HttpStreamFactoryTest, PrivacyModeDisablesChannelId) {
680 SpdySessionDependencies session_deps(
681 GetParam(), ProxyService::CreateDirect());
683 StaticSocketDataProvider socket_data;
684 socket_data.set_connect_data(MockConnect(ASYNC, OK));
685 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
687 SSLSocketDataProvider ssl(ASYNC, OK);
688 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
690 scoped_refptr<HttpNetworkSession> session(
691 SpdySessionDependencies::SpdyCreateSession(&session_deps));
693 // Set an existing SpdySession in the pool.
694 HostPortPair host_port_pair("www.google.com", 443);
695 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
696 PRIVACY_MODE_ENABLED);
698 HttpRequestInfo request_info;
699 request_info.method = "GET";
700 request_info.url = GURL("https://www.google.com");
701 request_info.load_flags = 0;
702 request_info.privacy_mode = PRIVACY_MODE_DISABLED;
704 SSLConfig ssl_config;
705 StreamRequestWaiter waiter;
706 scoped_ptr<HttpStreamRequest> request(
707 session->http_stream_factory()->RequestStream(
708 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config,
709 &waiter, BoundNetLog()));
710 waiter.WaitForStream();
712 // The stream shouldn't come from spdy as we are using different privacy mode
713 EXPECT_FALSE(request->using_spdy());
715 SSLConfig used_ssl_config = waiter.used_ssl_config();
716 EXPECT_EQ(used_ssl_config.channel_id_enabled, ssl_config.channel_id_enabled);
719 namespace {
720 // Return count of distinct groups in given socket pool.
721 int GetSocketPoolGroupCount(ClientSocketPool* pool) {
722 int count = 0;
723 scoped_ptr<base::DictionaryValue> dict(pool->GetInfoAsValue("", "", false));
724 EXPECT_TRUE(dict != nullptr);
725 base::DictionaryValue* groups = nullptr;
726 if (dict->GetDictionary("groups", &groups) && (groups != nullptr)) {
727 count = static_cast<int>(groups->size());
729 return count;
731 } // namespace
733 TEST_P(HttpStreamFactoryTest, PrivacyModeUsesDifferentSocketPoolGroup) {
734 SpdySessionDependencies session_deps(
735 GetParam(), ProxyService::CreateDirect());
737 StaticSocketDataProvider socket_data;
738 socket_data.set_connect_data(MockConnect(ASYNC, OK));
739 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
741 SSLSocketDataProvider ssl(ASYNC, OK);
742 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
744 scoped_refptr<HttpNetworkSession> session(
745 SpdySessionDependencies::SpdyCreateSession(&session_deps));
746 SSLClientSocketPool* ssl_pool = session->GetSSLSocketPool(
747 HttpNetworkSession::NORMAL_SOCKET_POOL);
749 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 0);
751 HttpRequestInfo request_info;
752 request_info.method = "GET";
753 request_info.url = GURL("https://www.google.com");
754 request_info.load_flags = 0;
755 request_info.privacy_mode = PRIVACY_MODE_DISABLED;
757 SSLConfig ssl_config;
758 StreamRequestWaiter waiter;
760 scoped_ptr<HttpStreamRequest> request1(
761 session->http_stream_factory()->RequestStream(
762 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config,
763 &waiter, BoundNetLog()));
764 waiter.WaitForStream();
766 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 1);
768 scoped_ptr<HttpStreamRequest> request2(
769 session->http_stream_factory()->RequestStream(
770 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config,
771 &waiter, BoundNetLog()));
772 waiter.WaitForStream();
774 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 1);
776 request_info.privacy_mode = PRIVACY_MODE_ENABLED;
777 scoped_ptr<HttpStreamRequest> request3(
778 session->http_stream_factory()->RequestStream(
779 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config,
780 &waiter, BoundNetLog()));
781 waiter.WaitForStream();
783 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 2);
786 TEST_P(HttpStreamFactoryTest, GetLoadState) {
787 SpdySessionDependencies session_deps(
788 GetParam(), ProxyService::CreateDirect());
790 StaticSocketDataProvider socket_data;
791 socket_data.set_connect_data(MockConnect(ASYNC, OK));
792 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
794 scoped_refptr<HttpNetworkSession> session(
795 SpdySessionDependencies::SpdyCreateSession(&session_deps));
797 HttpRequestInfo request_info;
798 request_info.method = "GET";
799 request_info.url = GURL("http://www.google.com");
801 SSLConfig ssl_config;
802 StreamRequestWaiter waiter;
803 scoped_ptr<HttpStreamRequest> request(
804 session->http_stream_factory()->RequestStream(
805 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config,
806 &waiter, BoundNetLog()));
808 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, request->GetLoadState());
810 waiter.WaitForStream();
813 TEST_P(HttpStreamFactoryTest, RequestHttpStream) {
814 SpdySessionDependencies session_deps(
815 GetParam(), ProxyService::CreateDirect());
817 StaticSocketDataProvider socket_data;
818 socket_data.set_connect_data(MockConnect(ASYNC, OK));
819 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
821 scoped_refptr<HttpNetworkSession> session(
822 SpdySessionDependencies::SpdyCreateSession(&session_deps));
824 // Now request a stream. It should succeed using the second proxy in the
825 // list.
826 HttpRequestInfo request_info;
827 request_info.method = "GET";
828 request_info.url = GURL("http://www.google.com");
829 request_info.load_flags = 0;
831 SSLConfig ssl_config;
832 StreamRequestWaiter waiter;
833 scoped_ptr<HttpStreamRequest> request(
834 session->http_stream_factory()->RequestStream(
835 request_info,
836 DEFAULT_PRIORITY,
837 ssl_config,
838 ssl_config,
839 &waiter,
840 BoundNetLog()));
841 waiter.WaitForStream();
842 EXPECT_TRUE(waiter.stream_done());
843 ASSERT_TRUE(nullptr != waiter.stream());
844 EXPECT_TRUE(nullptr == waiter.websocket_stream());
845 EXPECT_FALSE(waiter.stream()->IsSpdyHttpStream());
847 EXPECT_EQ(1, GetSocketPoolGroupCount(
848 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
849 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool(
850 HttpNetworkSession::NORMAL_SOCKET_POOL)));
851 EXPECT_EQ(0, GetSocketPoolGroupCount(
852 session->GetTransportSocketPool(
853 HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
854 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool(
855 HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
856 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
859 TEST_P(HttpStreamFactoryTest, RequestHttpStreamOverSSL) {
860 SpdySessionDependencies session_deps(
861 GetParam(), ProxyService::CreateDirect());
863 MockRead mock_read(ASYNC, OK);
864 StaticSocketDataProvider socket_data(&mock_read, 1, nullptr, 0);
865 socket_data.set_connect_data(MockConnect(ASYNC, OK));
866 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
868 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
869 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
871 scoped_refptr<HttpNetworkSession> session(
872 SpdySessionDependencies::SpdyCreateSession(&session_deps));
874 // Now request a stream.
875 HttpRequestInfo request_info;
876 request_info.method = "GET";
877 request_info.url = GURL("https://www.google.com");
878 request_info.load_flags = 0;
880 SSLConfig ssl_config;
881 StreamRequestWaiter waiter;
882 scoped_ptr<HttpStreamRequest> request(
883 session->http_stream_factory()->RequestStream(
884 request_info,
885 DEFAULT_PRIORITY,
886 ssl_config,
887 ssl_config,
888 &waiter,
889 BoundNetLog()));
890 waiter.WaitForStream();
891 EXPECT_TRUE(waiter.stream_done());
892 ASSERT_TRUE(nullptr != waiter.stream());
893 EXPECT_TRUE(nullptr == waiter.websocket_stream());
894 EXPECT_FALSE(waiter.stream()->IsSpdyHttpStream());
895 EXPECT_EQ(1, GetSocketPoolGroupCount(
896 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
897 EXPECT_EQ(1, GetSocketPoolGroupCount(
898 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
899 EXPECT_EQ(0, GetSocketPoolGroupCount(
900 session->GetTransportSocketPool(
901 HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
902 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool(
903 HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
904 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
907 TEST_P(HttpStreamFactoryTest, RequestHttpStreamOverProxy) {
908 SpdySessionDependencies session_deps(
909 GetParam(), ProxyService::CreateFixed("myproxy:8888"));
911 StaticSocketDataProvider socket_data;
912 socket_data.set_connect_data(MockConnect(ASYNC, OK));
913 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
915 scoped_refptr<HttpNetworkSession> session(
916 SpdySessionDependencies::SpdyCreateSession(&session_deps));
918 // Now request a stream. It should succeed using the second proxy in the
919 // list.
920 HttpRequestInfo request_info;
921 request_info.method = "GET";
922 request_info.url = GURL("http://www.google.com");
923 request_info.load_flags = 0;
925 SSLConfig ssl_config;
926 StreamRequestWaiter waiter;
927 scoped_ptr<HttpStreamRequest> request(
928 session->http_stream_factory()->RequestStream(
929 request_info,
930 DEFAULT_PRIORITY,
931 ssl_config,
932 ssl_config,
933 &waiter,
934 BoundNetLog()));
935 waiter.WaitForStream();
936 EXPECT_TRUE(waiter.stream_done());
937 ASSERT_TRUE(nullptr != waiter.stream());
938 EXPECT_TRUE(nullptr == waiter.websocket_stream());
939 EXPECT_FALSE(waiter.stream()->IsSpdyHttpStream());
940 EXPECT_EQ(0, GetSocketPoolGroupCount(
941 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
942 EXPECT_EQ(0, GetSocketPoolGroupCount(
943 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
944 EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSocketPoolForHTTPProxy(
945 HttpNetworkSession::NORMAL_SOCKET_POOL,
946 HostPortPair("myproxy", 8888))));
947 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForSSLWithProxy(
948 HttpNetworkSession::NORMAL_SOCKET_POOL,
949 HostPortPair("myproxy", 8888))));
950 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForHTTPProxy(
951 HttpNetworkSession::WEBSOCKET_SOCKET_POOL,
952 HostPortPair("myproxy", 8888))));
953 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForSSLWithProxy(
954 HttpNetworkSession::WEBSOCKET_SOCKET_POOL,
955 HostPortPair("myproxy", 8888))));
956 EXPECT_FALSE(waiter.used_proxy_info().is_direct());
959 TEST_P(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStream) {
960 SpdySessionDependencies session_deps(
961 GetParam(), ProxyService::CreateDirect());
963 StaticSocketDataProvider socket_data;
964 socket_data.set_connect_data(MockConnect(ASYNC, OK));
965 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
967 scoped_refptr<HttpNetworkSession> session(
968 SpdySessionDependencies::SpdyCreateSession(&session_deps));
970 // Now request a stream.
971 HttpRequestInfo request_info;
972 request_info.method = "GET";
973 request_info.url = GURL("ws://www.google.com");
974 request_info.load_flags = 0;
976 SSLConfig ssl_config;
977 StreamRequestWaiter waiter;
978 WebSocketStreamCreateHelper create_helper;
979 scoped_ptr<HttpStreamRequest> request(
980 session->http_stream_factory_for_websocket()
981 ->RequestWebSocketHandshakeStream(request_info,
982 DEFAULT_PRIORITY,
983 ssl_config,
984 ssl_config,
985 &waiter,
986 &create_helper,
987 BoundNetLog()));
988 waiter.WaitForStream();
989 EXPECT_TRUE(waiter.stream_done());
990 EXPECT_TRUE(nullptr == waiter.stream());
991 ASSERT_TRUE(nullptr != waiter.websocket_stream());
992 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic,
993 waiter.websocket_stream()->type());
994 EXPECT_EQ(0, GetSocketPoolGroupCount(
995 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
996 EXPECT_EQ(0, GetSocketPoolGroupCount(
997 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
998 EXPECT_EQ(0, GetSocketPoolGroupCount(
999 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1000 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
1003 TEST_P(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStreamOverSSL) {
1004 SpdySessionDependencies session_deps(
1005 GetParam(), ProxyService::CreateDirect());
1007 MockRead mock_read(ASYNC, OK);
1008 StaticSocketDataProvider socket_data(&mock_read, 1, nullptr, 0);
1009 socket_data.set_connect_data(MockConnect(ASYNC, OK));
1010 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
1012 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
1013 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
1015 scoped_refptr<HttpNetworkSession> session(
1016 SpdySessionDependencies::SpdyCreateSession(&session_deps));
1018 // Now request a stream.
1019 HttpRequestInfo request_info;
1020 request_info.method = "GET";
1021 request_info.url = GURL("wss://www.google.com");
1022 request_info.load_flags = 0;
1024 SSLConfig ssl_config;
1025 StreamRequestWaiter waiter;
1026 WebSocketStreamCreateHelper create_helper;
1027 scoped_ptr<HttpStreamRequest> request(
1028 session->http_stream_factory_for_websocket()
1029 ->RequestWebSocketHandshakeStream(request_info,
1030 DEFAULT_PRIORITY,
1031 ssl_config,
1032 ssl_config,
1033 &waiter,
1034 &create_helper,
1035 BoundNetLog()));
1036 waiter.WaitForStream();
1037 EXPECT_TRUE(waiter.stream_done());
1038 EXPECT_TRUE(nullptr == waiter.stream());
1039 ASSERT_TRUE(nullptr != waiter.websocket_stream());
1040 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic,
1041 waiter.websocket_stream()->type());
1042 EXPECT_EQ(0, GetSocketPoolGroupCount(
1043 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1044 EXPECT_EQ(0, GetSocketPoolGroupCount(
1045 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1046 EXPECT_EQ(1, GetSocketPoolGroupCount(
1047 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1048 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
1051 TEST_P(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStreamOverProxy) {
1052 SpdySessionDependencies session_deps(
1053 GetParam(), ProxyService::CreateFixed("myproxy:8888"));
1055 MockRead read(SYNCHRONOUS, "HTTP/1.0 200 Connection established\r\n\r\n");
1056 StaticSocketDataProvider socket_data(&read, 1, 0, 0);
1057 socket_data.set_connect_data(MockConnect(ASYNC, OK));
1058 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
1060 scoped_refptr<HttpNetworkSession> session(
1061 SpdySessionDependencies::SpdyCreateSession(&session_deps));
1063 // Now request a stream.
1064 HttpRequestInfo request_info;
1065 request_info.method = "GET";
1066 request_info.url = GURL("ws://www.google.com");
1067 request_info.load_flags = 0;
1069 SSLConfig ssl_config;
1070 StreamRequestWaiter waiter;
1071 WebSocketStreamCreateHelper create_helper;
1072 scoped_ptr<HttpStreamRequest> request(
1073 session->http_stream_factory_for_websocket()
1074 ->RequestWebSocketHandshakeStream(request_info,
1075 DEFAULT_PRIORITY,
1076 ssl_config,
1077 ssl_config,
1078 &waiter,
1079 &create_helper,
1080 BoundNetLog()));
1081 waiter.WaitForStream();
1082 EXPECT_TRUE(waiter.stream_done());
1083 EXPECT_TRUE(nullptr == waiter.stream());
1084 ASSERT_TRUE(nullptr != waiter.websocket_stream());
1085 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic,
1086 waiter.websocket_stream()->type());
1087 EXPECT_EQ(0, GetSocketPoolGroupCount(
1088 session->GetTransportSocketPool(
1089 HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1090 EXPECT_EQ(0, GetSocketPoolGroupCount(
1091 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1092 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForHTTPProxy(
1093 HttpNetworkSession::NORMAL_SOCKET_POOL,
1094 HostPortPair("myproxy", 8888))));
1095 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForSSLWithProxy(
1096 HttpNetworkSession::NORMAL_SOCKET_POOL,
1097 HostPortPair("myproxy", 8888))));
1098 EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSocketPoolForHTTPProxy(
1099 HttpNetworkSession::WEBSOCKET_SOCKET_POOL,
1100 HostPortPair("myproxy", 8888))));
1101 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForSSLWithProxy(
1102 HttpNetworkSession::WEBSOCKET_SOCKET_POOL,
1103 HostPortPair("myproxy", 8888))));
1104 EXPECT_FALSE(waiter.used_proxy_info().is_direct());
1107 TEST_P(HttpStreamFactoryTest, RequestSpdyHttpStream) {
1108 SpdySessionDependencies session_deps(GetParam(),
1109 ProxyService::CreateDirect());
1111 MockRead mock_read(ASYNC, OK);
1112 DeterministicSocketData socket_data(&mock_read, 1, nullptr, 0);
1113 socket_data.set_connect_data(MockConnect(ASYNC, OK));
1114 session_deps.deterministic_socket_factory->AddSocketDataProvider(
1115 &socket_data);
1117 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
1118 ssl_socket_data.SetNextProto(GetParam());
1119 session_deps.deterministic_socket_factory->AddSSLSocketDataProvider(
1120 &ssl_socket_data);
1122 HostPortPair host_port_pair("www.google.com", 443);
1123 scoped_refptr<HttpNetworkSession>
1124 session(SpdySessionDependencies::SpdyCreateSessionDeterministic(
1125 &session_deps));
1127 // Now request a stream.
1128 HttpRequestInfo request_info;
1129 request_info.method = "GET";
1130 request_info.url = GURL("https://www.google.com");
1131 request_info.load_flags = 0;
1133 SSLConfig ssl_config;
1134 StreamRequestWaiter waiter;
1135 scoped_ptr<HttpStreamRequest> request(
1136 session->http_stream_factory()->RequestStream(
1137 request_info,
1138 DEFAULT_PRIORITY,
1139 ssl_config,
1140 ssl_config,
1141 &waiter,
1142 BoundNetLog()));
1143 waiter.WaitForStream();
1144 EXPECT_TRUE(waiter.stream_done());
1145 EXPECT_TRUE(nullptr == waiter.websocket_stream());
1146 ASSERT_TRUE(nullptr != waiter.stream());
1147 EXPECT_TRUE(waiter.stream()->IsSpdyHttpStream());
1148 EXPECT_EQ(1, GetSocketPoolGroupCount(
1149 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1150 EXPECT_EQ(1, GetSocketPoolGroupCount(
1151 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1152 EXPECT_EQ(0, GetSocketPoolGroupCount(
1153 session->GetTransportSocketPool(
1154 HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1155 EXPECT_EQ(0, GetSocketPoolGroupCount(
1156 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1157 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
1160 // TODO(ricea): This test can be removed once the new WebSocket stack supports
1161 // SPDY. Currently, even if we connect to a SPDY-supporting server, we need to
1162 // use plain SSL.
1163 TEST_P(HttpStreamFactoryTest, RequestWebSocketSpdyHandshakeStreamButGetSSL) {
1164 SpdySessionDependencies session_deps(GetParam(),
1165 ProxyService::CreateDirect());
1167 MockRead mock_read(SYNCHRONOUS, ERR_IO_PENDING);
1168 StaticSocketDataProvider socket_data(&mock_read, 1, nullptr, 0);
1169 socket_data.set_connect_data(MockConnect(ASYNC, OK));
1170 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
1172 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
1173 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
1175 HostPortPair host_port_pair("www.google.com", 80);
1176 scoped_refptr<HttpNetworkSession>
1177 session(SpdySessionDependencies::SpdyCreateSession(&session_deps));
1179 // Now request a stream.
1180 HttpRequestInfo request_info;
1181 request_info.method = "GET";
1182 request_info.url = GURL("wss://www.google.com");
1183 request_info.load_flags = 0;
1185 SSLConfig ssl_config;
1186 StreamRequestWaiter waiter1;
1187 WebSocketStreamCreateHelper create_helper;
1188 scoped_ptr<HttpStreamRequest> request1(
1189 session->http_stream_factory_for_websocket()
1190 ->RequestWebSocketHandshakeStream(request_info,
1191 DEFAULT_PRIORITY,
1192 ssl_config,
1193 ssl_config,
1194 &waiter1,
1195 &create_helper,
1196 BoundNetLog()));
1197 waiter1.WaitForStream();
1198 EXPECT_TRUE(waiter1.stream_done());
1199 ASSERT_TRUE(nullptr != waiter1.websocket_stream());
1200 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic,
1201 waiter1.websocket_stream()->type());
1202 EXPECT_TRUE(nullptr == waiter1.stream());
1204 EXPECT_EQ(0, GetSocketPoolGroupCount(
1205 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1206 EXPECT_EQ(0, GetSocketPoolGroupCount(
1207 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1208 EXPECT_EQ(1, GetSocketPoolGroupCount(
1209 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1210 EXPECT_TRUE(waiter1.used_proxy_info().is_direct());
1213 // TODO(ricea): Re-enable once WebSocket-over-SPDY is implemented.
1214 TEST_P(HttpStreamFactoryTest, DISABLED_RequestWebSocketSpdyHandshakeStream) {
1215 SpdySessionDependencies session_deps(GetParam(),
1216 ProxyService::CreateDirect());
1218 MockRead mock_read(SYNCHRONOUS, ERR_IO_PENDING);
1219 StaticSocketDataProvider socket_data(&mock_read, 1, nullptr, 0);
1220 socket_data.set_connect_data(MockConnect(ASYNC, OK));
1221 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
1223 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
1224 ssl_socket_data.SetNextProto(GetParam());
1225 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
1227 HostPortPair host_port_pair("www.google.com", 80);
1228 scoped_refptr<HttpNetworkSession>
1229 session(SpdySessionDependencies::SpdyCreateSession(&session_deps));
1231 // Now request a stream.
1232 HttpRequestInfo request_info;
1233 request_info.method = "GET";
1234 request_info.url = GURL("wss://www.google.com");
1235 request_info.load_flags = 0;
1237 SSLConfig ssl_config;
1238 StreamRequestWaiter waiter1;
1239 WebSocketStreamCreateHelper create_helper;
1240 scoped_ptr<HttpStreamRequest> request1(
1241 session->http_stream_factory_for_websocket()
1242 ->RequestWebSocketHandshakeStream(request_info,
1243 DEFAULT_PRIORITY,
1244 ssl_config,
1245 ssl_config,
1246 &waiter1,
1247 &create_helper,
1248 BoundNetLog()));
1249 waiter1.WaitForStream();
1250 EXPECT_TRUE(waiter1.stream_done());
1251 ASSERT_TRUE(nullptr != waiter1.websocket_stream());
1252 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy,
1253 waiter1.websocket_stream()->type());
1254 EXPECT_TRUE(nullptr == waiter1.stream());
1256 StreamRequestWaiter waiter2;
1257 scoped_ptr<HttpStreamRequest> request2(
1258 session->http_stream_factory_for_websocket()
1259 ->RequestWebSocketHandshakeStream(request_info,
1260 DEFAULT_PRIORITY,
1261 ssl_config,
1262 ssl_config,
1263 &waiter2,
1264 &create_helper,
1265 BoundNetLog()));
1266 waiter2.WaitForStream();
1267 EXPECT_TRUE(waiter2.stream_done());
1268 ASSERT_TRUE(nullptr != waiter2.websocket_stream());
1269 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy,
1270 waiter2.websocket_stream()->type());
1271 EXPECT_TRUE(nullptr == waiter2.stream());
1272 EXPECT_NE(waiter2.websocket_stream(), waiter1.websocket_stream());
1273 EXPECT_EQ(static_cast<WebSocketSpdyHandshakeStream*>(
1274 waiter2.websocket_stream())->spdy_session(),
1275 static_cast<WebSocketSpdyHandshakeStream*>(
1276 waiter1.websocket_stream())->spdy_session());
1278 EXPECT_EQ(0, GetSocketPoolGroupCount(
1279 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1280 EXPECT_EQ(0, GetSocketPoolGroupCount(
1281 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1282 EXPECT_EQ(1, GetSocketPoolGroupCount(
1283 session->GetTransportSocketPool(
1284 HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1285 EXPECT_EQ(1, GetSocketPoolGroupCount(
1286 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1287 EXPECT_TRUE(waiter1.used_proxy_info().is_direct());
1290 // TODO(ricea): Re-enable once WebSocket over SPDY is implemented.
1291 TEST_P(HttpStreamFactoryTest, DISABLED_OrphanedWebSocketStream) {
1292 SpdySessionDependencies session_deps(GetParam(),
1293 ProxyService::CreateDirect());
1294 session_deps.use_alternate_protocols = true;
1296 MockRead mock_read(ASYNC, OK);
1297 DeterministicSocketData socket_data(&mock_read, 1, nullptr, 0);
1298 socket_data.set_connect_data(MockConnect(ASYNC, OK));
1299 session_deps.deterministic_socket_factory->AddSocketDataProvider(
1300 &socket_data);
1302 MockRead mock_read2(ASYNC, OK);
1303 DeterministicSocketData socket_data2(&mock_read2, 1, nullptr, 0);
1304 socket_data2.set_connect_data(MockConnect(ASYNC, ERR_IO_PENDING));
1305 session_deps.deterministic_socket_factory->AddSocketDataProvider(
1306 &socket_data2);
1308 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
1309 ssl_socket_data.SetNextProto(GetParam());
1310 session_deps.deterministic_socket_factory->AddSSLSocketDataProvider(
1311 &ssl_socket_data);
1313 scoped_refptr<HttpNetworkSession>
1314 session(SpdySessionDependencies::SpdyCreateSessionDeterministic(
1315 &session_deps));
1317 // Now request a stream.
1318 HttpRequestInfo request_info;
1319 request_info.method = "GET";
1320 request_info.url = GURL("ws://www.google.com:8888");
1321 request_info.load_flags = 0;
1323 session->http_server_properties()->SetAlternativeService(
1324 HostPortPair("www.google.com", 8888),
1325 AlternativeService(NPN_SPDY_4, "www.google.com", 9999), 1.0);
1327 SSLConfig ssl_config;
1328 StreamRequestWaiter waiter;
1329 WebSocketStreamCreateHelper create_helper;
1330 scoped_ptr<HttpStreamRequest> request(
1331 session->http_stream_factory_for_websocket()
1332 ->RequestWebSocketHandshakeStream(request_info,
1333 DEFAULT_PRIORITY,
1334 ssl_config,
1335 ssl_config,
1336 &waiter,
1337 &create_helper,
1338 BoundNetLog()));
1339 waiter.WaitForStream();
1340 EXPECT_TRUE(waiter.stream_done());
1341 EXPECT_TRUE(nullptr == waiter.stream());
1342 ASSERT_TRUE(nullptr != waiter.websocket_stream());
1343 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy,
1344 waiter.websocket_stream()->type());
1346 // Make sure that there was an alternative connection
1347 // which consumes extra connections.
1348 EXPECT_EQ(0, GetSocketPoolGroupCount(
1349 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1350 EXPECT_EQ(0, GetSocketPoolGroupCount(
1351 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1352 EXPECT_EQ(2, GetSocketPoolGroupCount(
1353 session->GetTransportSocketPool(
1354 HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1355 EXPECT_EQ(1, GetSocketPoolGroupCount(
1356 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1357 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
1359 // Make sure there is no orphaned job. it is already canceled.
1360 ASSERT_EQ(0u, static_cast<HttpStreamFactoryImpl*>(
1361 session->http_stream_factory_for_websocket())->num_orphaned_jobs());
1364 } // namespace
1366 } // namespace net