Revert "Fix broken channel icon in chrome://help on CrOS" and try again
[chromium-blink-merge.git] / net / http / http_stream_factory_impl_unittest.cc
bloba3a624a48e5eca3dce2dc5f44e7e79617ad1e6fb
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/port_util.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/log/net_log.h"
26 #include "net/proxy/proxy_info.h"
27 #include "net/proxy/proxy_service.h"
28 #include "net/socket/client_socket_handle.h"
29 #include "net/socket/mock_client_socket_pool_manager.h"
30 #include "net/socket/next_proto.h"
31 #include "net/socket/socket_test_util.h"
32 #include "net/spdy/spdy_session.h"
33 #include "net/spdy/spdy_session_pool.h"
34 #include "net/spdy/spdy_test_util_common.h"
35 #include "net/ssl/ssl_config_service.h"
36 #include "net/ssl/ssl_config_service_defaults.h"
37 // This file can be included from net/http even though
38 // it is in net/websockets because it doesn't
39 // introduce any link dependency to net/websockets.
40 #include "net/websockets/websocket_handshake_stream_base.h"
41 #include "testing/gtest/include/gtest/gtest.h"
43 namespace net {
45 namespace {
47 class MockWebSocketHandshakeStream : public WebSocketHandshakeStreamBase {
48 public:
49 enum StreamType {
50 kStreamTypeBasic,
51 kStreamTypeSpdy,
54 explicit MockWebSocketHandshakeStream(StreamType type) : type_(type) {}
56 ~MockWebSocketHandshakeStream() override {}
58 StreamType type() const {
59 return type_;
62 // HttpStream methods
63 int InitializeStream(const HttpRequestInfo* request_info,
64 RequestPriority priority,
65 const BoundNetLog& net_log,
66 const CompletionCallback& callback) override {
67 return ERR_IO_PENDING;
69 int SendRequest(const HttpRequestHeaders& request_headers,
70 HttpResponseInfo* response,
71 const CompletionCallback& callback) override {
72 return ERR_IO_PENDING;
74 int ReadResponseHeaders(const CompletionCallback& callback) override {
75 return ERR_IO_PENDING;
77 int ReadResponseBody(IOBuffer* buf,
78 int buf_len,
79 const CompletionCallback& callback) override {
80 return ERR_IO_PENDING;
82 void Close(bool not_reusable) override {}
83 bool IsResponseBodyComplete() const override { return false; }
84 bool CanFindEndOfResponse() const override { return false; }
85 bool IsConnectionReused() const override { return false; }
86 void SetConnectionReused() override {}
87 bool IsConnectionReusable() const override { return false; }
88 int64 GetTotalReceivedBytes() const override { return 0; }
89 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
90 return false;
92 void GetSSLInfo(SSLInfo* ssl_info) override {}
93 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {}
94 bool IsSpdyHttpStream() const override { return false; }
95 void Drain(HttpNetworkSession* session) override {}
96 void SetPriority(RequestPriority priority) override {}
97 UploadProgress GetUploadProgress() const override { return UploadProgress(); }
98 HttpStream* RenewStreamForAuth() override { return nullptr; }
100 scoped_ptr<WebSocketStream> Upgrade() override {
101 return scoped_ptr<WebSocketStream>();
104 private:
105 const StreamType type_;
108 // HttpStreamFactoryImpl subclass that can wait until a preconnect is complete.
109 class MockHttpStreamFactoryImplForPreconnect : public HttpStreamFactoryImpl {
110 public:
111 MockHttpStreamFactoryImplForPreconnect(HttpNetworkSession* session,
112 bool for_websockets)
113 : HttpStreamFactoryImpl(session, for_websockets),
114 preconnect_done_(false),
115 waiting_for_preconnect_(false) {}
118 void WaitForPreconnects() {
119 while (!preconnect_done_) {
120 waiting_for_preconnect_ = true;
121 base::MessageLoop::current()->Run();
122 waiting_for_preconnect_ = false;
126 private:
127 // HttpStreamFactoryImpl methods.
128 void OnPreconnectsCompleteInternal() override {
129 preconnect_done_ = true;
130 if (waiting_for_preconnect_)
131 base::MessageLoop::current()->Quit();
134 bool preconnect_done_;
135 bool waiting_for_preconnect_;
138 class StreamRequestWaiter : public HttpStreamRequest::Delegate {
139 public:
140 StreamRequestWaiter()
141 : waiting_for_stream_(false),
142 stream_done_(false) {}
144 // HttpStreamRequest::Delegate
146 void OnStreamReady(const SSLConfig& used_ssl_config,
147 const ProxyInfo& used_proxy_info,
148 HttpStream* stream) override {
149 stream_done_ = true;
150 if (waiting_for_stream_)
151 base::MessageLoop::current()->Quit();
152 stream_.reset(stream);
153 used_ssl_config_ = used_ssl_config;
154 used_proxy_info_ = used_proxy_info;
157 void OnWebSocketHandshakeStreamReady(
158 const SSLConfig& used_ssl_config,
159 const ProxyInfo& used_proxy_info,
160 WebSocketHandshakeStreamBase* stream) override {
161 stream_done_ = true;
162 if (waiting_for_stream_)
163 base::MessageLoop::current()->Quit();
164 websocket_stream_.reset(stream);
165 used_ssl_config_ = used_ssl_config;
166 used_proxy_info_ = used_proxy_info;
169 void OnStreamFailed(int status,
170 const SSLConfig& used_ssl_config,
171 SSLFailureState ssl_failure_state) override {}
173 void OnCertificateError(int status,
174 const SSLConfig& used_ssl_config,
175 const SSLInfo& ssl_info) override {}
177 void OnNeedsProxyAuth(const HttpResponseInfo& proxy_response,
178 const SSLConfig& used_ssl_config,
179 const ProxyInfo& used_proxy_info,
180 HttpAuthController* auth_controller) override {}
182 void OnNeedsClientAuth(const SSLConfig& used_ssl_config,
183 SSLCertRequestInfo* cert_info) override {}
185 void OnHttpsProxyTunnelResponse(const HttpResponseInfo& response_info,
186 const SSLConfig& used_ssl_config,
187 const ProxyInfo& used_proxy_info,
188 HttpStream* stream) override {}
190 void WaitForStream() {
191 while (!stream_done_) {
192 waiting_for_stream_ = true;
193 base::MessageLoop::current()->Run();
194 waiting_for_stream_ = false;
198 const SSLConfig& used_ssl_config() const {
199 return used_ssl_config_;
202 const ProxyInfo& used_proxy_info() const {
203 return used_proxy_info_;
206 HttpStream* stream() {
207 return stream_.get();
210 MockWebSocketHandshakeStream* websocket_stream() {
211 return static_cast<MockWebSocketHandshakeStream*>(websocket_stream_.get());
214 bool stream_done() const { return stream_done_; }
216 private:
217 bool waiting_for_stream_;
218 bool stream_done_;
219 scoped_ptr<HttpStream> stream_;
220 scoped_ptr<WebSocketHandshakeStreamBase> websocket_stream_;
221 SSLConfig used_ssl_config_;
222 ProxyInfo used_proxy_info_;
224 DISALLOW_COPY_AND_ASSIGN(StreamRequestWaiter);
227 class WebSocketSpdyHandshakeStream : public MockWebSocketHandshakeStream {
228 public:
229 explicit WebSocketSpdyHandshakeStream(
230 const base::WeakPtr<SpdySession>& spdy_session)
231 : MockWebSocketHandshakeStream(kStreamTypeSpdy),
232 spdy_session_(spdy_session) {}
234 ~WebSocketSpdyHandshakeStream() override {}
236 SpdySession* spdy_session() { return spdy_session_.get(); }
238 private:
239 base::WeakPtr<SpdySession> spdy_session_;
242 class WebSocketBasicHandshakeStream : public MockWebSocketHandshakeStream {
243 public:
244 explicit WebSocketBasicHandshakeStream(
245 scoped_ptr<ClientSocketHandle> connection)
246 : MockWebSocketHandshakeStream(kStreamTypeBasic),
247 connection_(connection.Pass()) {}
249 ~WebSocketBasicHandshakeStream() override {
250 connection_->socket()->Disconnect();
253 ClientSocketHandle* connection() { return connection_.get(); }
255 private:
256 scoped_ptr<ClientSocketHandle> connection_;
259 class WebSocketStreamCreateHelper
260 : public WebSocketHandshakeStreamBase::CreateHelper {
261 public:
262 ~WebSocketStreamCreateHelper() override {}
264 WebSocketHandshakeStreamBase* CreateBasicStream(
265 scoped_ptr<ClientSocketHandle> connection,
266 bool using_proxy) override {
267 return new WebSocketBasicHandshakeStream(connection.Pass());
270 WebSocketHandshakeStreamBase* CreateSpdyStream(
271 const base::WeakPtr<SpdySession>& spdy_session,
272 bool use_relative_url) override {
273 return new WebSocketSpdyHandshakeStream(spdy_session);
277 struct TestCase {
278 int num_streams;
279 bool ssl;
282 TestCase kTests[] = {
283 { 1, false },
284 { 2, false },
285 { 1, true},
286 { 2, true},
289 void PreconnectHelperForURL(int num_streams,
290 const GURL& url,
291 HttpNetworkSession* session) {
292 HttpNetworkSessionPeer peer(session);
293 MockHttpStreamFactoryImplForPreconnect* mock_factory =
294 new MockHttpStreamFactoryImplForPreconnect(session, false);
295 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(mock_factory));
296 SSLConfig ssl_config;
297 session->ssl_config_service()->GetSSLConfig(&ssl_config);
299 HttpRequestInfo request;
300 request.method = "GET";
301 request.url = url;
302 request.load_flags = 0;
304 session->http_stream_factory()->PreconnectStreams(num_streams, request,
305 ssl_config, ssl_config);
306 mock_factory->WaitForPreconnects();
309 void PreconnectHelper(const TestCase& test,
310 HttpNetworkSession* session) {
311 GURL url = test.ssl ? GURL("https://www.google.com") :
312 GURL("http://www.google.com");
313 PreconnectHelperForURL(test.num_streams, url, session);
316 template<typename ParentPool>
317 class CapturePreconnectsSocketPool : public ParentPool {
318 public:
319 CapturePreconnectsSocketPool(HostResolver* host_resolver,
320 CertVerifier* cert_verifier);
322 int last_num_streams() const {
323 return last_num_streams_;
326 int RequestSocket(const std::string& group_name,
327 const void* socket_params,
328 RequestPriority priority,
329 ClientSocketHandle* handle,
330 const CompletionCallback& callback,
331 const BoundNetLog& net_log) override {
332 ADD_FAILURE();
333 return ERR_UNEXPECTED;
336 void RequestSockets(const std::string& group_name,
337 const void* socket_params,
338 int num_sockets,
339 const BoundNetLog& net_log) override {
340 last_num_streams_ = num_sockets;
343 void CancelRequest(const std::string& group_name,
344 ClientSocketHandle* handle) override {
345 ADD_FAILURE();
347 void ReleaseSocket(const std::string& group_name,
348 scoped_ptr<StreamSocket> socket,
349 int id) override {
350 ADD_FAILURE();
352 void CloseIdleSockets() override { ADD_FAILURE(); }
353 int IdleSocketCount() const override {
354 ADD_FAILURE();
355 return 0;
357 int IdleSocketCountInGroup(const std::string& group_name) const override {
358 ADD_FAILURE();
359 return 0;
361 LoadState GetLoadState(const std::string& group_name,
362 const ClientSocketHandle* handle) const override {
363 ADD_FAILURE();
364 return LOAD_STATE_IDLE;
366 base::TimeDelta ConnectionTimeout() const override {
367 return base::TimeDelta();
370 private:
371 int last_num_streams_;
374 typedef CapturePreconnectsSocketPool<TransportClientSocketPool>
375 CapturePreconnectsTransportSocketPool;
376 typedef CapturePreconnectsSocketPool<HttpProxyClientSocketPool>
377 CapturePreconnectsHttpProxySocketPool;
378 typedef CapturePreconnectsSocketPool<SOCKSClientSocketPool>
379 CapturePreconnectsSOCKSSocketPool;
380 typedef CapturePreconnectsSocketPool<SSLClientSocketPool>
381 CapturePreconnectsSSLSocketPool;
383 template <typename ParentPool>
384 CapturePreconnectsSocketPool<ParentPool>::CapturePreconnectsSocketPool(
385 HostResolver* host_resolver,
386 CertVerifier* /* cert_verifier */)
387 : ParentPool(0, 0, host_resolver, nullptr, nullptr), last_num_streams_(-1) {
390 template <>
391 CapturePreconnectsHttpProxySocketPool::CapturePreconnectsSocketPool(
392 HostResolver* /* host_resolver */,
393 CertVerifier* /* cert_verifier */)
394 : HttpProxyClientSocketPool(0, 0, 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 cert_verifier,
405 nullptr, // channel_id_store
406 nullptr, // transport_security_state
407 nullptr, // cert_transparency_verifier
408 nullptr, // cert_policy_enforcer
409 std::string(), // ssl_session_cache_shard
410 nullptr, // deterministic_socket_factory
411 nullptr, // transport_socket_pool
412 nullptr,
413 nullptr,
414 nullptr, // ssl_config_service
415 nullptr), // net_log
416 last_num_streams_(-1) {
419 class HttpStreamFactoryTest : public ::testing::Test,
420 public ::testing::WithParamInterface<NextProto> {
423 INSTANTIATE_TEST_CASE_P(NextProto,
424 HttpStreamFactoryTest,
425 testing::Values(kProtoSPDY31,
426 kProtoHTTP2));
428 TEST_P(HttpStreamFactoryTest, PreconnectDirect) {
429 for (size_t i = 0; i < arraysize(kTests); ++i) {
430 SpdySessionDependencies session_deps(
431 GetParam(), ProxyService::CreateDirect());
432 scoped_refptr<HttpNetworkSession> session(
433 SpdySessionDependencies::SpdyCreateSession(&session_deps));
434 HttpNetworkSessionPeer peer(session);
435 CapturePreconnectsTransportSocketPool* transport_conn_pool =
436 new CapturePreconnectsTransportSocketPool(
437 session_deps.host_resolver.get(),
438 session_deps.cert_verifier.get());
439 CapturePreconnectsSSLSocketPool* ssl_conn_pool =
440 new CapturePreconnectsSSLSocketPool(
441 session_deps.host_resolver.get(),
442 session_deps.cert_verifier.get());
443 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
444 new MockClientSocketPoolManager);
445 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
446 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
447 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
448 PreconnectHelper(kTests[i], session.get());
449 if (kTests[i].ssl)
450 EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams());
451 else
452 EXPECT_EQ(kTests[i].num_streams, transport_conn_pool->last_num_streams());
456 TEST_P(HttpStreamFactoryTest, PreconnectHttpProxy) {
457 for (size_t i = 0; i < arraysize(kTests); ++i) {
458 SpdySessionDependencies session_deps(
459 GetParam(), ProxyService::CreateFixed("http_proxy"));
460 scoped_refptr<HttpNetworkSession> session(
461 SpdySessionDependencies::SpdyCreateSession(&session_deps));
462 HttpNetworkSessionPeer peer(session);
463 HostPortPair proxy_host("http_proxy", 80);
464 CapturePreconnectsHttpProxySocketPool* http_proxy_pool =
465 new CapturePreconnectsHttpProxySocketPool(
466 session_deps.host_resolver.get(),
467 session_deps.cert_verifier.get());
468 CapturePreconnectsSSLSocketPool* ssl_conn_pool =
469 new CapturePreconnectsSSLSocketPool(
470 session_deps.host_resolver.get(),
471 session_deps.cert_verifier.get());
472 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
473 new MockClientSocketPoolManager);
474 mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
475 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
476 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
477 PreconnectHelper(kTests[i], session.get());
478 if (kTests[i].ssl)
479 EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams());
480 else
481 EXPECT_EQ(kTests[i].num_streams, http_proxy_pool->last_num_streams());
485 TEST_P(HttpStreamFactoryTest, PreconnectSocksProxy) {
486 for (size_t i = 0; i < arraysize(kTests); ++i) {
487 SpdySessionDependencies session_deps(
488 GetParam(), ProxyService::CreateFixed("socks4://socks_proxy:1080"));
489 scoped_refptr<HttpNetworkSession> session(
490 SpdySessionDependencies::SpdyCreateSession(&session_deps));
491 HttpNetworkSessionPeer peer(session);
492 HostPortPair proxy_host("socks_proxy", 1080);
493 CapturePreconnectsSOCKSSocketPool* socks_proxy_pool =
494 new CapturePreconnectsSOCKSSocketPool(
495 session_deps.host_resolver.get(),
496 session_deps.cert_verifier.get());
497 CapturePreconnectsSSLSocketPool* ssl_conn_pool =
498 new CapturePreconnectsSSLSocketPool(
499 session_deps.host_resolver.get(),
500 session_deps.cert_verifier.get());
501 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
502 new MockClientSocketPoolManager);
503 mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_proxy_pool);
504 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
505 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
506 PreconnectHelper(kTests[i], session.get());
507 if (kTests[i].ssl)
508 EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams());
509 else
510 EXPECT_EQ(kTests[i].num_streams, socks_proxy_pool->last_num_streams());
514 TEST_P(HttpStreamFactoryTest, PreconnectDirectWithExistingSpdySession) {
515 for (size_t i = 0; i < arraysize(kTests); ++i) {
516 SpdySessionDependencies session_deps(
517 GetParam(), ProxyService::CreateDirect());
518 scoped_refptr<HttpNetworkSession> session(
519 SpdySessionDependencies::SpdyCreateSession(&session_deps));
520 HttpNetworkSessionPeer peer(session);
522 // Put a SpdySession in the pool.
523 HostPortPair host_port_pair("www.google.com", 443);
524 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
525 PRIVACY_MODE_DISABLED);
526 ignore_result(CreateFakeSpdySession(session->spdy_session_pool(), key));
528 CapturePreconnectsTransportSocketPool* transport_conn_pool =
529 new CapturePreconnectsTransportSocketPool(
530 session_deps.host_resolver.get(),
531 session_deps.cert_verifier.get());
532 CapturePreconnectsSSLSocketPool* ssl_conn_pool =
533 new CapturePreconnectsSSLSocketPool(
534 session_deps.host_resolver.get(),
535 session_deps.cert_verifier.get());
536 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
537 new MockClientSocketPoolManager);
538 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
539 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
540 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
541 PreconnectHelper(kTests[i], session.get());
542 // We shouldn't be preconnecting if we have an existing session, which is
543 // the case for https://www.google.com.
544 if (kTests[i].ssl)
545 EXPECT_EQ(-1, ssl_conn_pool->last_num_streams());
546 else
547 EXPECT_EQ(kTests[i].num_streams,
548 transport_conn_pool->last_num_streams());
552 // Verify that preconnects to unsafe ports are cancelled before they reach
553 // the SocketPool.
554 TEST_P(HttpStreamFactoryTest, PreconnectUnsafePort) {
555 ASSERT_FALSE(IsPortAllowedForScheme(7, "http"));
557 SpdySessionDependencies session_deps(
558 GetParam(), ProxyService::CreateDirect());
559 scoped_refptr<HttpNetworkSession> session(
560 SpdySessionDependencies::SpdyCreateSession(&session_deps));
561 HttpNetworkSessionPeer peer(session);
562 CapturePreconnectsTransportSocketPool* transport_conn_pool =
563 new CapturePreconnectsTransportSocketPool(
564 session_deps.host_resolver.get(),
565 session_deps.cert_verifier.get());
566 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
567 new MockClientSocketPoolManager);
568 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
569 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
571 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 EXPECT_EQ(1u, retry_info.size()) << i;
671 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
673 ProxyRetryInfoMap::const_iterator iter = retry_info.find("quic://bad:99");
674 EXPECT_TRUE(iter != retry_info.end()) << i;
678 } // namespace
680 TEST_P(HttpStreamFactoryTest, QuicLossyProxyMarkedAsBad) {
681 // Checks if a
682 scoped_ptr<ProxyService> proxy_service;
683 proxy_service.reset(
684 ProxyService::CreateFixedFromPacResult("QUIC bad:99; DIRECT"));
686 HttpNetworkSession::Params params;
687 params.enable_quic = true;
688 params.enable_quic_for_proxies = true;
689 scoped_refptr<SSLConfigServiceDefaults> ssl_config_service(
690 new SSLConfigServiceDefaults);
691 HttpServerPropertiesImpl http_server_properties;
692 MockClientSocketFactory socket_factory;
693 params.client_socket_factory = &socket_factory;
694 MockHostResolver host_resolver;
695 params.host_resolver = &host_resolver;
696 TransportSecurityState transport_security_state;
697 params.transport_security_state = &transport_security_state;
698 params.proxy_service = proxy_service.get();
699 params.ssl_config_service = ssl_config_service.get();
700 params.http_server_properties = http_server_properties.GetWeakPtr();
701 params.quic_max_number_of_lossy_connections = 2;
703 scoped_refptr<HttpNetworkSession> session;
704 session = new HttpNetworkSession(params);
705 session->quic_stream_factory()->set_require_confirmation(false);
707 session->quic_stream_factory()->number_of_lossy_connections_[99] =
708 params.quic_max_number_of_lossy_connections;
710 StaticSocketDataProvider socket_data2;
711 socket_data2.set_connect_data(MockConnect(ASYNC, OK));
712 socket_factory.AddSocketDataProvider(&socket_data2);
714 // Now request a stream. It should succeed using the second proxy in the
715 // list.
716 HttpRequestInfo request_info;
717 request_info.method = "GET";
718 request_info.url = GURL("http://www.google.com");
720 SSLConfig ssl_config;
721 StreamRequestWaiter waiter;
722 scoped_ptr<HttpStreamRequest> request(
723 session->http_stream_factory()->RequestStream(
724 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter,
725 BoundNetLog()));
726 waiter.WaitForStream();
728 // The proxy that failed should now be known to the proxy_service as bad.
729 const ProxyRetryInfoMap& retry_info =
730 session->proxy_service()->proxy_retry_info();
731 EXPECT_EQ(1u, retry_info.size());
732 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
734 ProxyRetryInfoMap::const_iterator iter = retry_info.find("quic://bad:99");
735 EXPECT_TRUE(iter != retry_info.end());
738 namespace {
740 TEST_P(HttpStreamFactoryTest, PrivacyModeDisablesChannelId) {
741 SpdySessionDependencies session_deps(
742 GetParam(), ProxyService::CreateDirect());
744 StaticSocketDataProvider socket_data;
745 socket_data.set_connect_data(MockConnect(ASYNC, OK));
746 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
748 SSLSocketDataProvider ssl(ASYNC, OK);
749 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
751 scoped_refptr<HttpNetworkSession> session(
752 SpdySessionDependencies::SpdyCreateSession(&session_deps));
754 // Set an existing SpdySession in the pool.
755 HostPortPair host_port_pair("www.google.com", 443);
756 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
757 PRIVACY_MODE_ENABLED);
759 HttpRequestInfo request_info;
760 request_info.method = "GET";
761 request_info.url = GURL("https://www.google.com");
762 request_info.load_flags = 0;
763 request_info.privacy_mode = PRIVACY_MODE_DISABLED;
765 SSLConfig ssl_config;
766 StreamRequestWaiter waiter;
767 scoped_ptr<HttpStreamRequest> request(
768 session->http_stream_factory()->RequestStream(
769 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config,
770 &waiter, BoundNetLog()));
771 waiter.WaitForStream();
773 // The stream shouldn't come from spdy as we are using different privacy mode
774 EXPECT_FALSE(request->using_spdy());
776 SSLConfig used_ssl_config = waiter.used_ssl_config();
777 EXPECT_EQ(used_ssl_config.channel_id_enabled, ssl_config.channel_id_enabled);
780 namespace {
781 // Return count of distinct groups in given socket pool.
782 int GetSocketPoolGroupCount(ClientSocketPool* pool) {
783 int count = 0;
784 scoped_ptr<base::DictionaryValue> dict(pool->GetInfoAsValue("", "", false));
785 EXPECT_TRUE(dict != nullptr);
786 base::DictionaryValue* groups = nullptr;
787 if (dict->GetDictionary("groups", &groups) && (groups != nullptr)) {
788 count = static_cast<int>(groups->size());
790 return count;
792 } // namespace
794 TEST_P(HttpStreamFactoryTest, PrivacyModeUsesDifferentSocketPoolGroup) {
795 SpdySessionDependencies session_deps(
796 GetParam(), ProxyService::CreateDirect());
798 StaticSocketDataProvider socket_data;
799 socket_data.set_connect_data(MockConnect(ASYNC, OK));
800 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
802 SSLSocketDataProvider ssl(ASYNC, OK);
803 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
805 scoped_refptr<HttpNetworkSession> session(
806 SpdySessionDependencies::SpdyCreateSession(&session_deps));
807 SSLClientSocketPool* ssl_pool = session->GetSSLSocketPool(
808 HttpNetworkSession::NORMAL_SOCKET_POOL);
810 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 0);
812 HttpRequestInfo request_info;
813 request_info.method = "GET";
814 request_info.url = GURL("https://www.google.com");
815 request_info.load_flags = 0;
816 request_info.privacy_mode = PRIVACY_MODE_DISABLED;
818 SSLConfig ssl_config;
819 StreamRequestWaiter waiter;
821 scoped_ptr<HttpStreamRequest> request1(
822 session->http_stream_factory()->RequestStream(
823 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config,
824 &waiter, BoundNetLog()));
825 waiter.WaitForStream();
827 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 1);
829 scoped_ptr<HttpStreamRequest> request2(
830 session->http_stream_factory()->RequestStream(
831 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config,
832 &waiter, BoundNetLog()));
833 waiter.WaitForStream();
835 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 1);
837 request_info.privacy_mode = PRIVACY_MODE_ENABLED;
838 scoped_ptr<HttpStreamRequest> request3(
839 session->http_stream_factory()->RequestStream(
840 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config,
841 &waiter, BoundNetLog()));
842 waiter.WaitForStream();
844 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 2);
847 TEST_P(HttpStreamFactoryTest, GetLoadState) {
848 SpdySessionDependencies session_deps(
849 GetParam(), ProxyService::CreateDirect());
851 StaticSocketDataProvider socket_data;
852 socket_data.set_connect_data(MockConnect(ASYNC, OK));
853 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
855 scoped_refptr<HttpNetworkSession> session(
856 SpdySessionDependencies::SpdyCreateSession(&session_deps));
858 HttpRequestInfo request_info;
859 request_info.method = "GET";
860 request_info.url = GURL("http://www.google.com");
862 SSLConfig ssl_config;
863 StreamRequestWaiter waiter;
864 scoped_ptr<HttpStreamRequest> request(
865 session->http_stream_factory()->RequestStream(
866 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config,
867 &waiter, BoundNetLog()));
869 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, request->GetLoadState());
871 waiter.WaitForStream();
874 TEST_P(HttpStreamFactoryTest, RequestHttpStream) {
875 SpdySessionDependencies session_deps(
876 GetParam(), ProxyService::CreateDirect());
878 StaticSocketDataProvider socket_data;
879 socket_data.set_connect_data(MockConnect(ASYNC, OK));
880 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
882 scoped_refptr<HttpNetworkSession> session(
883 SpdySessionDependencies::SpdyCreateSession(&session_deps));
885 // Now request a stream. It should succeed using the second proxy in the
886 // list.
887 HttpRequestInfo request_info;
888 request_info.method = "GET";
889 request_info.url = GURL("http://www.google.com");
890 request_info.load_flags = 0;
892 SSLConfig ssl_config;
893 StreamRequestWaiter waiter;
894 scoped_ptr<HttpStreamRequest> request(
895 session->http_stream_factory()->RequestStream(
896 request_info,
897 DEFAULT_PRIORITY,
898 ssl_config,
899 ssl_config,
900 &waiter,
901 BoundNetLog()));
902 waiter.WaitForStream();
903 EXPECT_TRUE(waiter.stream_done());
904 ASSERT_TRUE(nullptr != waiter.stream());
905 EXPECT_TRUE(nullptr == waiter.websocket_stream());
906 EXPECT_FALSE(waiter.stream()->IsSpdyHttpStream());
908 EXPECT_EQ(1, GetSocketPoolGroupCount(
909 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
910 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool(
911 HttpNetworkSession::NORMAL_SOCKET_POOL)));
912 EXPECT_EQ(0, GetSocketPoolGroupCount(
913 session->GetTransportSocketPool(
914 HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
915 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool(
916 HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
917 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
920 TEST_P(HttpStreamFactoryTest, RequestHttpStreamOverSSL) {
921 SpdySessionDependencies session_deps(
922 GetParam(), ProxyService::CreateDirect());
924 MockRead mock_read(ASYNC, OK);
925 StaticSocketDataProvider socket_data(&mock_read, 1, nullptr, 0);
926 socket_data.set_connect_data(MockConnect(ASYNC, OK));
927 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
929 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
930 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
932 scoped_refptr<HttpNetworkSession> session(
933 SpdySessionDependencies::SpdyCreateSession(&session_deps));
935 // Now request a stream.
936 HttpRequestInfo request_info;
937 request_info.method = "GET";
938 request_info.url = GURL("https://www.google.com");
939 request_info.load_flags = 0;
941 SSLConfig ssl_config;
942 StreamRequestWaiter waiter;
943 scoped_ptr<HttpStreamRequest> request(
944 session->http_stream_factory()->RequestStream(
945 request_info,
946 DEFAULT_PRIORITY,
947 ssl_config,
948 ssl_config,
949 &waiter,
950 BoundNetLog()));
951 waiter.WaitForStream();
952 EXPECT_TRUE(waiter.stream_done());
953 ASSERT_TRUE(nullptr != waiter.stream());
954 EXPECT_TRUE(nullptr == waiter.websocket_stream());
955 EXPECT_FALSE(waiter.stream()->IsSpdyHttpStream());
956 EXPECT_EQ(1, GetSocketPoolGroupCount(
957 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
958 EXPECT_EQ(1, GetSocketPoolGroupCount(
959 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
960 EXPECT_EQ(0, GetSocketPoolGroupCount(
961 session->GetTransportSocketPool(
962 HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
963 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool(
964 HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
965 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
968 TEST_P(HttpStreamFactoryTest, RequestHttpStreamOverProxy) {
969 SpdySessionDependencies session_deps(
970 GetParam(), ProxyService::CreateFixed("myproxy:8888"));
972 StaticSocketDataProvider socket_data;
973 socket_data.set_connect_data(MockConnect(ASYNC, OK));
974 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
976 scoped_refptr<HttpNetworkSession> session(
977 SpdySessionDependencies::SpdyCreateSession(&session_deps));
979 // Now request a stream. It should succeed using the second proxy in the
980 // list.
981 HttpRequestInfo request_info;
982 request_info.method = "GET";
983 request_info.url = GURL("http://www.google.com");
984 request_info.load_flags = 0;
986 SSLConfig ssl_config;
987 StreamRequestWaiter waiter;
988 scoped_ptr<HttpStreamRequest> request(
989 session->http_stream_factory()->RequestStream(
990 request_info,
991 DEFAULT_PRIORITY,
992 ssl_config,
993 ssl_config,
994 &waiter,
995 BoundNetLog()));
996 waiter.WaitForStream();
997 EXPECT_TRUE(waiter.stream_done());
998 ASSERT_TRUE(nullptr != waiter.stream());
999 EXPECT_TRUE(nullptr == waiter.websocket_stream());
1000 EXPECT_FALSE(waiter.stream()->IsSpdyHttpStream());
1001 EXPECT_EQ(0, GetSocketPoolGroupCount(
1002 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1003 EXPECT_EQ(0, GetSocketPoolGroupCount(
1004 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1005 EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSocketPoolForHTTPProxy(
1006 HttpNetworkSession::NORMAL_SOCKET_POOL,
1007 HostPortPair("myproxy", 8888))));
1008 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForSSLWithProxy(
1009 HttpNetworkSession::NORMAL_SOCKET_POOL,
1010 HostPortPair("myproxy", 8888))));
1011 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForHTTPProxy(
1012 HttpNetworkSession::WEBSOCKET_SOCKET_POOL,
1013 HostPortPair("myproxy", 8888))));
1014 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForSSLWithProxy(
1015 HttpNetworkSession::WEBSOCKET_SOCKET_POOL,
1016 HostPortPair("myproxy", 8888))));
1017 EXPECT_FALSE(waiter.used_proxy_info().is_direct());
1020 TEST_P(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStream) {
1021 SpdySessionDependencies session_deps(
1022 GetParam(), ProxyService::CreateDirect());
1024 StaticSocketDataProvider socket_data;
1025 socket_data.set_connect_data(MockConnect(ASYNC, OK));
1026 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
1028 scoped_refptr<HttpNetworkSession> session(
1029 SpdySessionDependencies::SpdyCreateSession(&session_deps));
1031 // Now request a stream.
1032 HttpRequestInfo request_info;
1033 request_info.method = "GET";
1034 request_info.url = GURL("ws://www.google.com");
1035 request_info.load_flags = 0;
1037 SSLConfig ssl_config;
1038 StreamRequestWaiter waiter;
1039 WebSocketStreamCreateHelper create_helper;
1040 scoped_ptr<HttpStreamRequest> request(
1041 session->http_stream_factory_for_websocket()
1042 ->RequestWebSocketHandshakeStream(request_info,
1043 DEFAULT_PRIORITY,
1044 ssl_config,
1045 ssl_config,
1046 &waiter,
1047 &create_helper,
1048 BoundNetLog()));
1049 waiter.WaitForStream();
1050 EXPECT_TRUE(waiter.stream_done());
1051 EXPECT_TRUE(nullptr == waiter.stream());
1052 ASSERT_TRUE(nullptr != waiter.websocket_stream());
1053 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic,
1054 waiter.websocket_stream()->type());
1055 EXPECT_EQ(0, GetSocketPoolGroupCount(
1056 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1057 EXPECT_EQ(0, GetSocketPoolGroupCount(
1058 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1059 EXPECT_EQ(0, GetSocketPoolGroupCount(
1060 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1061 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
1064 TEST_P(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStreamOverSSL) {
1065 SpdySessionDependencies session_deps(
1066 GetParam(), ProxyService::CreateDirect());
1068 MockRead mock_read(ASYNC, OK);
1069 StaticSocketDataProvider socket_data(&mock_read, 1, nullptr, 0);
1070 socket_data.set_connect_data(MockConnect(ASYNC, OK));
1071 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
1073 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
1074 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
1076 scoped_refptr<HttpNetworkSession> session(
1077 SpdySessionDependencies::SpdyCreateSession(&session_deps));
1079 // Now request a stream.
1080 HttpRequestInfo request_info;
1081 request_info.method = "GET";
1082 request_info.url = GURL("wss://www.google.com");
1083 request_info.load_flags = 0;
1085 SSLConfig ssl_config;
1086 StreamRequestWaiter waiter;
1087 WebSocketStreamCreateHelper create_helper;
1088 scoped_ptr<HttpStreamRequest> request(
1089 session->http_stream_factory_for_websocket()
1090 ->RequestWebSocketHandshakeStream(request_info,
1091 DEFAULT_PRIORITY,
1092 ssl_config,
1093 ssl_config,
1094 &waiter,
1095 &create_helper,
1096 BoundNetLog()));
1097 waiter.WaitForStream();
1098 EXPECT_TRUE(waiter.stream_done());
1099 EXPECT_TRUE(nullptr == waiter.stream());
1100 ASSERT_TRUE(nullptr != waiter.websocket_stream());
1101 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic,
1102 waiter.websocket_stream()->type());
1103 EXPECT_EQ(0, GetSocketPoolGroupCount(
1104 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1105 EXPECT_EQ(0, GetSocketPoolGroupCount(
1106 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1107 EXPECT_EQ(1, GetSocketPoolGroupCount(
1108 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1109 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
1112 TEST_P(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStreamOverProxy) {
1113 SpdySessionDependencies session_deps(
1114 GetParam(), ProxyService::CreateFixed("myproxy:8888"));
1116 MockRead read(SYNCHRONOUS, "HTTP/1.0 200 Connection established\r\n\r\n");
1117 StaticSocketDataProvider socket_data(&read, 1, 0, 0);
1118 socket_data.set_connect_data(MockConnect(ASYNC, OK));
1119 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
1121 scoped_refptr<HttpNetworkSession> session(
1122 SpdySessionDependencies::SpdyCreateSession(&session_deps));
1124 // Now request a stream.
1125 HttpRequestInfo request_info;
1126 request_info.method = "GET";
1127 request_info.url = GURL("ws://www.google.com");
1128 request_info.load_flags = 0;
1130 SSLConfig ssl_config;
1131 StreamRequestWaiter waiter;
1132 WebSocketStreamCreateHelper create_helper;
1133 scoped_ptr<HttpStreamRequest> request(
1134 session->http_stream_factory_for_websocket()
1135 ->RequestWebSocketHandshakeStream(request_info,
1136 DEFAULT_PRIORITY,
1137 ssl_config,
1138 ssl_config,
1139 &waiter,
1140 &create_helper,
1141 BoundNetLog()));
1142 waiter.WaitForStream();
1143 EXPECT_TRUE(waiter.stream_done());
1144 EXPECT_TRUE(nullptr == waiter.stream());
1145 ASSERT_TRUE(nullptr != waiter.websocket_stream());
1146 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic,
1147 waiter.websocket_stream()->type());
1148 EXPECT_EQ(0, GetSocketPoolGroupCount(
1149 session->GetTransportSocketPool(
1150 HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1151 EXPECT_EQ(0, GetSocketPoolGroupCount(
1152 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1153 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForHTTPProxy(
1154 HttpNetworkSession::NORMAL_SOCKET_POOL,
1155 HostPortPair("myproxy", 8888))));
1156 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForSSLWithProxy(
1157 HttpNetworkSession::NORMAL_SOCKET_POOL,
1158 HostPortPair("myproxy", 8888))));
1159 EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSocketPoolForHTTPProxy(
1160 HttpNetworkSession::WEBSOCKET_SOCKET_POOL,
1161 HostPortPair("myproxy", 8888))));
1162 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForSSLWithProxy(
1163 HttpNetworkSession::WEBSOCKET_SOCKET_POOL,
1164 HostPortPair("myproxy", 8888))));
1165 EXPECT_FALSE(waiter.used_proxy_info().is_direct());
1168 TEST_P(HttpStreamFactoryTest, RequestSpdyHttpStream) {
1169 SpdySessionDependencies session_deps(GetParam(),
1170 ProxyService::CreateDirect());
1172 MockRead mock_read(ASYNC, OK);
1173 SequencedSocketData socket_data(&mock_read, 1, nullptr, 0);
1174 socket_data.set_connect_data(MockConnect(ASYNC, OK));
1175 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
1177 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
1178 ssl_socket_data.SetNextProto(GetParam());
1179 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
1181 HostPortPair host_port_pair("www.google.com", 443);
1182 scoped_refptr<HttpNetworkSession> session(
1183 SpdySessionDependencies::SpdyCreateSession(&session_deps));
1185 // Now request a stream.
1186 HttpRequestInfo request_info;
1187 request_info.method = "GET";
1188 request_info.url = GURL("https://www.google.com");
1189 request_info.load_flags = 0;
1191 SSLConfig ssl_config;
1192 StreamRequestWaiter waiter;
1193 scoped_ptr<HttpStreamRequest> request(
1194 session->http_stream_factory()->RequestStream(
1195 request_info,
1196 DEFAULT_PRIORITY,
1197 ssl_config,
1198 ssl_config,
1199 &waiter,
1200 BoundNetLog()));
1201 waiter.WaitForStream();
1202 EXPECT_TRUE(waiter.stream_done());
1203 EXPECT_TRUE(nullptr == waiter.websocket_stream());
1204 ASSERT_TRUE(nullptr != waiter.stream());
1205 EXPECT_TRUE(waiter.stream()->IsSpdyHttpStream());
1206 EXPECT_EQ(1, GetSocketPoolGroupCount(
1207 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1208 EXPECT_EQ(1, GetSocketPoolGroupCount(
1209 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1210 EXPECT_EQ(0, GetSocketPoolGroupCount(
1211 session->GetTransportSocketPool(
1212 HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1213 EXPECT_EQ(0, GetSocketPoolGroupCount(
1214 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1215 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
1218 // TODO(ricea): This test can be removed once the new WebSocket stack supports
1219 // SPDY. Currently, even if we connect to a SPDY-supporting server, we need to
1220 // use plain SSL.
1221 TEST_P(HttpStreamFactoryTest, RequestWebSocketSpdyHandshakeStreamButGetSSL) {
1222 SpdySessionDependencies session_deps(GetParam(),
1223 ProxyService::CreateDirect());
1225 MockRead mock_read(SYNCHRONOUS, ERR_IO_PENDING);
1226 StaticSocketDataProvider socket_data(&mock_read, 1, nullptr, 0);
1227 socket_data.set_connect_data(MockConnect(ASYNC, OK));
1228 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
1230 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
1231 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
1233 HostPortPair host_port_pair("www.google.com", 80);
1234 scoped_refptr<HttpNetworkSession>
1235 session(SpdySessionDependencies::SpdyCreateSession(&session_deps));
1237 // Now request a stream.
1238 HttpRequestInfo request_info;
1239 request_info.method = "GET";
1240 request_info.url = GURL("wss://www.google.com");
1241 request_info.load_flags = 0;
1243 SSLConfig ssl_config;
1244 StreamRequestWaiter waiter1;
1245 WebSocketStreamCreateHelper create_helper;
1246 scoped_ptr<HttpStreamRequest> request1(
1247 session->http_stream_factory_for_websocket()
1248 ->RequestWebSocketHandshakeStream(request_info,
1249 DEFAULT_PRIORITY,
1250 ssl_config,
1251 ssl_config,
1252 &waiter1,
1253 &create_helper,
1254 BoundNetLog()));
1255 waiter1.WaitForStream();
1256 EXPECT_TRUE(waiter1.stream_done());
1257 ASSERT_TRUE(nullptr != waiter1.websocket_stream());
1258 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic,
1259 waiter1.websocket_stream()->type());
1260 EXPECT_TRUE(nullptr == waiter1.stream());
1262 EXPECT_EQ(0, GetSocketPoolGroupCount(
1263 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1264 EXPECT_EQ(0, GetSocketPoolGroupCount(
1265 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1266 EXPECT_EQ(1, GetSocketPoolGroupCount(
1267 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1268 EXPECT_TRUE(waiter1.used_proxy_info().is_direct());
1271 // TODO(ricea): Re-enable once WebSocket-over-SPDY is implemented.
1272 TEST_P(HttpStreamFactoryTest, DISABLED_RequestWebSocketSpdyHandshakeStream) {
1273 SpdySessionDependencies session_deps(GetParam(),
1274 ProxyService::CreateDirect());
1276 MockRead mock_read(SYNCHRONOUS, ERR_IO_PENDING);
1277 StaticSocketDataProvider socket_data(&mock_read, 1, nullptr, 0);
1278 socket_data.set_connect_data(MockConnect(ASYNC, OK));
1279 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
1281 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
1282 ssl_socket_data.SetNextProto(GetParam());
1283 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
1285 HostPortPair host_port_pair("www.google.com", 80);
1286 scoped_refptr<HttpNetworkSession>
1287 session(SpdySessionDependencies::SpdyCreateSession(&session_deps));
1289 // Now request a stream.
1290 HttpRequestInfo request_info;
1291 request_info.method = "GET";
1292 request_info.url = GURL("wss://www.google.com");
1293 request_info.load_flags = 0;
1295 SSLConfig ssl_config;
1296 StreamRequestWaiter waiter1;
1297 WebSocketStreamCreateHelper create_helper;
1298 scoped_ptr<HttpStreamRequest> request1(
1299 session->http_stream_factory_for_websocket()
1300 ->RequestWebSocketHandshakeStream(request_info,
1301 DEFAULT_PRIORITY,
1302 ssl_config,
1303 ssl_config,
1304 &waiter1,
1305 &create_helper,
1306 BoundNetLog()));
1307 waiter1.WaitForStream();
1308 EXPECT_TRUE(waiter1.stream_done());
1309 ASSERT_TRUE(nullptr != waiter1.websocket_stream());
1310 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy,
1311 waiter1.websocket_stream()->type());
1312 EXPECT_TRUE(nullptr == waiter1.stream());
1314 StreamRequestWaiter waiter2;
1315 scoped_ptr<HttpStreamRequest> request2(
1316 session->http_stream_factory_for_websocket()
1317 ->RequestWebSocketHandshakeStream(request_info,
1318 DEFAULT_PRIORITY,
1319 ssl_config,
1320 ssl_config,
1321 &waiter2,
1322 &create_helper,
1323 BoundNetLog()));
1324 waiter2.WaitForStream();
1325 EXPECT_TRUE(waiter2.stream_done());
1326 ASSERT_TRUE(nullptr != waiter2.websocket_stream());
1327 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy,
1328 waiter2.websocket_stream()->type());
1329 EXPECT_TRUE(nullptr == waiter2.stream());
1330 EXPECT_NE(waiter2.websocket_stream(), waiter1.websocket_stream());
1331 EXPECT_EQ(static_cast<WebSocketSpdyHandshakeStream*>(
1332 waiter2.websocket_stream())->spdy_session(),
1333 static_cast<WebSocketSpdyHandshakeStream*>(
1334 waiter1.websocket_stream())->spdy_session());
1336 EXPECT_EQ(0, GetSocketPoolGroupCount(
1337 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1338 EXPECT_EQ(0, GetSocketPoolGroupCount(
1339 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1340 EXPECT_EQ(1, GetSocketPoolGroupCount(
1341 session->GetTransportSocketPool(
1342 HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1343 EXPECT_EQ(1, GetSocketPoolGroupCount(
1344 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1345 EXPECT_TRUE(waiter1.used_proxy_info().is_direct());
1348 // TODO(ricea): Re-enable once WebSocket over SPDY is implemented.
1349 TEST_P(HttpStreamFactoryTest, DISABLED_OrphanedWebSocketStream) {
1350 SpdySessionDependencies session_deps(GetParam(),
1351 ProxyService::CreateDirect());
1352 session_deps.use_alternative_services = true;
1354 MockRead mock_read(ASYNC, OK);
1355 SequencedSocketData socket_data(&mock_read, 1, nullptr, 0);
1356 socket_data.set_connect_data(MockConnect(ASYNC, OK));
1357 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
1359 MockRead mock_read2(ASYNC, OK);
1360 SequencedSocketData socket_data2(&mock_read2, 1, nullptr, 0);
1361 socket_data2.set_connect_data(MockConnect(ASYNC, ERR_IO_PENDING));
1362 session_deps.socket_factory->AddSocketDataProvider(&socket_data2);
1364 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
1365 ssl_socket_data.SetNextProto(GetParam());
1366 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
1368 scoped_refptr<HttpNetworkSession> session(
1369 SpdySessionDependencies::SpdyCreateSession(&session_deps));
1371 // Now request a stream.
1372 HttpRequestInfo request_info;
1373 request_info.method = "GET";
1374 request_info.url = GURL("ws://www.google.com:8888");
1375 request_info.load_flags = 0;
1377 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
1378 session->http_server_properties()->SetAlternativeService(
1379 HostPortPair("www.google.com", 8888),
1380 AlternativeService(NPN_HTTP_2, "www.google.com", 9999), 1.0, expiration);
1382 SSLConfig ssl_config;
1383 StreamRequestWaiter waiter;
1384 WebSocketStreamCreateHelper create_helper;
1385 scoped_ptr<HttpStreamRequest> request(
1386 session->http_stream_factory_for_websocket()
1387 ->RequestWebSocketHandshakeStream(request_info,
1388 DEFAULT_PRIORITY,
1389 ssl_config,
1390 ssl_config,
1391 &waiter,
1392 &create_helper,
1393 BoundNetLog()));
1394 waiter.WaitForStream();
1395 EXPECT_TRUE(waiter.stream_done());
1396 EXPECT_TRUE(nullptr == waiter.stream());
1397 ASSERT_TRUE(nullptr != waiter.websocket_stream());
1398 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy,
1399 waiter.websocket_stream()->type());
1401 // Make sure that there was an alternative connection
1402 // which consumes extra connections.
1403 EXPECT_EQ(0, GetSocketPoolGroupCount(
1404 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1405 EXPECT_EQ(0, GetSocketPoolGroupCount(
1406 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1407 EXPECT_EQ(2, GetSocketPoolGroupCount(
1408 session->GetTransportSocketPool(
1409 HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1410 EXPECT_EQ(1, GetSocketPoolGroupCount(
1411 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1412 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
1414 // Make sure there is no orphaned job. it is already canceled.
1415 ASSERT_EQ(0u, static_cast<HttpStreamFactoryImpl*>(
1416 session->http_stream_factory_for_websocket())->num_orphaned_jobs());
1419 } // namespace
1421 } // namespace net