Bypass QUIC proxy on ERR_MSG_TOO_BIG
[chromium-blink-merge.git] / net / http / http_stream_factory_impl_unittest.cc
blob9bf70e04d98d715b2f79f47a5dde25b169a701ed
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 <stdint.h>
9 #include <string>
10 #include <vector>
12 #include "base/basictypes.h"
13 #include "base/compiler_specific.h"
14 #include "net/base/port_util.h"
15 #include "net/base/test_completion_callback.h"
16 #include "net/cert/mock_cert_verifier.h"
17 #include "net/dns/mock_host_resolver.h"
18 #include "net/http/http_auth_handler_factory.h"
19 #include "net/http/http_network_session.h"
20 #include "net/http/http_network_session_peer.h"
21 #include "net/http/http_network_transaction.h"
22 #include "net/http/http_request_info.h"
23 #include "net/http/http_server_properties.h"
24 #include "net/http/http_server_properties_impl.h"
25 #include "net/http/http_stream.h"
26 #include "net/http/transport_security_state.h"
27 #include "net/log/net_log.h"
28 #include "net/proxy/proxy_info.h"
29 #include "net/proxy/proxy_service.h"
30 #include "net/socket/client_socket_handle.h"
31 #include "net/socket/mock_client_socket_pool_manager.h"
32 #include "net/socket/next_proto.h"
33 #include "net/socket/socket_test_util.h"
34 #include "net/spdy/spdy_session.h"
35 #include "net/spdy/spdy_session_pool.h"
36 #include "net/spdy/spdy_test_util_common.h"
37 #include "net/ssl/ssl_config_service.h"
38 #include "net/ssl/ssl_config_service_defaults.h"
39 // This file can be included from net/http even though
40 // it is in net/websockets because it doesn't
41 // introduce any link dependency to net/websockets.
42 #include "net/websockets/websocket_handshake_stream_base.h"
43 #include "testing/gtest/include/gtest/gtest.h"
45 namespace net {
47 namespace {
49 class MockWebSocketHandshakeStream : public WebSocketHandshakeStreamBase {
50 public:
51 enum StreamType {
52 kStreamTypeBasic,
53 kStreamTypeSpdy,
56 explicit MockWebSocketHandshakeStream(StreamType type) : type_(type) {}
58 ~MockWebSocketHandshakeStream() override {}
60 StreamType type() const {
61 return type_;
64 // HttpStream methods
65 int InitializeStream(const HttpRequestInfo* request_info,
66 RequestPriority priority,
67 const BoundNetLog& net_log,
68 const CompletionCallback& callback) override {
69 return ERR_IO_PENDING;
71 int SendRequest(const HttpRequestHeaders& request_headers,
72 HttpResponseInfo* response,
73 const CompletionCallback& callback) override {
74 return ERR_IO_PENDING;
76 int ReadResponseHeaders(const CompletionCallback& callback) override {
77 return ERR_IO_PENDING;
79 int ReadResponseBody(IOBuffer* buf,
80 int buf_len,
81 const CompletionCallback& callback) override {
82 return ERR_IO_PENDING;
84 void Close(bool not_reusable) override {}
85 bool IsResponseBodyComplete() const override { return false; }
86 bool IsConnectionReused() const override { return false; }
87 void SetConnectionReused() override {}
88 bool CanReuseConnection() const override { return false; }
89 int64 GetTotalReceivedBytes() const override { return 0; }
90 int64_t GetTotalSentBytes() const override { return 0; }
91 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
92 return false;
94 void GetSSLInfo(SSLInfo* ssl_info) override {}
95 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {}
96 void Drain(HttpNetworkSession* session) override {}
97 void SetPriority(RequestPriority priority) override {}
98 UploadProgress GetUploadProgress() const override { return UploadProgress(); }
99 HttpStream* RenewStreamForAuth() override { return nullptr; }
101 scoped_ptr<WebSocketStream> Upgrade() override {
102 return scoped_ptr<WebSocketStream>();
105 private:
106 const StreamType type_;
109 // HttpStreamFactoryImpl subclass that can wait until a preconnect is complete.
110 class MockHttpStreamFactoryImplForPreconnect : public HttpStreamFactoryImpl {
111 public:
112 MockHttpStreamFactoryImplForPreconnect(HttpNetworkSession* session,
113 bool for_websockets)
114 : HttpStreamFactoryImpl(session, for_websockets),
115 preconnect_done_(false),
116 waiting_for_preconnect_(false) {}
119 void WaitForPreconnects() {
120 while (!preconnect_done_) {
121 waiting_for_preconnect_ = true;
122 base::MessageLoop::current()->Run();
123 waiting_for_preconnect_ = false;
127 private:
128 // HttpStreamFactoryImpl methods.
129 void OnPreconnectsCompleteInternal() override {
130 preconnect_done_ = true;
131 if (waiting_for_preconnect_)
132 base::MessageLoop::current()->Quit();
135 bool preconnect_done_;
136 bool waiting_for_preconnect_;
139 class StreamRequestWaiter : public HttpStreamRequest::Delegate {
140 public:
141 StreamRequestWaiter()
142 : waiting_for_stream_(false),
143 stream_done_(false) {}
145 // HttpStreamRequest::Delegate
147 void OnStreamReady(const SSLConfig& used_ssl_config,
148 const ProxyInfo& used_proxy_info,
149 HttpStream* stream) override {
150 stream_done_ = true;
151 if (waiting_for_stream_)
152 base::MessageLoop::current()->Quit();
153 stream_.reset(stream);
154 used_ssl_config_ = used_ssl_config;
155 used_proxy_info_ = used_proxy_info;
158 void OnWebSocketHandshakeStreamReady(
159 const SSLConfig& used_ssl_config,
160 const ProxyInfo& used_proxy_info,
161 WebSocketHandshakeStreamBase* stream) override {
162 stream_done_ = true;
163 if (waiting_for_stream_)
164 base::MessageLoop::current()->Quit();
165 websocket_stream_.reset(stream);
166 used_ssl_config_ = used_ssl_config;
167 used_proxy_info_ = used_proxy_info;
170 void OnStreamFailed(int status,
171 const SSLConfig& used_ssl_config,
172 SSLFailureState ssl_failure_state) override {}
174 void OnCertificateError(int status,
175 const SSLConfig& used_ssl_config,
176 const SSLInfo& ssl_info) override {}
178 void OnNeedsProxyAuth(const HttpResponseInfo& proxy_response,
179 const SSLConfig& used_ssl_config,
180 const ProxyInfo& used_proxy_info,
181 HttpAuthController* auth_controller) override {}
183 void OnNeedsClientAuth(const SSLConfig& used_ssl_config,
184 SSLCertRequestInfo* cert_info) override {}
186 void OnHttpsProxyTunnelResponse(const HttpResponseInfo& response_info,
187 const SSLConfig& used_ssl_config,
188 const ProxyInfo& used_proxy_info,
189 HttpStream* stream) override {}
191 void WaitForStream() {
192 while (!stream_done_) {
193 waiting_for_stream_ = true;
194 base::MessageLoop::current()->Run();
195 waiting_for_stream_ = false;
199 const SSLConfig& used_ssl_config() const {
200 return used_ssl_config_;
203 const ProxyInfo& used_proxy_info() const {
204 return used_proxy_info_;
207 HttpStream* stream() {
208 return stream_.get();
211 MockWebSocketHandshakeStream* websocket_stream() {
212 return static_cast<MockWebSocketHandshakeStream*>(websocket_stream_.get());
215 bool stream_done() const { return stream_done_; }
217 private:
218 bool waiting_for_stream_;
219 bool stream_done_;
220 scoped_ptr<HttpStream> stream_;
221 scoped_ptr<WebSocketHandshakeStreamBase> websocket_stream_;
222 SSLConfig used_ssl_config_;
223 ProxyInfo used_proxy_info_;
225 DISALLOW_COPY_AND_ASSIGN(StreamRequestWaiter);
228 class WebSocketSpdyHandshakeStream : public MockWebSocketHandshakeStream {
229 public:
230 explicit WebSocketSpdyHandshakeStream(
231 const base::WeakPtr<SpdySession>& spdy_session)
232 : MockWebSocketHandshakeStream(kStreamTypeSpdy),
233 spdy_session_(spdy_session) {}
235 ~WebSocketSpdyHandshakeStream() override {}
237 SpdySession* spdy_session() { return spdy_session_.get(); }
239 private:
240 base::WeakPtr<SpdySession> spdy_session_;
243 class WebSocketBasicHandshakeStream : public MockWebSocketHandshakeStream {
244 public:
245 explicit WebSocketBasicHandshakeStream(
246 scoped_ptr<ClientSocketHandle> connection)
247 : MockWebSocketHandshakeStream(kStreamTypeBasic),
248 connection_(connection.Pass()) {}
250 ~WebSocketBasicHandshakeStream() override {
251 connection_->socket()->Disconnect();
254 ClientSocketHandle* connection() { return connection_.get(); }
256 private:
257 scoped_ptr<ClientSocketHandle> connection_;
260 class WebSocketStreamCreateHelper
261 : public WebSocketHandshakeStreamBase::CreateHelper {
262 public:
263 ~WebSocketStreamCreateHelper() override {}
265 WebSocketHandshakeStreamBase* CreateBasicStream(
266 scoped_ptr<ClientSocketHandle> connection,
267 bool using_proxy) override {
268 return new WebSocketBasicHandshakeStream(connection.Pass());
271 WebSocketHandshakeStreamBase* CreateSpdyStream(
272 const base::WeakPtr<SpdySession>& spdy_session,
273 bool use_relative_url) override {
274 return new WebSocketSpdyHandshakeStream(spdy_session);
278 struct TestCase {
279 int num_streams;
280 bool ssl;
283 TestCase kTests[] = {
284 { 1, false },
285 { 2, false },
286 { 1, true},
287 { 2, true},
290 void PreconnectHelperForURL(int num_streams,
291 const GURL& url,
292 HttpNetworkSession* session) {
293 HttpNetworkSessionPeer peer(session);
294 MockHttpStreamFactoryImplForPreconnect* mock_factory =
295 new MockHttpStreamFactoryImplForPreconnect(session, false);
296 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(mock_factory));
297 SSLConfig ssl_config;
298 session->ssl_config_service()->GetSSLConfig(&ssl_config);
300 HttpRequestInfo request;
301 request.method = "GET";
302 request.url = url;
303 request.load_flags = 0;
305 session->http_stream_factory()->PreconnectStreams(num_streams, request,
306 ssl_config, ssl_config);
307 mock_factory->WaitForPreconnects();
310 void PreconnectHelper(const TestCase& test,
311 HttpNetworkSession* session) {
312 GURL url = test.ssl ? GURL("https://www.google.com") :
313 GURL("http://www.google.com");
314 PreconnectHelperForURL(test.num_streams, url, session);
317 template<typename ParentPool>
318 class CapturePreconnectsSocketPool : public ParentPool {
319 public:
320 CapturePreconnectsSocketPool(HostResolver* host_resolver,
321 CertVerifier* cert_verifier);
323 int last_num_streams() const {
324 return last_num_streams_;
327 int RequestSocket(const std::string& group_name,
328 const void* socket_params,
329 RequestPriority priority,
330 ClientSocketHandle* handle,
331 const CompletionCallback& callback,
332 const BoundNetLog& net_log) override {
333 ADD_FAILURE();
334 return ERR_UNEXPECTED;
337 void RequestSockets(const std::string& group_name,
338 const void* socket_params,
339 int num_sockets,
340 const BoundNetLog& net_log) override {
341 last_num_streams_ = num_sockets;
344 void CancelRequest(const std::string& group_name,
345 ClientSocketHandle* handle) override {
346 ADD_FAILURE();
348 void ReleaseSocket(const std::string& group_name,
349 scoped_ptr<StreamSocket> socket,
350 int id) override {
351 ADD_FAILURE();
353 void CloseIdleSockets() override { ADD_FAILURE(); }
354 int IdleSocketCount() const override {
355 ADD_FAILURE();
356 return 0;
358 int IdleSocketCountInGroup(const std::string& group_name) const override {
359 ADD_FAILURE();
360 return 0;
362 LoadState GetLoadState(const std::string& group_name,
363 const ClientSocketHandle* handle) const override {
364 ADD_FAILURE();
365 return LOAD_STATE_IDLE;
367 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,
387 CertVerifier* /* cert_verifier */)
388 : ParentPool(0, 0, host_resolver, nullptr, nullptr), last_num_streams_(-1) {
391 template <>
392 CapturePreconnectsHttpProxySocketPool::CapturePreconnectsSocketPool(
393 HostResolver* /* host_resolver */,
394 CertVerifier* /* cert_verifier */)
395 : HttpProxyClientSocketPool(0, 0, nullptr, nullptr, nullptr),
396 last_num_streams_(-1) {
399 template <>
400 CapturePreconnectsSSLSocketPool::CapturePreconnectsSocketPool(
401 HostResolver* /* host_resolver */,
402 CertVerifier* cert_verifier)
403 : SSLClientSocketPool(0,
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 kProtoHTTP2));
429 TEST_P(HttpStreamFactoryTest, PreconnectDirect) {
430 for (size_t i = 0; i < arraysize(kTests); ++i) {
431 SpdySessionDependencies session_deps(
432 GetParam(), ProxyService::CreateDirect());
433 scoped_refptr<HttpNetworkSession> session(
434 SpdySessionDependencies::SpdyCreateSession(&session_deps));
435 HttpNetworkSessionPeer peer(session);
436 CapturePreconnectsTransportSocketPool* transport_conn_pool =
437 new CapturePreconnectsTransportSocketPool(
438 session_deps.host_resolver.get(),
439 session_deps.cert_verifier.get());
440 CapturePreconnectsSSLSocketPool* ssl_conn_pool =
441 new CapturePreconnectsSSLSocketPool(
442 session_deps.host_resolver.get(),
443 session_deps.cert_verifier.get());
444 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
445 new MockClientSocketPoolManager);
446 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
447 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
448 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
449 PreconnectHelper(kTests[i], session.get());
450 if (kTests[i].ssl)
451 EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams());
452 else
453 EXPECT_EQ(kTests[i].num_streams, transport_conn_pool->last_num_streams());
457 TEST_P(HttpStreamFactoryTest, PreconnectHttpProxy) {
458 for (size_t i = 0; i < arraysize(kTests); ++i) {
459 SpdySessionDependencies session_deps(
460 GetParam(), ProxyService::CreateFixed("http_proxy"));
461 scoped_refptr<HttpNetworkSession> session(
462 SpdySessionDependencies::SpdyCreateSession(&session_deps));
463 HttpNetworkSessionPeer peer(session);
464 HostPortPair proxy_host("http_proxy", 80);
465 CapturePreconnectsHttpProxySocketPool* http_proxy_pool =
466 new CapturePreconnectsHttpProxySocketPool(
467 session_deps.host_resolver.get(),
468 session_deps.cert_verifier.get());
469 CapturePreconnectsSSLSocketPool* ssl_conn_pool =
470 new CapturePreconnectsSSLSocketPool(
471 session_deps.host_resolver.get(),
472 session_deps.cert_verifier.get());
473 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
474 new MockClientSocketPoolManager);
475 mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
476 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
477 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
478 PreconnectHelper(kTests[i], session.get());
479 if (kTests[i].ssl)
480 EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams());
481 else
482 EXPECT_EQ(kTests[i].num_streams, http_proxy_pool->last_num_streams());
486 TEST_P(HttpStreamFactoryTest, PreconnectSocksProxy) {
487 for (size_t i = 0; i < arraysize(kTests); ++i) {
488 SpdySessionDependencies session_deps(
489 GetParam(), ProxyService::CreateFixed("socks4://socks_proxy:1080"));
490 scoped_refptr<HttpNetworkSession> session(
491 SpdySessionDependencies::SpdyCreateSession(&session_deps));
492 HttpNetworkSessionPeer peer(session);
493 HostPortPair proxy_host("socks_proxy", 1080);
494 CapturePreconnectsSOCKSSocketPool* socks_proxy_pool =
495 new CapturePreconnectsSOCKSSocketPool(
496 session_deps.host_resolver.get(),
497 session_deps.cert_verifier.get());
498 CapturePreconnectsSSLSocketPool* ssl_conn_pool =
499 new CapturePreconnectsSSLSocketPool(
500 session_deps.host_resolver.get(),
501 session_deps.cert_verifier.get());
502 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
503 new MockClientSocketPoolManager);
504 mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_proxy_pool);
505 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
506 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
507 PreconnectHelper(kTests[i], session.get());
508 if (kTests[i].ssl)
509 EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams());
510 else
511 EXPECT_EQ(kTests[i].num_streams, socks_proxy_pool->last_num_streams());
515 TEST_P(HttpStreamFactoryTest, PreconnectDirectWithExistingSpdySession) {
516 for (size_t i = 0; i < arraysize(kTests); ++i) {
517 SpdySessionDependencies session_deps(
518 GetParam(), ProxyService::CreateDirect());
519 scoped_refptr<HttpNetworkSession> session(
520 SpdySessionDependencies::SpdyCreateSession(&session_deps));
521 HttpNetworkSessionPeer peer(session);
523 // Put a SpdySession in the pool.
524 HostPortPair host_port_pair("www.google.com", 443);
525 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
526 PRIVACY_MODE_DISABLED);
527 ignore_result(CreateFakeSpdySession(session->spdy_session_pool(), key));
529 CapturePreconnectsTransportSocketPool* transport_conn_pool =
530 new CapturePreconnectsTransportSocketPool(
531 session_deps.host_resolver.get(),
532 session_deps.cert_verifier.get());
533 CapturePreconnectsSSLSocketPool* ssl_conn_pool =
534 new CapturePreconnectsSSLSocketPool(
535 session_deps.host_resolver.get(),
536 session_deps.cert_verifier.get());
537 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
538 new MockClientSocketPoolManager);
539 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
540 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
541 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
542 PreconnectHelper(kTests[i], session.get());
543 // We shouldn't be preconnecting if we have an existing session, which is
544 // the case for https://www.google.com.
545 if (kTests[i].ssl)
546 EXPECT_EQ(-1, ssl_conn_pool->last_num_streams());
547 else
548 EXPECT_EQ(kTests[i].num_streams,
549 transport_conn_pool->last_num_streams());
553 // Verify that preconnects to unsafe ports are cancelled before they reach
554 // the SocketPool.
555 TEST_P(HttpStreamFactoryTest, PreconnectUnsafePort) {
556 ASSERT_FALSE(IsPortAllowedForScheme(7, "http"));
558 SpdySessionDependencies session_deps(
559 GetParam(), ProxyService::CreateDirect());
560 scoped_refptr<HttpNetworkSession> session(
561 SpdySessionDependencies::SpdyCreateSession(&session_deps));
562 HttpNetworkSessionPeer peer(session);
563 CapturePreconnectsTransportSocketPool* transport_conn_pool =
564 new CapturePreconnectsTransportSocketPool(
565 session_deps.host_resolver.get(),
566 session_deps.cert_verifier.get());
567 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
568 new MockClientSocketPoolManager);
569 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
570 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
572 PreconnectHelperForURL(1, GURL("http://www.google.com:7"), session.get());
573 EXPECT_EQ(-1, transport_conn_pool->last_num_streams());
576 TEST_P(HttpStreamFactoryTest, JobNotifiesProxy) {
577 const char* kProxyString = "PROXY bad:99; PROXY maybe:80; DIRECT";
578 SpdySessionDependencies session_deps(
579 GetParam(), ProxyService::CreateFixedFromPacResult(kProxyString));
581 // First connection attempt fails
582 StaticSocketDataProvider socket_data1;
583 socket_data1.set_connect_data(MockConnect(ASYNC, ERR_ADDRESS_UNREACHABLE));
584 session_deps.socket_factory->AddSocketDataProvider(&socket_data1);
586 // Second connection attempt succeeds
587 StaticSocketDataProvider socket_data2;
588 socket_data2.set_connect_data(MockConnect(ASYNC, OK));
589 session_deps.socket_factory->AddSocketDataProvider(&socket_data2);
591 scoped_refptr<HttpNetworkSession> session(
592 SpdySessionDependencies::SpdyCreateSession(&session_deps));
594 // Now request a stream. It should succeed using the second proxy in the
595 // list.
596 HttpRequestInfo request_info;
597 request_info.method = "GET";
598 request_info.url = GURL("http://www.google.com");
600 SSLConfig ssl_config;
601 StreamRequestWaiter waiter;
602 scoped_ptr<HttpStreamRequest> request(
603 session->http_stream_factory()->RequestStream(
604 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config,
605 &waiter, BoundNetLog()));
606 waiter.WaitForStream();
608 // The proxy that failed should now be known to the proxy_service as bad.
609 const ProxyRetryInfoMap& retry_info =
610 session->proxy_service()->proxy_retry_info();
611 EXPECT_EQ(1u, retry_info.size());
612 ProxyRetryInfoMap::const_iterator iter = retry_info.find("bad:99");
613 EXPECT_TRUE(iter != retry_info.end());
616 TEST_P(HttpStreamFactoryTest, UnreachableQuicProxyMarkedAsBad) {
617 const int mock_error[] = {ERR_QUIC_PROTOCOL_ERROR, ERR_QUIC_HANDSHAKE_FAILED,
618 ERR_MSG_TOO_BIG};
619 for (size_t i = 0; i < arraysize(mock_error); ++i) {
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[i]));
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()) << mock_error[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()) << mock_error[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 {
782 // Return count of distinct groups in given socket pool.
783 int GetSocketPoolGroupCount(ClientSocketPool* pool) {
784 int count = 0;
785 scoped_ptr<base::DictionaryValue> dict(pool->GetInfoAsValue("", "", false));
786 EXPECT_TRUE(dict != nullptr);
787 base::DictionaryValue* groups = nullptr;
788 if (dict->GetDictionary("groups", &groups) && (groups != nullptr)) {
789 count = static_cast<int>(groups->size());
791 return count;
794 // Return count of distinct spdy sessions.
795 int GetSpdySessionCount(HttpNetworkSession* session) {
796 scoped_ptr<base::Value> value(
797 session->spdy_session_pool()->SpdySessionPoolInfoToValue());
798 base::ListValue* session_list;
799 if (!value || !value->GetAsList(&session_list))
800 return -1;
801 return session_list->GetSize();
804 } // namespace
806 TEST_P(HttpStreamFactoryTest, PrivacyModeUsesDifferentSocketPoolGroup) {
807 SpdySessionDependencies session_deps(
808 GetParam(), ProxyService::CreateDirect());
810 StaticSocketDataProvider socket_data;
811 socket_data.set_connect_data(MockConnect(ASYNC, OK));
812 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
814 SSLSocketDataProvider ssl(ASYNC, OK);
815 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
817 scoped_refptr<HttpNetworkSession> session(
818 SpdySessionDependencies::SpdyCreateSession(&session_deps));
819 SSLClientSocketPool* ssl_pool = session->GetSSLSocketPool(
820 HttpNetworkSession::NORMAL_SOCKET_POOL);
822 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 0);
824 HttpRequestInfo request_info;
825 request_info.method = "GET";
826 request_info.url = GURL("https://www.google.com");
827 request_info.load_flags = 0;
828 request_info.privacy_mode = PRIVACY_MODE_DISABLED;
830 SSLConfig ssl_config;
831 StreamRequestWaiter waiter;
833 scoped_ptr<HttpStreamRequest> request1(
834 session->http_stream_factory()->RequestStream(
835 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config,
836 &waiter, BoundNetLog()));
837 waiter.WaitForStream();
839 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 1);
841 scoped_ptr<HttpStreamRequest> request2(
842 session->http_stream_factory()->RequestStream(
843 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config,
844 &waiter, BoundNetLog()));
845 waiter.WaitForStream();
847 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 1);
849 request_info.privacy_mode = PRIVACY_MODE_ENABLED;
850 scoped_ptr<HttpStreamRequest> request3(
851 session->http_stream_factory()->RequestStream(
852 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config,
853 &waiter, BoundNetLog()));
854 waiter.WaitForStream();
856 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 2);
859 TEST_P(HttpStreamFactoryTest, GetLoadState) {
860 SpdySessionDependencies session_deps(
861 GetParam(), ProxyService::CreateDirect());
863 StaticSocketDataProvider socket_data;
864 socket_data.set_connect_data(MockConnect(ASYNC, OK));
865 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
867 scoped_refptr<HttpNetworkSession> session(
868 SpdySessionDependencies::SpdyCreateSession(&session_deps));
870 HttpRequestInfo request_info;
871 request_info.method = "GET";
872 request_info.url = GURL("http://www.google.com");
874 SSLConfig ssl_config;
875 StreamRequestWaiter waiter;
876 scoped_ptr<HttpStreamRequest> request(
877 session->http_stream_factory()->RequestStream(
878 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config,
879 &waiter, BoundNetLog()));
881 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, request->GetLoadState());
883 waiter.WaitForStream();
886 TEST_P(HttpStreamFactoryTest, RequestHttpStream) {
887 SpdySessionDependencies session_deps(
888 GetParam(), ProxyService::CreateDirect());
890 StaticSocketDataProvider socket_data;
891 socket_data.set_connect_data(MockConnect(ASYNC, OK));
892 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
894 scoped_refptr<HttpNetworkSession> session(
895 SpdySessionDependencies::SpdyCreateSession(&session_deps));
897 // Now request a stream. It should succeed using the second proxy in the
898 // list.
899 HttpRequestInfo request_info;
900 request_info.method = "GET";
901 request_info.url = GURL("http://www.google.com");
902 request_info.load_flags = 0;
904 SSLConfig ssl_config;
905 StreamRequestWaiter waiter;
906 scoped_ptr<HttpStreamRequest> request(
907 session->http_stream_factory()->RequestStream(
908 request_info,
909 DEFAULT_PRIORITY,
910 ssl_config,
911 ssl_config,
912 &waiter,
913 BoundNetLog()));
914 waiter.WaitForStream();
915 EXPECT_TRUE(waiter.stream_done());
916 ASSERT_TRUE(nullptr != waiter.stream());
917 EXPECT_TRUE(nullptr == waiter.websocket_stream());
919 EXPECT_EQ(0, GetSpdySessionCount(session.get()));
920 EXPECT_EQ(1, GetSocketPoolGroupCount(
921 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
922 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool(
923 HttpNetworkSession::NORMAL_SOCKET_POOL)));
924 EXPECT_EQ(0, GetSocketPoolGroupCount(
925 session->GetTransportSocketPool(
926 HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
927 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool(
928 HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
929 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
932 TEST_P(HttpStreamFactoryTest, RequestHttpStreamOverSSL) {
933 SpdySessionDependencies session_deps(
934 GetParam(), ProxyService::CreateDirect());
936 MockRead mock_read(ASYNC, OK);
937 StaticSocketDataProvider socket_data(&mock_read, 1, nullptr, 0);
938 socket_data.set_connect_data(MockConnect(ASYNC, OK));
939 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
941 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
942 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
944 scoped_refptr<HttpNetworkSession> session(
945 SpdySessionDependencies::SpdyCreateSession(&session_deps));
947 // Now request a stream.
948 HttpRequestInfo request_info;
949 request_info.method = "GET";
950 request_info.url = GURL("https://www.google.com");
951 request_info.load_flags = 0;
953 SSLConfig ssl_config;
954 StreamRequestWaiter waiter;
955 scoped_ptr<HttpStreamRequest> request(
956 session->http_stream_factory()->RequestStream(
957 request_info,
958 DEFAULT_PRIORITY,
959 ssl_config,
960 ssl_config,
961 &waiter,
962 BoundNetLog()));
963 waiter.WaitForStream();
964 EXPECT_TRUE(waiter.stream_done());
965 ASSERT_TRUE(nullptr != waiter.stream());
966 EXPECT_TRUE(nullptr == waiter.websocket_stream());
968 EXPECT_EQ(0, GetSpdySessionCount(session.get()));
969 EXPECT_EQ(1, GetSocketPoolGroupCount(
970 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
971 EXPECT_EQ(1, GetSocketPoolGroupCount(
972 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
973 EXPECT_EQ(0, GetSocketPoolGroupCount(
974 session->GetTransportSocketPool(
975 HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
976 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool(
977 HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
978 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
981 TEST_P(HttpStreamFactoryTest, RequestHttpStreamOverProxy) {
982 SpdySessionDependencies session_deps(
983 GetParam(), ProxyService::CreateFixed("myproxy:8888"));
985 StaticSocketDataProvider socket_data;
986 socket_data.set_connect_data(MockConnect(ASYNC, OK));
987 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
989 scoped_refptr<HttpNetworkSession> session(
990 SpdySessionDependencies::SpdyCreateSession(&session_deps));
992 // Now request a stream. It should succeed using the second proxy in the
993 // list.
994 HttpRequestInfo request_info;
995 request_info.method = "GET";
996 request_info.url = GURL("http://www.google.com");
997 request_info.load_flags = 0;
999 SSLConfig ssl_config;
1000 StreamRequestWaiter waiter;
1001 scoped_ptr<HttpStreamRequest> request(
1002 session->http_stream_factory()->RequestStream(
1003 request_info,
1004 DEFAULT_PRIORITY,
1005 ssl_config,
1006 ssl_config,
1007 &waiter,
1008 BoundNetLog()));
1009 waiter.WaitForStream();
1010 EXPECT_TRUE(waiter.stream_done());
1011 ASSERT_TRUE(nullptr != waiter.stream());
1012 EXPECT_TRUE(nullptr == waiter.websocket_stream());
1014 EXPECT_EQ(0, GetSpdySessionCount(session.get()));
1015 EXPECT_EQ(0, GetSocketPoolGroupCount(
1016 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1017 EXPECT_EQ(0, GetSocketPoolGroupCount(
1018 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1019 EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSocketPoolForHTTPProxy(
1020 HttpNetworkSession::NORMAL_SOCKET_POOL,
1021 HostPortPair("myproxy", 8888))));
1022 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForSSLWithProxy(
1023 HttpNetworkSession::NORMAL_SOCKET_POOL,
1024 HostPortPair("myproxy", 8888))));
1025 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForHTTPProxy(
1026 HttpNetworkSession::WEBSOCKET_SOCKET_POOL,
1027 HostPortPair("myproxy", 8888))));
1028 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForSSLWithProxy(
1029 HttpNetworkSession::WEBSOCKET_SOCKET_POOL,
1030 HostPortPair("myproxy", 8888))));
1031 EXPECT_FALSE(waiter.used_proxy_info().is_direct());
1034 TEST_P(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStream) {
1035 SpdySessionDependencies session_deps(
1036 GetParam(), ProxyService::CreateDirect());
1038 StaticSocketDataProvider socket_data;
1039 socket_data.set_connect_data(MockConnect(ASYNC, OK));
1040 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
1042 scoped_refptr<HttpNetworkSession> session(
1043 SpdySessionDependencies::SpdyCreateSession(&session_deps));
1045 // Now request a stream.
1046 HttpRequestInfo request_info;
1047 request_info.method = "GET";
1048 request_info.url = GURL("ws://www.google.com");
1049 request_info.load_flags = 0;
1051 SSLConfig ssl_config;
1052 StreamRequestWaiter waiter;
1053 WebSocketStreamCreateHelper create_helper;
1054 scoped_ptr<HttpStreamRequest> request(
1055 session->http_stream_factory_for_websocket()
1056 ->RequestWebSocketHandshakeStream(request_info,
1057 DEFAULT_PRIORITY,
1058 ssl_config,
1059 ssl_config,
1060 &waiter,
1061 &create_helper,
1062 BoundNetLog()));
1063 waiter.WaitForStream();
1064 EXPECT_TRUE(waiter.stream_done());
1065 EXPECT_TRUE(nullptr == waiter.stream());
1066 ASSERT_TRUE(nullptr != waiter.websocket_stream());
1067 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic,
1068 waiter.websocket_stream()->type());
1069 EXPECT_EQ(0, GetSocketPoolGroupCount(
1070 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1071 EXPECT_EQ(0, GetSocketPoolGroupCount(
1072 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1073 EXPECT_EQ(0, GetSocketPoolGroupCount(
1074 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1075 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
1078 TEST_P(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStreamOverSSL) {
1079 SpdySessionDependencies session_deps(
1080 GetParam(), ProxyService::CreateDirect());
1082 MockRead mock_read(ASYNC, OK);
1083 StaticSocketDataProvider socket_data(&mock_read, 1, nullptr, 0);
1084 socket_data.set_connect_data(MockConnect(ASYNC, OK));
1085 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
1087 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
1088 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
1090 scoped_refptr<HttpNetworkSession> session(
1091 SpdySessionDependencies::SpdyCreateSession(&session_deps));
1093 // Now request a stream.
1094 HttpRequestInfo request_info;
1095 request_info.method = "GET";
1096 request_info.url = GURL("wss://www.google.com");
1097 request_info.load_flags = 0;
1099 SSLConfig ssl_config;
1100 StreamRequestWaiter waiter;
1101 WebSocketStreamCreateHelper create_helper;
1102 scoped_ptr<HttpStreamRequest> request(
1103 session->http_stream_factory_for_websocket()
1104 ->RequestWebSocketHandshakeStream(request_info,
1105 DEFAULT_PRIORITY,
1106 ssl_config,
1107 ssl_config,
1108 &waiter,
1109 &create_helper,
1110 BoundNetLog()));
1111 waiter.WaitForStream();
1112 EXPECT_TRUE(waiter.stream_done());
1113 EXPECT_TRUE(nullptr == waiter.stream());
1114 ASSERT_TRUE(nullptr != waiter.websocket_stream());
1115 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic,
1116 waiter.websocket_stream()->type());
1117 EXPECT_EQ(0, GetSocketPoolGroupCount(
1118 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1119 EXPECT_EQ(0, GetSocketPoolGroupCount(
1120 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1121 EXPECT_EQ(1, GetSocketPoolGroupCount(
1122 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1123 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
1126 TEST_P(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStreamOverProxy) {
1127 SpdySessionDependencies session_deps(
1128 GetParam(), ProxyService::CreateFixed("myproxy:8888"));
1130 MockRead read(SYNCHRONOUS, "HTTP/1.0 200 Connection established\r\n\r\n");
1131 StaticSocketDataProvider socket_data(&read, 1, 0, 0);
1132 socket_data.set_connect_data(MockConnect(ASYNC, OK));
1133 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
1135 scoped_refptr<HttpNetworkSession> session(
1136 SpdySessionDependencies::SpdyCreateSession(&session_deps));
1138 // Now request a stream.
1139 HttpRequestInfo request_info;
1140 request_info.method = "GET";
1141 request_info.url = GURL("ws://www.google.com");
1142 request_info.load_flags = 0;
1144 SSLConfig ssl_config;
1145 StreamRequestWaiter waiter;
1146 WebSocketStreamCreateHelper create_helper;
1147 scoped_ptr<HttpStreamRequest> request(
1148 session->http_stream_factory_for_websocket()
1149 ->RequestWebSocketHandshakeStream(request_info,
1150 DEFAULT_PRIORITY,
1151 ssl_config,
1152 ssl_config,
1153 &waiter,
1154 &create_helper,
1155 BoundNetLog()));
1156 waiter.WaitForStream();
1157 EXPECT_TRUE(waiter.stream_done());
1158 EXPECT_TRUE(nullptr == waiter.stream());
1159 ASSERT_TRUE(nullptr != waiter.websocket_stream());
1160 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic,
1161 waiter.websocket_stream()->type());
1162 EXPECT_EQ(0, GetSocketPoolGroupCount(
1163 session->GetTransportSocketPool(
1164 HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1165 EXPECT_EQ(0, GetSocketPoolGroupCount(
1166 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1167 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForHTTPProxy(
1168 HttpNetworkSession::NORMAL_SOCKET_POOL,
1169 HostPortPair("myproxy", 8888))));
1170 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForSSLWithProxy(
1171 HttpNetworkSession::NORMAL_SOCKET_POOL,
1172 HostPortPair("myproxy", 8888))));
1173 EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSocketPoolForHTTPProxy(
1174 HttpNetworkSession::WEBSOCKET_SOCKET_POOL,
1175 HostPortPair("myproxy", 8888))));
1176 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForSSLWithProxy(
1177 HttpNetworkSession::WEBSOCKET_SOCKET_POOL,
1178 HostPortPair("myproxy", 8888))));
1179 EXPECT_FALSE(waiter.used_proxy_info().is_direct());
1182 TEST_P(HttpStreamFactoryTest, RequestSpdyHttpStream) {
1183 SpdySessionDependencies session_deps(GetParam(),
1184 ProxyService::CreateDirect());
1186 MockRead mock_read(SYNCHRONOUS, ERR_IO_PENDING);
1187 SequencedSocketData socket_data(&mock_read, 1, nullptr, 0);
1188 socket_data.set_connect_data(MockConnect(ASYNC, OK));
1189 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
1191 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
1192 ssl_socket_data.SetNextProto(GetParam());
1193 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
1195 HostPortPair host_port_pair("www.google.com", 443);
1196 scoped_refptr<HttpNetworkSession> session(
1197 SpdySessionDependencies::SpdyCreateSession(&session_deps));
1199 // Now request a stream.
1200 HttpRequestInfo request_info;
1201 request_info.method = "GET";
1202 request_info.url = GURL("https://www.google.com");
1203 request_info.load_flags = 0;
1205 SSLConfig ssl_config;
1206 StreamRequestWaiter waiter;
1207 scoped_ptr<HttpStreamRequest> request(
1208 session->http_stream_factory()->RequestStream(
1209 request_info,
1210 DEFAULT_PRIORITY,
1211 ssl_config,
1212 ssl_config,
1213 &waiter,
1214 BoundNetLog()));
1215 waiter.WaitForStream();
1216 EXPECT_TRUE(waiter.stream_done());
1217 EXPECT_TRUE(nullptr == waiter.websocket_stream());
1218 ASSERT_TRUE(nullptr != waiter.stream());
1220 EXPECT_EQ(1, GetSpdySessionCount(session.get()));
1221 EXPECT_EQ(1, GetSocketPoolGroupCount(
1222 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1223 EXPECT_EQ(1, GetSocketPoolGroupCount(
1224 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1225 EXPECT_EQ(0, GetSocketPoolGroupCount(
1226 session->GetTransportSocketPool(
1227 HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1228 EXPECT_EQ(0, GetSocketPoolGroupCount(
1229 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1230 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
1233 // TODO(ricea): This test can be removed once the new WebSocket stack supports
1234 // SPDY. Currently, even if we connect to a SPDY-supporting server, we need to
1235 // use plain SSL.
1236 TEST_P(HttpStreamFactoryTest, RequestWebSocketSpdyHandshakeStreamButGetSSL) {
1237 SpdySessionDependencies session_deps(GetParam(),
1238 ProxyService::CreateDirect());
1240 MockRead mock_read(SYNCHRONOUS, ERR_IO_PENDING);
1241 StaticSocketDataProvider socket_data(&mock_read, 1, nullptr, 0);
1242 socket_data.set_connect_data(MockConnect(ASYNC, OK));
1243 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
1245 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
1246 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
1248 HostPortPair host_port_pair("www.google.com", 80);
1249 scoped_refptr<HttpNetworkSession>
1250 session(SpdySessionDependencies::SpdyCreateSession(&session_deps));
1252 // Now request a stream.
1253 HttpRequestInfo request_info;
1254 request_info.method = "GET";
1255 request_info.url = GURL("wss://www.google.com");
1256 request_info.load_flags = 0;
1258 SSLConfig ssl_config;
1259 StreamRequestWaiter waiter1;
1260 WebSocketStreamCreateHelper create_helper;
1261 scoped_ptr<HttpStreamRequest> request1(
1262 session->http_stream_factory_for_websocket()
1263 ->RequestWebSocketHandshakeStream(request_info,
1264 DEFAULT_PRIORITY,
1265 ssl_config,
1266 ssl_config,
1267 &waiter1,
1268 &create_helper,
1269 BoundNetLog()));
1270 waiter1.WaitForStream();
1271 EXPECT_TRUE(waiter1.stream_done());
1272 ASSERT_TRUE(nullptr != waiter1.websocket_stream());
1273 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic,
1274 waiter1.websocket_stream()->type());
1275 EXPECT_TRUE(nullptr == waiter1.stream());
1277 EXPECT_EQ(0, GetSocketPoolGroupCount(
1278 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1279 EXPECT_EQ(0, GetSocketPoolGroupCount(
1280 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1281 EXPECT_EQ(1, GetSocketPoolGroupCount(
1282 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1283 EXPECT_TRUE(waiter1.used_proxy_info().is_direct());
1286 // TODO(ricea): Re-enable once WebSocket-over-SPDY is implemented.
1287 TEST_P(HttpStreamFactoryTest, DISABLED_RequestWebSocketSpdyHandshakeStream) {
1288 SpdySessionDependencies session_deps(GetParam(),
1289 ProxyService::CreateDirect());
1291 MockRead mock_read(SYNCHRONOUS, ERR_IO_PENDING);
1292 StaticSocketDataProvider socket_data(&mock_read, 1, nullptr, 0);
1293 socket_data.set_connect_data(MockConnect(ASYNC, OK));
1294 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
1296 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
1297 ssl_socket_data.SetNextProto(GetParam());
1298 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
1300 HostPortPair host_port_pair("www.google.com", 80);
1301 scoped_refptr<HttpNetworkSession>
1302 session(SpdySessionDependencies::SpdyCreateSession(&session_deps));
1304 // Now request a stream.
1305 HttpRequestInfo request_info;
1306 request_info.method = "GET";
1307 request_info.url = GURL("wss://www.google.com");
1308 request_info.load_flags = 0;
1310 SSLConfig ssl_config;
1311 StreamRequestWaiter waiter1;
1312 WebSocketStreamCreateHelper create_helper;
1313 scoped_ptr<HttpStreamRequest> request1(
1314 session->http_stream_factory_for_websocket()
1315 ->RequestWebSocketHandshakeStream(request_info,
1316 DEFAULT_PRIORITY,
1317 ssl_config,
1318 ssl_config,
1319 &waiter1,
1320 &create_helper,
1321 BoundNetLog()));
1322 waiter1.WaitForStream();
1323 EXPECT_TRUE(waiter1.stream_done());
1324 ASSERT_TRUE(nullptr != waiter1.websocket_stream());
1325 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy,
1326 waiter1.websocket_stream()->type());
1327 EXPECT_TRUE(nullptr == waiter1.stream());
1329 StreamRequestWaiter waiter2;
1330 scoped_ptr<HttpStreamRequest> request2(
1331 session->http_stream_factory_for_websocket()
1332 ->RequestWebSocketHandshakeStream(request_info,
1333 DEFAULT_PRIORITY,
1334 ssl_config,
1335 ssl_config,
1336 &waiter2,
1337 &create_helper,
1338 BoundNetLog()));
1339 waiter2.WaitForStream();
1340 EXPECT_TRUE(waiter2.stream_done());
1341 ASSERT_TRUE(nullptr != waiter2.websocket_stream());
1342 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy,
1343 waiter2.websocket_stream()->type());
1344 EXPECT_TRUE(nullptr == waiter2.stream());
1345 EXPECT_NE(waiter2.websocket_stream(), waiter1.websocket_stream());
1346 EXPECT_EQ(static_cast<WebSocketSpdyHandshakeStream*>(
1347 waiter2.websocket_stream())->spdy_session(),
1348 static_cast<WebSocketSpdyHandshakeStream*>(
1349 waiter1.websocket_stream())->spdy_session());
1351 EXPECT_EQ(0, GetSocketPoolGroupCount(
1352 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1353 EXPECT_EQ(0, GetSocketPoolGroupCount(
1354 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1355 EXPECT_EQ(1, GetSocketPoolGroupCount(
1356 session->GetTransportSocketPool(
1357 HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1358 EXPECT_EQ(1, GetSocketPoolGroupCount(
1359 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1360 EXPECT_TRUE(waiter1.used_proxy_info().is_direct());
1363 // TODO(ricea): Re-enable once WebSocket over SPDY is implemented.
1364 TEST_P(HttpStreamFactoryTest, DISABLED_OrphanedWebSocketStream) {
1365 SpdySessionDependencies session_deps(GetParam(),
1366 ProxyService::CreateDirect());
1367 session_deps.use_alternative_services = true;
1369 MockRead mock_read(ASYNC, OK);
1370 SequencedSocketData socket_data(&mock_read, 1, nullptr, 0);
1371 socket_data.set_connect_data(MockConnect(ASYNC, OK));
1372 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
1374 MockRead mock_read2(ASYNC, OK);
1375 SequencedSocketData socket_data2(&mock_read2, 1, nullptr, 0);
1376 socket_data2.set_connect_data(MockConnect(ASYNC, ERR_IO_PENDING));
1377 session_deps.socket_factory->AddSocketDataProvider(&socket_data2);
1379 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
1380 ssl_socket_data.SetNextProto(GetParam());
1381 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
1383 scoped_refptr<HttpNetworkSession> session(
1384 SpdySessionDependencies::SpdyCreateSession(&session_deps));
1386 // Now request a stream.
1387 HttpRequestInfo request_info;
1388 request_info.method = "GET";
1389 request_info.url = GURL("ws://www.google.com:8888");
1390 request_info.load_flags = 0;
1392 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
1393 session->http_server_properties()->SetAlternativeService(
1394 HostPortPair("www.google.com", 8888),
1395 AlternativeService(NPN_HTTP_2, "www.google.com", 9999), 1.0, expiration);
1397 SSLConfig ssl_config;
1398 StreamRequestWaiter waiter;
1399 WebSocketStreamCreateHelper create_helper;
1400 scoped_ptr<HttpStreamRequest> request(
1401 session->http_stream_factory_for_websocket()
1402 ->RequestWebSocketHandshakeStream(request_info,
1403 DEFAULT_PRIORITY,
1404 ssl_config,
1405 ssl_config,
1406 &waiter,
1407 &create_helper,
1408 BoundNetLog()));
1409 waiter.WaitForStream();
1410 EXPECT_TRUE(waiter.stream_done());
1411 EXPECT_TRUE(nullptr == waiter.stream());
1412 ASSERT_TRUE(nullptr != waiter.websocket_stream());
1413 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy,
1414 waiter.websocket_stream()->type());
1416 // Make sure that there was an alternative connection
1417 // which consumes extra connections.
1418 EXPECT_EQ(0, GetSocketPoolGroupCount(
1419 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1420 EXPECT_EQ(0, GetSocketPoolGroupCount(
1421 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1422 EXPECT_EQ(2, GetSocketPoolGroupCount(
1423 session->GetTransportSocketPool(
1424 HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1425 EXPECT_EQ(1, GetSocketPoolGroupCount(
1426 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1427 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
1429 // Make sure there is no orphaned job. it is already canceled.
1430 ASSERT_EQ(0u, static_cast<HttpStreamFactoryImpl*>(
1431 session->http_stream_factory_for_websocket())->num_orphaned_jobs());
1434 } // namespace
1436 } // namespace net