Lint.
[chromium-blink-merge.git] / net / http / http_stream_factory_impl_unittest.cc
blob505acdf3fa43f7fc4793e84c82a977df0d75237f
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/http/http_stream_factory_impl.h"
7 #include <string>
8 #include <vector>
10 #include "base/basictypes.h"
11 #include "base/compiler_specific.h"
12 #include "net/base/net_log.h"
13 #include "net/base/test_completion_callback.h"
14 #include "net/cert/mock_cert_verifier.h"
15 #include "net/dns/mock_host_resolver.h"
16 #include "net/http/http_auth_handler_factory.h"
17 #include "net/http/http_network_session.h"
18 #include "net/http/http_network_session_peer.h"
19 #include "net/http/http_network_transaction.h"
20 #include "net/http/http_request_info.h"
21 #include "net/http/http_server_properties.h"
22 #include "net/http/http_server_properties_impl.h"
23 #include "net/http/http_stream.h"
24 #include "net/http/transport_security_state.h"
25 #include "net/proxy/proxy_info.h"
26 #include "net/proxy/proxy_service.h"
27 #include "net/socket/client_socket_handle.h"
28 #include "net/socket/mock_client_socket_pool_manager.h"
29 #include "net/socket/next_proto.h"
30 #include "net/socket/socket_test_util.h"
31 #include "net/spdy/spdy_session.h"
32 #include "net/spdy/spdy_session_pool.h"
33 #include "net/spdy/spdy_test_util_common.h"
34 #include "net/ssl/ssl_config_service.h"
35 #include "net/ssl/ssl_config_service_defaults.h"
36 // This file can be included from net/http even though
37 // it is in net/websockets because it doesn't
38 // introduce any link dependency to net/websockets.
39 #include "net/websockets/websocket_handshake_stream_base.h"
40 #include "testing/gtest/include/gtest/gtest.h"
42 namespace net {
44 namespace {
46 class MockWebSocketHandshakeStream : public WebSocketHandshakeStreamBase {
47 public:
48 enum StreamType {
49 kStreamTypeBasic,
50 kStreamTypeSpdy,
53 explicit MockWebSocketHandshakeStream(StreamType type) : type_(type) {}
55 ~MockWebSocketHandshakeStream() override {}
57 StreamType type() const {
58 return type_;
61 // HttpStream methods
62 int InitializeStream(const HttpRequestInfo* request_info,
63 RequestPriority priority,
64 const BoundNetLog& net_log,
65 const CompletionCallback& callback) override {
66 return ERR_IO_PENDING;
68 int SendRequest(const HttpRequestHeaders& request_headers,
69 HttpResponseInfo* response,
70 const CompletionCallback& callback) override {
71 return ERR_IO_PENDING;
73 int ReadResponseHeaders(const CompletionCallback& callback) override {
74 return ERR_IO_PENDING;
76 int ReadResponseBody(IOBuffer* buf,
77 int buf_len,
78 const CompletionCallback& callback) override {
79 return ERR_IO_PENDING;
81 void Close(bool not_reusable) override {}
82 bool IsResponseBodyComplete() const override { return false; }
83 bool CanFindEndOfResponse() const override { return false; }
84 bool IsConnectionReused() const override { return false; }
85 void SetConnectionReused() override {}
86 bool IsConnectionReusable() const override { return false; }
87 int64 GetTotalReceivedBytes() const override { return 0; }
88 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
89 return false;
91 void GetSSLInfo(SSLInfo* ssl_info) override {}
92 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {}
93 bool IsSpdyHttpStream() const override { return false; }
94 void Drain(HttpNetworkSession* session) override {}
95 void SetPriority(RequestPriority priority) override {}
96 UploadProgress GetUploadProgress() const override { return UploadProgress(); }
97 HttpStream* RenewStreamForAuth() override { return nullptr; }
99 scoped_ptr<WebSocketStream> Upgrade() override {
100 return scoped_ptr<WebSocketStream>();
103 private:
104 const StreamType type_;
107 // HttpStreamFactoryImpl subclass that can wait until a preconnect is complete.
108 class MockHttpStreamFactoryImplForPreconnect : public HttpStreamFactoryImpl {
109 public:
110 MockHttpStreamFactoryImplForPreconnect(HttpNetworkSession* session,
111 bool for_websockets)
112 : HttpStreamFactoryImpl(session, for_websockets),
113 preconnect_done_(false),
114 waiting_for_preconnect_(false) {}
117 void WaitForPreconnects() {
118 while (!preconnect_done_) {
119 waiting_for_preconnect_ = true;
120 base::MessageLoop::current()->Run();
121 waiting_for_preconnect_ = false;
125 private:
126 // HttpStreamFactoryImpl methods.
127 void OnPreconnectsCompleteInternal() override {
128 preconnect_done_ = true;
129 if (waiting_for_preconnect_)
130 base::MessageLoop::current()->Quit();
133 bool preconnect_done_;
134 bool waiting_for_preconnect_;
137 class StreamRequestWaiter : public HttpStreamRequest::Delegate {
138 public:
139 StreamRequestWaiter()
140 : waiting_for_stream_(false),
141 stream_done_(false) {}
143 // HttpStreamRequest::Delegate
145 void OnStreamReady(const SSLConfig& used_ssl_config,
146 const ProxyInfo& used_proxy_info,
147 HttpStream* stream) override {
148 stream_done_ = true;
149 if (waiting_for_stream_)
150 base::MessageLoop::current()->Quit();
151 stream_.reset(stream);
152 used_ssl_config_ = used_ssl_config;
153 used_proxy_info_ = used_proxy_info;
156 void OnWebSocketHandshakeStreamReady(
157 const SSLConfig& used_ssl_config,
158 const ProxyInfo& used_proxy_info,
159 WebSocketHandshakeStreamBase* stream) override {
160 stream_done_ = true;
161 if (waiting_for_stream_)
162 base::MessageLoop::current()->Quit();
163 websocket_stream_.reset(stream);
164 used_ssl_config_ = used_ssl_config;
165 used_proxy_info_ = used_proxy_info;
168 void OnStreamFailed(int status, const SSLConfig& used_ssl_config) override {}
170 void OnCertificateError(int status,
171 const SSLConfig& used_ssl_config,
172 const SSLInfo& ssl_info) override {}
174 void OnNeedsProxyAuth(const HttpResponseInfo& proxy_response,
175 const SSLConfig& used_ssl_config,
176 const ProxyInfo& used_proxy_info,
177 HttpAuthController* auth_controller) override {}
179 void OnNeedsClientAuth(const SSLConfig& used_ssl_config,
180 SSLCertRequestInfo* cert_info) override {}
182 void OnHttpsProxyTunnelResponse(const HttpResponseInfo& response_info,
183 const SSLConfig& used_ssl_config,
184 const ProxyInfo& used_proxy_info,
185 HttpStream* stream) override {}
187 void WaitForStream() {
188 while (!stream_done_) {
189 waiting_for_stream_ = true;
190 base::MessageLoop::current()->Run();
191 waiting_for_stream_ = false;
195 const SSLConfig& used_ssl_config() const {
196 return used_ssl_config_;
199 const ProxyInfo& used_proxy_info() const {
200 return used_proxy_info_;
203 HttpStream* stream() {
204 return stream_.get();
207 MockWebSocketHandshakeStream* websocket_stream() {
208 return static_cast<MockWebSocketHandshakeStream*>(websocket_stream_.get());
211 bool stream_done() const { return stream_done_; }
213 private:
214 bool waiting_for_stream_;
215 bool stream_done_;
216 scoped_ptr<HttpStream> stream_;
217 scoped_ptr<WebSocketHandshakeStreamBase> websocket_stream_;
218 SSLConfig used_ssl_config_;
219 ProxyInfo used_proxy_info_;
221 DISALLOW_COPY_AND_ASSIGN(StreamRequestWaiter);
224 class WebSocketSpdyHandshakeStream : public MockWebSocketHandshakeStream {
225 public:
226 explicit WebSocketSpdyHandshakeStream(
227 const base::WeakPtr<SpdySession>& spdy_session)
228 : MockWebSocketHandshakeStream(kStreamTypeSpdy),
229 spdy_session_(spdy_session) {}
231 ~WebSocketSpdyHandshakeStream() override {}
233 SpdySession* spdy_session() { return spdy_session_.get(); }
235 private:
236 base::WeakPtr<SpdySession> spdy_session_;
239 class WebSocketBasicHandshakeStream : public MockWebSocketHandshakeStream {
240 public:
241 explicit WebSocketBasicHandshakeStream(
242 scoped_ptr<ClientSocketHandle> connection)
243 : MockWebSocketHandshakeStream(kStreamTypeBasic),
244 connection_(connection.Pass()) {}
246 ~WebSocketBasicHandshakeStream() override {
247 connection_->socket()->Disconnect();
250 ClientSocketHandle* connection() { return connection_.get(); }
252 private:
253 scoped_ptr<ClientSocketHandle> connection_;
256 class WebSocketStreamCreateHelper
257 : public WebSocketHandshakeStreamBase::CreateHelper {
258 public:
259 ~WebSocketStreamCreateHelper() override {}
261 WebSocketHandshakeStreamBase* CreateBasicStream(
262 scoped_ptr<ClientSocketHandle> connection,
263 bool using_proxy) override {
264 return new WebSocketBasicHandshakeStream(connection.Pass());
267 WebSocketHandshakeStreamBase* CreateSpdyStream(
268 const base::WeakPtr<SpdySession>& spdy_session,
269 bool use_relative_url) override {
270 return new WebSocketSpdyHandshakeStream(spdy_session);
274 struct TestCase {
275 int num_streams;
276 bool ssl;
279 TestCase kTests[] = {
280 { 1, false },
281 { 2, false },
282 { 1, true},
283 { 2, true},
286 void PreconnectHelperForURL(int num_streams,
287 const GURL& url,
288 HttpNetworkSession* session) {
289 HttpNetworkSessionPeer peer(session);
290 MockHttpStreamFactoryImplForPreconnect* mock_factory =
291 new MockHttpStreamFactoryImplForPreconnect(session, false);
292 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(mock_factory));
293 SSLConfig ssl_config;
294 session->ssl_config_service()->GetSSLConfig(&ssl_config);
296 HttpRequestInfo request;
297 request.method = "GET";
298 request.url = url;
299 request.load_flags = 0;
301 session->http_stream_factory()->PreconnectStreams(
302 num_streams, request, DEFAULT_PRIORITY, ssl_config, ssl_config);
303 mock_factory->WaitForPreconnects();
306 void PreconnectHelper(const TestCase& test,
307 HttpNetworkSession* session) {
308 GURL url = test.ssl ? GURL("https://www.google.com") :
309 GURL("http://www.google.com");
310 PreconnectHelperForURL(test.num_streams, url, session);
313 template<typename ParentPool>
314 class CapturePreconnectsSocketPool : public ParentPool {
315 public:
316 CapturePreconnectsSocketPool(HostResolver* host_resolver,
317 CertVerifier* cert_verifier);
319 int last_num_streams() const {
320 return last_num_streams_;
323 virtual int RequestSocket(const std::string& group_name,
324 const void* socket_params,
325 RequestPriority priority,
326 ClientSocketHandle* handle,
327 const CompletionCallback& callback,
328 const BoundNetLog& net_log) override {
329 ADD_FAILURE();
330 return ERR_UNEXPECTED;
333 virtual void RequestSockets(const std::string& group_name,
334 const void* socket_params,
335 int num_sockets,
336 const BoundNetLog& net_log) override {
337 last_num_streams_ = num_sockets;
340 virtual void CancelRequest(const std::string& group_name,
341 ClientSocketHandle* handle) override {
342 ADD_FAILURE();
344 virtual void ReleaseSocket(const std::string& group_name,
345 scoped_ptr<StreamSocket> socket,
346 int id) override {
347 ADD_FAILURE();
349 virtual void CloseIdleSockets() override {
350 ADD_FAILURE();
352 virtual int IdleSocketCount() const override {
353 ADD_FAILURE();
354 return 0;
356 virtual int IdleSocketCountInGroup(
357 const std::string& group_name) const override {
358 ADD_FAILURE();
359 return 0;
361 virtual LoadState GetLoadState(
362 const std::string& group_name,
363 const ClientSocketHandle* handle) const override {
364 ADD_FAILURE();
365 return LOAD_STATE_IDLE;
367 virtual base::TimeDelta ConnectionTimeout() const override {
368 return base::TimeDelta();
371 private:
372 int last_num_streams_;
375 typedef CapturePreconnectsSocketPool<TransportClientSocketPool>
376 CapturePreconnectsTransportSocketPool;
377 typedef CapturePreconnectsSocketPool<HttpProxyClientSocketPool>
378 CapturePreconnectsHttpProxySocketPool;
379 typedef CapturePreconnectsSocketPool<SOCKSClientSocketPool>
380 CapturePreconnectsSOCKSSocketPool;
381 typedef CapturePreconnectsSocketPool<SSLClientSocketPool>
382 CapturePreconnectsSSLSocketPool;
384 template<typename ParentPool>
385 CapturePreconnectsSocketPool<ParentPool>::CapturePreconnectsSocketPool(
386 HostResolver* host_resolver, CertVerifier* /* cert_verifier */)
387 : ParentPool(0, 0, nullptr, host_resolver, nullptr, nullptr),
388 last_num_streams_(-1) {}
390 template <>
391 CapturePreconnectsHttpProxySocketPool::CapturePreconnectsSocketPool(
392 HostResolver* /* host_resolver */,
393 CertVerifier* /* cert_verifier */)
394 : HttpProxyClientSocketPool(0, 0, nullptr, nullptr, nullptr, nullptr),
395 last_num_streams_(-1) {
398 template <>
399 CapturePreconnectsSSLSocketPool::CapturePreconnectsSocketPool(
400 HostResolver* /* host_resolver */,
401 CertVerifier* cert_verifier)
402 : SSLClientSocketPool(0,
404 nullptr, // ssl_histograms
405 cert_verifier,
406 nullptr, // channel_id_store
407 nullptr, // transport_security_state
408 nullptr, // cert_transparency_verifier
409 nullptr, // cert_policy_enforcer
410 std::string(), // ssl_session_cache_shard
411 nullptr, // deterministic_socket_factory
412 nullptr, // transport_socket_pool
413 nullptr,
414 nullptr,
415 nullptr, // ssl_config_service
416 false, // enable_ssl_connect_job_waiting
417 nullptr), // net_log
418 last_num_streams_(-1) {
421 class HttpStreamFactoryTest : public ::testing::Test,
422 public ::testing::WithParamInterface<NextProto> {
425 INSTANTIATE_TEST_CASE_P(
426 NextProto,
427 HttpStreamFactoryTest,
428 testing::Values(kProtoSPDY31, kProtoSPDY4_14, kProtoSPDY4_15));
430 TEST_P(HttpStreamFactoryTest, PreconnectDirect) {
431 for (size_t i = 0; i < arraysize(kTests); ++i) {
432 SpdySessionDependencies session_deps(
433 GetParam(), ProxyService::CreateDirect());
434 scoped_refptr<HttpNetworkSession> session(
435 SpdySessionDependencies::SpdyCreateSession(&session_deps));
436 HttpNetworkSessionPeer peer(session);
437 CapturePreconnectsTransportSocketPool* transport_conn_pool =
438 new CapturePreconnectsTransportSocketPool(
439 session_deps.host_resolver.get(),
440 session_deps.cert_verifier.get());
441 CapturePreconnectsSSLSocketPool* ssl_conn_pool =
442 new CapturePreconnectsSSLSocketPool(
443 session_deps.host_resolver.get(),
444 session_deps.cert_verifier.get());
445 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
446 new MockClientSocketPoolManager);
447 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
448 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
449 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
450 PreconnectHelper(kTests[i], session.get());
451 if (kTests[i].ssl)
452 EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams());
453 else
454 EXPECT_EQ(kTests[i].num_streams, transport_conn_pool->last_num_streams());
458 TEST_P(HttpStreamFactoryTest, PreconnectHttpProxy) {
459 for (size_t i = 0; i < arraysize(kTests); ++i) {
460 SpdySessionDependencies session_deps(
461 GetParam(), ProxyService::CreateFixed("http_proxy"));
462 scoped_refptr<HttpNetworkSession> session(
463 SpdySessionDependencies::SpdyCreateSession(&session_deps));
464 HttpNetworkSessionPeer peer(session);
465 HostPortPair proxy_host("http_proxy", 80);
466 CapturePreconnectsHttpProxySocketPool* http_proxy_pool =
467 new CapturePreconnectsHttpProxySocketPool(
468 session_deps.host_resolver.get(),
469 session_deps.cert_verifier.get());
470 CapturePreconnectsSSLSocketPool* ssl_conn_pool =
471 new CapturePreconnectsSSLSocketPool(
472 session_deps.host_resolver.get(),
473 session_deps.cert_verifier.get());
474 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
475 new MockClientSocketPoolManager);
476 mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
477 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
478 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
479 PreconnectHelper(kTests[i], session.get());
480 if (kTests[i].ssl)
481 EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams());
482 else
483 EXPECT_EQ(kTests[i].num_streams, http_proxy_pool->last_num_streams());
487 TEST_P(HttpStreamFactoryTest, PreconnectSocksProxy) {
488 for (size_t i = 0; i < arraysize(kTests); ++i) {
489 SpdySessionDependencies session_deps(
490 GetParam(), ProxyService::CreateFixed("socks4://socks_proxy:1080"));
491 scoped_refptr<HttpNetworkSession> session(
492 SpdySessionDependencies::SpdyCreateSession(&session_deps));
493 HttpNetworkSessionPeer peer(session);
494 HostPortPair proxy_host("socks_proxy", 1080);
495 CapturePreconnectsSOCKSSocketPool* socks_proxy_pool =
496 new CapturePreconnectsSOCKSSocketPool(
497 session_deps.host_resolver.get(),
498 session_deps.cert_verifier.get());
499 CapturePreconnectsSSLSocketPool* ssl_conn_pool =
500 new CapturePreconnectsSSLSocketPool(
501 session_deps.host_resolver.get(),
502 session_deps.cert_verifier.get());
503 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
504 new MockClientSocketPoolManager);
505 mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_proxy_pool);
506 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
507 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
508 PreconnectHelper(kTests[i], session.get());
509 if (kTests[i].ssl)
510 EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams());
511 else
512 EXPECT_EQ(kTests[i].num_streams, socks_proxy_pool->last_num_streams());
516 TEST_P(HttpStreamFactoryTest, PreconnectDirectWithExistingSpdySession) {
517 for (size_t i = 0; i < arraysize(kTests); ++i) {
518 SpdySessionDependencies session_deps(
519 GetParam(), ProxyService::CreateDirect());
520 scoped_refptr<HttpNetworkSession> session(
521 SpdySessionDependencies::SpdyCreateSession(&session_deps));
522 HttpNetworkSessionPeer peer(session);
524 // Put a SpdySession in the pool.
525 HostPortPair host_port_pair("www.google.com", 443);
526 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
527 PRIVACY_MODE_DISABLED);
528 ignore_result(CreateFakeSpdySession(session->spdy_session_pool(), key));
530 CapturePreconnectsTransportSocketPool* transport_conn_pool =
531 new CapturePreconnectsTransportSocketPool(
532 session_deps.host_resolver.get(),
533 session_deps.cert_verifier.get());
534 CapturePreconnectsSSLSocketPool* ssl_conn_pool =
535 new CapturePreconnectsSSLSocketPool(
536 session_deps.host_resolver.get(),
537 session_deps.cert_verifier.get());
538 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
539 new MockClientSocketPoolManager);
540 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
541 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
542 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
543 PreconnectHelper(kTests[i], session.get());
544 // We shouldn't be preconnecting if we have an existing session, which is
545 // the case for https://www.google.com.
546 if (kTests[i].ssl)
547 EXPECT_EQ(-1, ssl_conn_pool->last_num_streams());
548 else
549 EXPECT_EQ(kTests[i].num_streams,
550 transport_conn_pool->last_num_streams());
554 // Verify that preconnects to unsafe ports are cancelled before they reach
555 // the SocketPool.
556 TEST_P(HttpStreamFactoryTest, PreconnectUnsafePort) {
557 ASSERT_FALSE(IsPortAllowedByDefault(7));
558 ASSERT_FALSE(IsPortAllowedByOverride(7));
560 SpdySessionDependencies session_deps(
561 GetParam(), ProxyService::CreateDirect());
562 scoped_refptr<HttpNetworkSession> session(
563 SpdySessionDependencies::SpdyCreateSession(&session_deps));
564 HttpNetworkSessionPeer peer(session);
565 CapturePreconnectsTransportSocketPool* transport_conn_pool =
566 new CapturePreconnectsTransportSocketPool(
567 session_deps.host_resolver.get(),
568 session_deps.cert_verifier.get());
569 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
570 new MockClientSocketPoolManager);
571 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
572 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
574 PreconnectHelperForURL(1, GURL("http://www.google.com:7"), session.get());
576 EXPECT_EQ(-1, transport_conn_pool->last_num_streams());
579 TEST_P(HttpStreamFactoryTest, JobNotifiesProxy) {
580 const char* kProxyString = "PROXY bad:99; PROXY maybe:80; DIRECT";
581 SpdySessionDependencies session_deps(
582 GetParam(), ProxyService::CreateFixedFromPacResult(kProxyString));
584 // First connection attempt fails
585 StaticSocketDataProvider socket_data1;
586 socket_data1.set_connect_data(MockConnect(ASYNC, ERR_ADDRESS_UNREACHABLE));
587 session_deps.socket_factory->AddSocketDataProvider(&socket_data1);
589 // Second connection attempt succeeds
590 StaticSocketDataProvider socket_data2;
591 socket_data2.set_connect_data(MockConnect(ASYNC, OK));
592 session_deps.socket_factory->AddSocketDataProvider(&socket_data2);
594 scoped_refptr<HttpNetworkSession> session(
595 SpdySessionDependencies::SpdyCreateSession(&session_deps));
597 // Now request a stream. It should succeed using the second proxy in the
598 // list.
599 HttpRequestInfo request_info;
600 request_info.method = "GET";
601 request_info.url = GURL("http://www.google.com");
603 SSLConfig ssl_config;
604 StreamRequestWaiter waiter;
605 scoped_ptr<HttpStreamRequest> request(
606 session->http_stream_factory()->RequestStream(
607 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config,
608 &waiter, BoundNetLog()));
609 waiter.WaitForStream();
611 // The proxy that failed should now be known to the proxy_service as bad.
612 const ProxyRetryInfoMap& retry_info =
613 session->proxy_service()->proxy_retry_info();
614 EXPECT_EQ(1u, retry_info.size());
615 ProxyRetryInfoMap::const_iterator iter = retry_info.find("bad:99");
616 EXPECT_TRUE(iter != retry_info.end());
619 TEST_P(HttpStreamFactoryTest, PrivacyModeDisablesChannelId) {
620 SpdySessionDependencies session_deps(
621 GetParam(), ProxyService::CreateDirect());
623 StaticSocketDataProvider socket_data;
624 socket_data.set_connect_data(MockConnect(ASYNC, OK));
625 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
627 SSLSocketDataProvider ssl(ASYNC, OK);
628 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
630 scoped_refptr<HttpNetworkSession> session(
631 SpdySessionDependencies::SpdyCreateSession(&session_deps));
633 // Set an existing SpdySession in the pool.
634 HostPortPair host_port_pair("www.google.com", 443);
635 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
636 PRIVACY_MODE_ENABLED);
638 HttpRequestInfo request_info;
639 request_info.method = "GET";
640 request_info.url = GURL("https://www.google.com");
641 request_info.load_flags = 0;
642 request_info.privacy_mode = PRIVACY_MODE_DISABLED;
644 SSLConfig ssl_config;
645 StreamRequestWaiter waiter;
646 scoped_ptr<HttpStreamRequest> request(
647 session->http_stream_factory()->RequestStream(
648 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config,
649 &waiter, BoundNetLog()));
650 waiter.WaitForStream();
652 // The stream shouldn't come from spdy as we are using different privacy mode
653 EXPECT_FALSE(request->using_spdy());
655 SSLConfig used_ssl_config = waiter.used_ssl_config();
656 EXPECT_EQ(used_ssl_config.channel_id_enabled, ssl_config.channel_id_enabled);
659 namespace {
660 // Return count of distinct groups in given socket pool.
661 int GetSocketPoolGroupCount(ClientSocketPool* pool) {
662 int count = 0;
663 scoped_ptr<base::DictionaryValue> dict(pool->GetInfoAsValue("", "", false));
664 EXPECT_TRUE(dict != nullptr);
665 base::DictionaryValue* groups = nullptr;
666 if (dict->GetDictionary("groups", &groups) && (groups != nullptr)) {
667 count = static_cast<int>(groups->size());
669 return count;
671 } // namespace
673 TEST_P(HttpStreamFactoryTest, PrivacyModeUsesDifferentSocketPoolGroup) {
674 SpdySessionDependencies session_deps(
675 GetParam(), ProxyService::CreateDirect());
677 StaticSocketDataProvider socket_data;
678 socket_data.set_connect_data(MockConnect(ASYNC, OK));
679 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
681 SSLSocketDataProvider ssl(ASYNC, OK);
682 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
684 scoped_refptr<HttpNetworkSession> session(
685 SpdySessionDependencies::SpdyCreateSession(&session_deps));
686 SSLClientSocketPool* ssl_pool = session->GetSSLSocketPool(
687 HttpNetworkSession::NORMAL_SOCKET_POOL);
689 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 0);
691 HttpRequestInfo request_info;
692 request_info.method = "GET";
693 request_info.url = GURL("https://www.google.com");
694 request_info.load_flags = 0;
695 request_info.privacy_mode = PRIVACY_MODE_DISABLED;
697 SSLConfig ssl_config;
698 StreamRequestWaiter waiter;
700 scoped_ptr<HttpStreamRequest> request1(
701 session->http_stream_factory()->RequestStream(
702 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config,
703 &waiter, BoundNetLog()));
704 waiter.WaitForStream();
706 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 1);
708 scoped_ptr<HttpStreamRequest> request2(
709 session->http_stream_factory()->RequestStream(
710 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config,
711 &waiter, BoundNetLog()));
712 waiter.WaitForStream();
714 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 1);
716 request_info.privacy_mode = PRIVACY_MODE_ENABLED;
717 scoped_ptr<HttpStreamRequest> request3(
718 session->http_stream_factory()->RequestStream(
719 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config,
720 &waiter, BoundNetLog()));
721 waiter.WaitForStream();
723 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 2);
726 TEST_P(HttpStreamFactoryTest, GetLoadState) {
727 SpdySessionDependencies session_deps(
728 GetParam(), ProxyService::CreateDirect());
730 StaticSocketDataProvider socket_data;
731 socket_data.set_connect_data(MockConnect(ASYNC, OK));
732 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
734 scoped_refptr<HttpNetworkSession> session(
735 SpdySessionDependencies::SpdyCreateSession(&session_deps));
737 HttpRequestInfo request_info;
738 request_info.method = "GET";
739 request_info.url = GURL("http://www.google.com");
741 SSLConfig ssl_config;
742 StreamRequestWaiter waiter;
743 scoped_ptr<HttpStreamRequest> request(
744 session->http_stream_factory()->RequestStream(
745 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config,
746 &waiter, BoundNetLog()));
748 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, request->GetLoadState());
750 waiter.WaitForStream();
753 TEST_P(HttpStreamFactoryTest, RequestHttpStream) {
754 SpdySessionDependencies session_deps(
755 GetParam(), ProxyService::CreateDirect());
757 StaticSocketDataProvider socket_data;
758 socket_data.set_connect_data(MockConnect(ASYNC, OK));
759 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
761 scoped_refptr<HttpNetworkSession> session(
762 SpdySessionDependencies::SpdyCreateSession(&session_deps));
764 // Now request a stream. It should succeed using the second proxy in the
765 // list.
766 HttpRequestInfo request_info;
767 request_info.method = "GET";
768 request_info.url = GURL("http://www.google.com");
769 request_info.load_flags = 0;
771 SSLConfig ssl_config;
772 StreamRequestWaiter waiter;
773 scoped_ptr<HttpStreamRequest> request(
774 session->http_stream_factory()->RequestStream(
775 request_info,
776 DEFAULT_PRIORITY,
777 ssl_config,
778 ssl_config,
779 &waiter,
780 BoundNetLog()));
781 waiter.WaitForStream();
782 EXPECT_TRUE(waiter.stream_done());
783 ASSERT_TRUE(nullptr != waiter.stream());
784 EXPECT_TRUE(nullptr == waiter.websocket_stream());
785 EXPECT_FALSE(waiter.stream()->IsSpdyHttpStream());
787 EXPECT_EQ(1, GetSocketPoolGroupCount(
788 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
789 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool(
790 HttpNetworkSession::NORMAL_SOCKET_POOL)));
791 EXPECT_EQ(0, GetSocketPoolGroupCount(
792 session->GetTransportSocketPool(
793 HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
794 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool(
795 HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
796 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
799 TEST_P(HttpStreamFactoryTest, RequestHttpStreamOverSSL) {
800 SpdySessionDependencies session_deps(
801 GetParam(), ProxyService::CreateDirect());
803 MockRead mock_read(ASYNC, OK);
804 StaticSocketDataProvider socket_data(&mock_read, 1, nullptr, 0);
805 socket_data.set_connect_data(MockConnect(ASYNC, OK));
806 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
808 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
809 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
811 scoped_refptr<HttpNetworkSession> session(
812 SpdySessionDependencies::SpdyCreateSession(&session_deps));
814 // Now request a stream.
815 HttpRequestInfo request_info;
816 request_info.method = "GET";
817 request_info.url = GURL("https://www.google.com");
818 request_info.load_flags = 0;
820 SSLConfig ssl_config;
821 StreamRequestWaiter waiter;
822 scoped_ptr<HttpStreamRequest> request(
823 session->http_stream_factory()->RequestStream(
824 request_info,
825 DEFAULT_PRIORITY,
826 ssl_config,
827 ssl_config,
828 &waiter,
829 BoundNetLog()));
830 waiter.WaitForStream();
831 EXPECT_TRUE(waiter.stream_done());
832 ASSERT_TRUE(nullptr != waiter.stream());
833 EXPECT_TRUE(nullptr == waiter.websocket_stream());
834 EXPECT_FALSE(waiter.stream()->IsSpdyHttpStream());
835 EXPECT_EQ(1, GetSocketPoolGroupCount(
836 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
837 EXPECT_EQ(1, GetSocketPoolGroupCount(
838 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
839 EXPECT_EQ(0, GetSocketPoolGroupCount(
840 session->GetTransportSocketPool(
841 HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
842 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool(
843 HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
844 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
847 TEST_P(HttpStreamFactoryTest, RequestHttpStreamOverProxy) {
848 SpdySessionDependencies session_deps(
849 GetParam(), ProxyService::CreateFixed("myproxy:8888"));
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 // Now request a stream. It should succeed using the second proxy in the
859 // list.
860 HttpRequestInfo request_info;
861 request_info.method = "GET";
862 request_info.url = GURL("http://www.google.com");
863 request_info.load_flags = 0;
865 SSLConfig ssl_config;
866 StreamRequestWaiter waiter;
867 scoped_ptr<HttpStreamRequest> request(
868 session->http_stream_factory()->RequestStream(
869 request_info,
870 DEFAULT_PRIORITY,
871 ssl_config,
872 ssl_config,
873 &waiter,
874 BoundNetLog()));
875 waiter.WaitForStream();
876 EXPECT_TRUE(waiter.stream_done());
877 ASSERT_TRUE(nullptr != waiter.stream());
878 EXPECT_TRUE(nullptr == waiter.websocket_stream());
879 EXPECT_FALSE(waiter.stream()->IsSpdyHttpStream());
880 EXPECT_EQ(0, GetSocketPoolGroupCount(
881 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
882 EXPECT_EQ(0, GetSocketPoolGroupCount(
883 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
884 EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSocketPoolForHTTPProxy(
885 HttpNetworkSession::NORMAL_SOCKET_POOL,
886 HostPortPair("myproxy", 8888))));
887 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForSSLWithProxy(
888 HttpNetworkSession::NORMAL_SOCKET_POOL,
889 HostPortPair("myproxy", 8888))));
890 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForHTTPProxy(
891 HttpNetworkSession::WEBSOCKET_SOCKET_POOL,
892 HostPortPair("myproxy", 8888))));
893 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForSSLWithProxy(
894 HttpNetworkSession::WEBSOCKET_SOCKET_POOL,
895 HostPortPair("myproxy", 8888))));
896 EXPECT_FALSE(waiter.used_proxy_info().is_direct());
899 TEST_P(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStream) {
900 SpdySessionDependencies session_deps(
901 GetParam(), ProxyService::CreateDirect());
903 StaticSocketDataProvider socket_data;
904 socket_data.set_connect_data(MockConnect(ASYNC, OK));
905 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
907 scoped_refptr<HttpNetworkSession> session(
908 SpdySessionDependencies::SpdyCreateSession(&session_deps));
910 // Now request a stream.
911 HttpRequestInfo request_info;
912 request_info.method = "GET";
913 request_info.url = GURL("ws://www.google.com");
914 request_info.load_flags = 0;
916 SSLConfig ssl_config;
917 StreamRequestWaiter waiter;
918 WebSocketStreamCreateHelper create_helper;
919 scoped_ptr<HttpStreamRequest> request(
920 session->http_stream_factory_for_websocket()
921 ->RequestWebSocketHandshakeStream(request_info,
922 DEFAULT_PRIORITY,
923 ssl_config,
924 ssl_config,
925 &waiter,
926 &create_helper,
927 BoundNetLog()));
928 waiter.WaitForStream();
929 EXPECT_TRUE(waiter.stream_done());
930 EXPECT_TRUE(nullptr == waiter.stream());
931 ASSERT_TRUE(nullptr != waiter.websocket_stream());
932 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic,
933 waiter.websocket_stream()->type());
934 EXPECT_EQ(0, GetSocketPoolGroupCount(
935 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
936 EXPECT_EQ(0, GetSocketPoolGroupCount(
937 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
938 EXPECT_EQ(0, GetSocketPoolGroupCount(
939 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
940 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
943 TEST_P(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStreamOverSSL) {
944 SpdySessionDependencies session_deps(
945 GetParam(), ProxyService::CreateDirect());
947 MockRead mock_read(ASYNC, OK);
948 StaticSocketDataProvider socket_data(&mock_read, 1, nullptr, 0);
949 socket_data.set_connect_data(MockConnect(ASYNC, OK));
950 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
952 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
953 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
955 scoped_refptr<HttpNetworkSession> session(
956 SpdySessionDependencies::SpdyCreateSession(&session_deps));
958 // Now request a stream.
959 HttpRequestInfo request_info;
960 request_info.method = "GET";
961 request_info.url = GURL("wss://www.google.com");
962 request_info.load_flags = 0;
964 SSLConfig ssl_config;
965 StreamRequestWaiter waiter;
966 WebSocketStreamCreateHelper create_helper;
967 scoped_ptr<HttpStreamRequest> request(
968 session->http_stream_factory_for_websocket()
969 ->RequestWebSocketHandshakeStream(request_info,
970 DEFAULT_PRIORITY,
971 ssl_config,
972 ssl_config,
973 &waiter,
974 &create_helper,
975 BoundNetLog()));
976 waiter.WaitForStream();
977 EXPECT_TRUE(waiter.stream_done());
978 EXPECT_TRUE(nullptr == waiter.stream());
979 ASSERT_TRUE(nullptr != waiter.websocket_stream());
980 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic,
981 waiter.websocket_stream()->type());
982 EXPECT_EQ(0, GetSocketPoolGroupCount(
983 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
984 EXPECT_EQ(0, GetSocketPoolGroupCount(
985 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
986 EXPECT_EQ(1, GetSocketPoolGroupCount(
987 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
988 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
991 TEST_P(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStreamOverProxy) {
992 SpdySessionDependencies session_deps(
993 GetParam(), ProxyService::CreateFixed("myproxy:8888"));
995 MockRead read(SYNCHRONOUS, "HTTP/1.0 200 Connection established\r\n\r\n");
996 StaticSocketDataProvider socket_data(&read, 1, 0, 0);
997 socket_data.set_connect_data(MockConnect(ASYNC, OK));
998 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
1000 scoped_refptr<HttpNetworkSession> session(
1001 SpdySessionDependencies::SpdyCreateSession(&session_deps));
1003 // Now request a stream.
1004 HttpRequestInfo request_info;
1005 request_info.method = "GET";
1006 request_info.url = GURL("ws://www.google.com");
1007 request_info.load_flags = 0;
1009 SSLConfig ssl_config;
1010 StreamRequestWaiter waiter;
1011 WebSocketStreamCreateHelper create_helper;
1012 scoped_ptr<HttpStreamRequest> request(
1013 session->http_stream_factory_for_websocket()
1014 ->RequestWebSocketHandshakeStream(request_info,
1015 DEFAULT_PRIORITY,
1016 ssl_config,
1017 ssl_config,
1018 &waiter,
1019 &create_helper,
1020 BoundNetLog()));
1021 waiter.WaitForStream();
1022 EXPECT_TRUE(waiter.stream_done());
1023 EXPECT_TRUE(nullptr == waiter.stream());
1024 ASSERT_TRUE(nullptr != waiter.websocket_stream());
1025 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic,
1026 waiter.websocket_stream()->type());
1027 EXPECT_EQ(0, GetSocketPoolGroupCount(
1028 session->GetTransportSocketPool(
1029 HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1030 EXPECT_EQ(0, GetSocketPoolGroupCount(
1031 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1032 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForHTTPProxy(
1033 HttpNetworkSession::NORMAL_SOCKET_POOL,
1034 HostPortPair("myproxy", 8888))));
1035 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForSSLWithProxy(
1036 HttpNetworkSession::NORMAL_SOCKET_POOL,
1037 HostPortPair("myproxy", 8888))));
1038 EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSocketPoolForHTTPProxy(
1039 HttpNetworkSession::WEBSOCKET_SOCKET_POOL,
1040 HostPortPair("myproxy", 8888))));
1041 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForSSLWithProxy(
1042 HttpNetworkSession::WEBSOCKET_SOCKET_POOL,
1043 HostPortPair("myproxy", 8888))));
1044 EXPECT_FALSE(waiter.used_proxy_info().is_direct());
1047 TEST_P(HttpStreamFactoryTest, RequestSpdyHttpStream) {
1048 SpdySessionDependencies session_deps(GetParam(),
1049 ProxyService::CreateDirect());
1051 MockRead mock_read(ASYNC, OK);
1052 DeterministicSocketData socket_data(&mock_read, 1, nullptr, 0);
1053 socket_data.set_connect_data(MockConnect(ASYNC, OK));
1054 session_deps.deterministic_socket_factory->AddSocketDataProvider(
1055 &socket_data);
1057 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
1058 ssl_socket_data.SetNextProto(GetParam());
1059 session_deps.deterministic_socket_factory->AddSSLSocketDataProvider(
1060 &ssl_socket_data);
1062 HostPortPair host_port_pair("www.google.com", 443);
1063 scoped_refptr<HttpNetworkSession>
1064 session(SpdySessionDependencies::SpdyCreateSessionDeterministic(
1065 &session_deps));
1067 // Now request a stream.
1068 HttpRequestInfo request_info;
1069 request_info.method = "GET";
1070 request_info.url = GURL("https://www.google.com");
1071 request_info.load_flags = 0;
1073 SSLConfig ssl_config;
1074 StreamRequestWaiter waiter;
1075 scoped_ptr<HttpStreamRequest> request(
1076 session->http_stream_factory()->RequestStream(
1077 request_info,
1078 DEFAULT_PRIORITY,
1079 ssl_config,
1080 ssl_config,
1081 &waiter,
1082 BoundNetLog()));
1083 waiter.WaitForStream();
1084 EXPECT_TRUE(waiter.stream_done());
1085 EXPECT_TRUE(nullptr == waiter.websocket_stream());
1086 ASSERT_TRUE(nullptr != waiter.stream());
1087 EXPECT_TRUE(waiter.stream()->IsSpdyHttpStream());
1088 EXPECT_EQ(1, GetSocketPoolGroupCount(
1089 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1090 EXPECT_EQ(1, GetSocketPoolGroupCount(
1091 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1092 EXPECT_EQ(0, GetSocketPoolGroupCount(
1093 session->GetTransportSocketPool(
1094 HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1095 EXPECT_EQ(0, GetSocketPoolGroupCount(
1096 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1097 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
1100 // TODO(ricea): This test can be removed once the new WebSocket stack supports
1101 // SPDY. Currently, even if we connect to a SPDY-supporting server, we need to
1102 // use plain SSL.
1103 TEST_P(HttpStreamFactoryTest, RequestWebSocketSpdyHandshakeStreamButGetSSL) {
1104 SpdySessionDependencies session_deps(GetParam(),
1105 ProxyService::CreateDirect());
1107 MockRead mock_read(SYNCHRONOUS, ERR_IO_PENDING);
1108 StaticSocketDataProvider socket_data(&mock_read, 1, nullptr, 0);
1109 socket_data.set_connect_data(MockConnect(ASYNC, OK));
1110 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
1112 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
1113 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
1115 HostPortPair host_port_pair("www.google.com", 80);
1116 scoped_refptr<HttpNetworkSession>
1117 session(SpdySessionDependencies::SpdyCreateSession(&session_deps));
1119 // Now request a stream.
1120 HttpRequestInfo request_info;
1121 request_info.method = "GET";
1122 request_info.url = GURL("wss://www.google.com");
1123 request_info.load_flags = 0;
1125 SSLConfig ssl_config;
1126 StreamRequestWaiter waiter1;
1127 WebSocketStreamCreateHelper create_helper;
1128 scoped_ptr<HttpStreamRequest> request1(
1129 session->http_stream_factory_for_websocket()
1130 ->RequestWebSocketHandshakeStream(request_info,
1131 DEFAULT_PRIORITY,
1132 ssl_config,
1133 ssl_config,
1134 &waiter1,
1135 &create_helper,
1136 BoundNetLog()));
1137 waiter1.WaitForStream();
1138 EXPECT_TRUE(waiter1.stream_done());
1139 ASSERT_TRUE(nullptr != waiter1.websocket_stream());
1140 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic,
1141 waiter1.websocket_stream()->type());
1142 EXPECT_TRUE(nullptr == waiter1.stream());
1144 EXPECT_EQ(0, GetSocketPoolGroupCount(
1145 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1146 EXPECT_EQ(0, GetSocketPoolGroupCount(
1147 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1148 EXPECT_EQ(1, GetSocketPoolGroupCount(
1149 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1150 EXPECT_TRUE(waiter1.used_proxy_info().is_direct());
1153 // TODO(ricea): Re-enable once WebSocket-over-SPDY is implemented.
1154 TEST_P(HttpStreamFactoryTest, DISABLED_RequestWebSocketSpdyHandshakeStream) {
1155 SpdySessionDependencies session_deps(GetParam(),
1156 ProxyService::CreateDirect());
1158 MockRead mock_read(SYNCHRONOUS, ERR_IO_PENDING);
1159 StaticSocketDataProvider socket_data(&mock_read, 1, nullptr, 0);
1160 socket_data.set_connect_data(MockConnect(ASYNC, OK));
1161 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
1163 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
1164 ssl_socket_data.SetNextProto(GetParam());
1165 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
1167 HostPortPair host_port_pair("www.google.com", 80);
1168 scoped_refptr<HttpNetworkSession>
1169 session(SpdySessionDependencies::SpdyCreateSession(&session_deps));
1171 // Now request a stream.
1172 HttpRequestInfo request_info;
1173 request_info.method = "GET";
1174 request_info.url = GURL("wss://www.google.com");
1175 request_info.load_flags = 0;
1177 SSLConfig ssl_config;
1178 StreamRequestWaiter waiter1;
1179 WebSocketStreamCreateHelper create_helper;
1180 scoped_ptr<HttpStreamRequest> request1(
1181 session->http_stream_factory_for_websocket()
1182 ->RequestWebSocketHandshakeStream(request_info,
1183 DEFAULT_PRIORITY,
1184 ssl_config,
1185 ssl_config,
1186 &waiter1,
1187 &create_helper,
1188 BoundNetLog()));
1189 waiter1.WaitForStream();
1190 EXPECT_TRUE(waiter1.stream_done());
1191 ASSERT_TRUE(nullptr != waiter1.websocket_stream());
1192 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy,
1193 waiter1.websocket_stream()->type());
1194 EXPECT_TRUE(nullptr == waiter1.stream());
1196 StreamRequestWaiter waiter2;
1197 scoped_ptr<HttpStreamRequest> request2(
1198 session->http_stream_factory_for_websocket()
1199 ->RequestWebSocketHandshakeStream(request_info,
1200 DEFAULT_PRIORITY,
1201 ssl_config,
1202 ssl_config,
1203 &waiter2,
1204 &create_helper,
1205 BoundNetLog()));
1206 waiter2.WaitForStream();
1207 EXPECT_TRUE(waiter2.stream_done());
1208 ASSERT_TRUE(nullptr != waiter2.websocket_stream());
1209 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy,
1210 waiter2.websocket_stream()->type());
1211 EXPECT_TRUE(nullptr == waiter2.stream());
1212 EXPECT_NE(waiter2.websocket_stream(), waiter1.websocket_stream());
1213 EXPECT_EQ(static_cast<WebSocketSpdyHandshakeStream*>(
1214 waiter2.websocket_stream())->spdy_session(),
1215 static_cast<WebSocketSpdyHandshakeStream*>(
1216 waiter1.websocket_stream())->spdy_session());
1218 EXPECT_EQ(0, GetSocketPoolGroupCount(
1219 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1220 EXPECT_EQ(0, GetSocketPoolGroupCount(
1221 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1222 EXPECT_EQ(1, GetSocketPoolGroupCount(
1223 session->GetTransportSocketPool(
1224 HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1225 EXPECT_EQ(1, GetSocketPoolGroupCount(
1226 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1227 EXPECT_TRUE(waiter1.used_proxy_info().is_direct());
1230 // TODO(ricea): Re-enable once WebSocket over SPDY is implemented.
1231 TEST_P(HttpStreamFactoryTest, DISABLED_OrphanedWebSocketStream) {
1232 SpdySessionDependencies session_deps(GetParam(),
1233 ProxyService::CreateDirect());
1234 session_deps.use_alternate_protocols = true;
1236 MockRead mock_read(ASYNC, OK);
1237 DeterministicSocketData socket_data(&mock_read, 1, nullptr, 0);
1238 socket_data.set_connect_data(MockConnect(ASYNC, OK));
1239 session_deps.deterministic_socket_factory->AddSocketDataProvider(
1240 &socket_data);
1242 MockRead mock_read2(ASYNC, OK);
1243 DeterministicSocketData socket_data2(&mock_read2, 1, nullptr, 0);
1244 socket_data2.set_connect_data(MockConnect(ASYNC, ERR_IO_PENDING));
1245 session_deps.deterministic_socket_factory->AddSocketDataProvider(
1246 &socket_data2);
1248 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
1249 ssl_socket_data.SetNextProto(GetParam());
1250 session_deps.deterministic_socket_factory->AddSSLSocketDataProvider(
1251 &ssl_socket_data);
1253 scoped_refptr<HttpNetworkSession>
1254 session(SpdySessionDependencies::SpdyCreateSessionDeterministic(
1255 &session_deps));
1257 // Now request a stream.
1258 HttpRequestInfo request_info;
1259 request_info.method = "GET";
1260 request_info.url = GURL("ws://www.google.com:8888");
1261 request_info.load_flags = 0;
1263 session->http_server_properties()->SetAlternateProtocol(
1264 HostPortPair("www.google.com", 8888), 9999, NPN_SPDY_3, 1.0);
1266 SSLConfig ssl_config;
1267 StreamRequestWaiter waiter;
1268 WebSocketStreamCreateHelper create_helper;
1269 scoped_ptr<HttpStreamRequest> request(
1270 session->http_stream_factory_for_websocket()
1271 ->RequestWebSocketHandshakeStream(request_info,
1272 DEFAULT_PRIORITY,
1273 ssl_config,
1274 ssl_config,
1275 &waiter,
1276 &create_helper,
1277 BoundNetLog()));
1278 waiter.WaitForStream();
1279 EXPECT_TRUE(waiter.stream_done());
1280 EXPECT_TRUE(nullptr == waiter.stream());
1281 ASSERT_TRUE(nullptr != waiter.websocket_stream());
1282 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy,
1283 waiter.websocket_stream()->type());
1285 // Make sure that there was an alternative connection
1286 // which consumes extra connections.
1287 EXPECT_EQ(0, GetSocketPoolGroupCount(
1288 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1289 EXPECT_EQ(0, GetSocketPoolGroupCount(
1290 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1291 EXPECT_EQ(2, GetSocketPoolGroupCount(
1292 session->GetTransportSocketPool(
1293 HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1294 EXPECT_EQ(1, GetSocketPoolGroupCount(
1295 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1296 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
1298 // Make sure there is no orphaned job. it is already canceled.
1299 ASSERT_EQ(0u, static_cast<HttpStreamFactoryImpl*>(
1300 session->http_stream_factory_for_websocket())->num_orphaned_jobs());
1303 } // namespace
1305 } // namespace net