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