Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / net / http / http_stream_factory_impl_unittest.cc
blob0f261a9792bd55fe180386a10485716dc9cf8a45
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 virtual ~MockWebSocketHandshakeStream() {}
57 StreamType type() const {
58 return type_;
61 // HttpStreamBase methods
62 virtual 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 virtual int SendRequest(const HttpRequestHeaders& request_headers,
69 HttpResponseInfo* response,
70 const CompletionCallback& callback) OVERRIDE {
71 return ERR_IO_PENDING;
73 virtual int ReadResponseHeaders(const CompletionCallback& callback) OVERRIDE {
74 return ERR_IO_PENDING;
76 virtual int ReadResponseBody(IOBuffer* buf,
77 int buf_len,
78 const CompletionCallback& callback) OVERRIDE {
79 return ERR_IO_PENDING;
81 virtual void Close(bool not_reusable) OVERRIDE {}
82 virtual bool IsResponseBodyComplete() const OVERRIDE { return false; }
83 virtual bool CanFindEndOfResponse() const OVERRIDE { return false; }
84 virtual bool IsConnectionReused() const OVERRIDE { return false; }
85 virtual void SetConnectionReused() OVERRIDE {}
86 virtual bool IsConnectionReusable() const OVERRIDE { return false; }
87 virtual int64 GetTotalReceivedBytes() const OVERRIDE { return 0; }
88 virtual bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const
89 OVERRIDE {
90 return false;
92 virtual void GetSSLInfo(SSLInfo* ssl_info) OVERRIDE {}
93 virtual void GetSSLCertRequestInfo(
94 SSLCertRequestInfo* cert_request_info) OVERRIDE {}
95 virtual bool IsSpdyHttpStream() const OVERRIDE { return false; }
96 virtual void Drain(HttpNetworkSession* session) OVERRIDE {}
97 virtual void SetPriority(RequestPriority priority) OVERRIDE {}
99 virtual 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 virtual 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 virtual void OnStreamReady(
146 const SSLConfig& used_ssl_config,
147 const ProxyInfo& used_proxy_info,
148 HttpStreamBase* stream) OVERRIDE {
149 stream_done_ = true;
150 if (waiting_for_stream_)
151 base::MessageLoop::current()->Quit();
152 stream_.reset(stream);
153 used_ssl_config_ = used_ssl_config;
154 used_proxy_info_ = used_proxy_info;
157 virtual void OnWebSocketHandshakeStreamReady(
158 const SSLConfig& used_ssl_config,
159 const ProxyInfo& used_proxy_info,
160 WebSocketHandshakeStreamBase* stream) OVERRIDE {
161 stream_done_ = true;
162 if (waiting_for_stream_)
163 base::MessageLoop::current()->Quit();
164 websocket_stream_.reset(stream);
165 used_ssl_config_ = used_ssl_config;
166 used_proxy_info_ = used_proxy_info;
169 virtual void OnStreamFailed(
170 int status,
171 const SSLConfig& used_ssl_config) OVERRIDE {}
173 virtual void OnCertificateError(
174 int status,
175 const SSLConfig& used_ssl_config,
176 const SSLInfo& ssl_info) OVERRIDE {}
178 virtual void OnNeedsProxyAuth(const HttpResponseInfo& proxy_response,
179 const SSLConfig& used_ssl_config,
180 const ProxyInfo& used_proxy_info,
181 HttpAuthController* auth_controller) OVERRIDE {}
183 virtual void OnNeedsClientAuth(const SSLConfig& used_ssl_config,
184 SSLCertRequestInfo* cert_info) OVERRIDE {}
186 virtual void OnHttpsProxyTunnelResponse(const HttpResponseInfo& response_info,
187 const SSLConfig& used_ssl_config,
188 const ProxyInfo& used_proxy_info,
189 HttpStreamBase* 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 HttpStreamBase* 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<HttpStreamBase> 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 virtual ~WebSocketSpdyHandshakeStream() {}
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 virtual ~WebSocketBasicHandshakeStream() {
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 virtual ~WebSocketStreamCreateHelper() {}
265 virtual WebSocketHandshakeStreamBase* CreateBasicStream(
266 scoped_ptr<ClientSocketHandle> connection,
267 bool using_proxy) OVERRIDE {
268 return new WebSocketBasicHandshakeStream(connection.Pass());
271 virtual 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(
306 num_streams, request, DEFAULT_PRIORITY, 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 virtual 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 virtual 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 virtual void CancelRequest(const std::string& group_name,
345 ClientSocketHandle* handle) OVERRIDE {
346 ADD_FAILURE();
348 virtual void ReleaseSocket(const std::string& group_name,
349 scoped_ptr<StreamSocket> socket,
350 int id) OVERRIDE {
351 ADD_FAILURE();
353 virtual void CloseIdleSockets() OVERRIDE {
354 ADD_FAILURE();
356 virtual int IdleSocketCount() const OVERRIDE {
357 ADD_FAILURE();
358 return 0;
360 virtual int IdleSocketCountInGroup(
361 const std::string& group_name) const OVERRIDE {
362 ADD_FAILURE();
363 return 0;
365 virtual LoadState GetLoadState(
366 const std::string& group_name,
367 const ClientSocketHandle* handle) const OVERRIDE {
368 ADD_FAILURE();
369 return LOAD_STATE_IDLE;
371 virtual base::TimeDelta ConnectionTimeout() const OVERRIDE {
372 return base::TimeDelta();
375 private:
376 int last_num_streams_;
379 typedef CapturePreconnectsSocketPool<TransportClientSocketPool>
380 CapturePreconnectsTransportSocketPool;
381 typedef CapturePreconnectsSocketPool<HttpProxyClientSocketPool>
382 CapturePreconnectsHttpProxySocketPool;
383 typedef CapturePreconnectsSocketPool<SOCKSClientSocketPool>
384 CapturePreconnectsSOCKSSocketPool;
385 typedef CapturePreconnectsSocketPool<SSLClientSocketPool>
386 CapturePreconnectsSSLSocketPool;
388 template<typename ParentPool>
389 CapturePreconnectsSocketPool<ParentPool>::CapturePreconnectsSocketPool(
390 HostResolver* host_resolver, CertVerifier* /* cert_verifier */)
391 : ParentPool(0, 0, NULL, host_resolver, NULL, NULL),
392 last_num_streams_(-1) {}
394 template<>
395 CapturePreconnectsHttpProxySocketPool::CapturePreconnectsSocketPool(
396 HostResolver* host_resolver, CertVerifier* /* cert_verifier */)
397 : HttpProxyClientSocketPool(0, 0, NULL, host_resolver, NULL, NULL, NULL),
398 last_num_streams_(-1) {}
400 template <>
401 CapturePreconnectsSSLSocketPool::CapturePreconnectsSocketPool(
402 HostResolver* host_resolver,
403 CertVerifier* cert_verifier)
404 : SSLClientSocketPool(0,
406 NULL, // ssl_histograms
407 host_resolver,
408 cert_verifier,
409 NULL, // channel_id_store
410 NULL, // transport_security_state
411 NULL, // cert_transparency_verifier
412 std::string(), // ssl_session_cache_shard
413 NULL, // deterministic_socket_factory
414 NULL, // transport_socket_pool
415 NULL,
416 NULL,
417 NULL, // ssl_config_service
418 false, // enable_ssl_connect_job_waiting
419 NULL), // net_log
420 last_num_streams_(-1) {
423 class HttpStreamFactoryTest : public ::testing::Test,
424 public ::testing::WithParamInterface<NextProto> {
427 INSTANTIATE_TEST_CASE_P(
428 NextProto,
429 HttpStreamFactoryTest,
430 testing::Values(kProtoDeprecatedSPDY2,
431 kProtoSPDY3, kProtoSPDY31, kProtoSPDY4));
433 TEST_P(HttpStreamFactoryTest, PreconnectDirect) {
434 for (size_t i = 0; i < arraysize(kTests); ++i) {
435 SpdySessionDependencies session_deps(
436 GetParam(), ProxyService::CreateDirect());
437 scoped_refptr<HttpNetworkSession> session(
438 SpdySessionDependencies::SpdyCreateSession(&session_deps));
439 HttpNetworkSessionPeer peer(session);
440 CapturePreconnectsTransportSocketPool* transport_conn_pool =
441 new CapturePreconnectsTransportSocketPool(
442 session_deps.host_resolver.get(),
443 session_deps.cert_verifier.get());
444 CapturePreconnectsSSLSocketPool* ssl_conn_pool =
445 new CapturePreconnectsSSLSocketPool(
446 session_deps.host_resolver.get(),
447 session_deps.cert_verifier.get());
448 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
449 new MockClientSocketPoolManager);
450 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
451 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
452 peer.SetClientSocketPoolManager(
453 mock_pool_manager.PassAs<ClientSocketPoolManager>());
454 PreconnectHelper(kTests[i], session.get());
455 if (kTests[i].ssl)
456 EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams());
457 else
458 EXPECT_EQ(kTests[i].num_streams, transport_conn_pool->last_num_streams());
462 TEST_P(HttpStreamFactoryTest, PreconnectHttpProxy) {
463 for (size_t i = 0; i < arraysize(kTests); ++i) {
464 SpdySessionDependencies session_deps(
465 GetParam(), ProxyService::CreateFixed("http_proxy"));
466 scoped_refptr<HttpNetworkSession> session(
467 SpdySessionDependencies::SpdyCreateSession(&session_deps));
468 HttpNetworkSessionPeer peer(session);
469 HostPortPair proxy_host("http_proxy", 80);
470 CapturePreconnectsHttpProxySocketPool* http_proxy_pool =
471 new CapturePreconnectsHttpProxySocketPool(
472 session_deps.host_resolver.get(),
473 session_deps.cert_verifier.get());
474 CapturePreconnectsSSLSocketPool* ssl_conn_pool =
475 new CapturePreconnectsSSLSocketPool(
476 session_deps.host_resolver.get(),
477 session_deps.cert_verifier.get());
478 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
479 new MockClientSocketPoolManager);
480 mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
481 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
482 peer.SetClientSocketPoolManager(
483 mock_pool_manager.PassAs<ClientSocketPoolManager>());
484 PreconnectHelper(kTests[i], session.get());
485 if (kTests[i].ssl)
486 EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams());
487 else
488 EXPECT_EQ(kTests[i].num_streams, http_proxy_pool->last_num_streams());
492 TEST_P(HttpStreamFactoryTest, PreconnectSocksProxy) {
493 for (size_t i = 0; i < arraysize(kTests); ++i) {
494 SpdySessionDependencies session_deps(
495 GetParam(), ProxyService::CreateFixed("socks4://socks_proxy:1080"));
496 scoped_refptr<HttpNetworkSession> session(
497 SpdySessionDependencies::SpdyCreateSession(&session_deps));
498 HttpNetworkSessionPeer peer(session);
499 HostPortPair proxy_host("socks_proxy", 1080);
500 CapturePreconnectsSOCKSSocketPool* socks_proxy_pool =
501 new CapturePreconnectsSOCKSSocketPool(
502 session_deps.host_resolver.get(),
503 session_deps.cert_verifier.get());
504 CapturePreconnectsSSLSocketPool* ssl_conn_pool =
505 new CapturePreconnectsSSLSocketPool(
506 session_deps.host_resolver.get(),
507 session_deps.cert_verifier.get());
508 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
509 new MockClientSocketPoolManager);
510 mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_proxy_pool);
511 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
512 peer.SetClientSocketPoolManager(
513 mock_pool_manager.PassAs<ClientSocketPoolManager>());
514 PreconnectHelper(kTests[i], session.get());
515 if (kTests[i].ssl)
516 EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams());
517 else
518 EXPECT_EQ(kTests[i].num_streams, socks_proxy_pool->last_num_streams());
522 TEST_P(HttpStreamFactoryTest, PreconnectDirectWithExistingSpdySession) {
523 for (size_t i = 0; i < arraysize(kTests); ++i) {
524 SpdySessionDependencies session_deps(
525 GetParam(), ProxyService::CreateDirect());
526 scoped_refptr<HttpNetworkSession> session(
527 SpdySessionDependencies::SpdyCreateSession(&session_deps));
528 HttpNetworkSessionPeer peer(session);
530 // Put a SpdySession in the pool.
531 HostPortPair host_port_pair("www.google.com", 443);
532 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
533 PRIVACY_MODE_DISABLED);
534 ignore_result(CreateFakeSpdySession(session->spdy_session_pool(), key));
536 CapturePreconnectsTransportSocketPool* transport_conn_pool =
537 new CapturePreconnectsTransportSocketPool(
538 session_deps.host_resolver.get(),
539 session_deps.cert_verifier.get());
540 CapturePreconnectsSSLSocketPool* ssl_conn_pool =
541 new CapturePreconnectsSSLSocketPool(
542 session_deps.host_resolver.get(),
543 session_deps.cert_verifier.get());
544 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
545 new MockClientSocketPoolManager);
546 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
547 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
548 peer.SetClientSocketPoolManager(
549 mock_pool_manager.PassAs<ClientSocketPoolManager>());
550 PreconnectHelper(kTests[i], session.get());
551 // We shouldn't be preconnecting if we have an existing session, which is
552 // the case for https://www.google.com.
553 if (kTests[i].ssl)
554 EXPECT_EQ(-1, ssl_conn_pool->last_num_streams());
555 else
556 EXPECT_EQ(kTests[i].num_streams,
557 transport_conn_pool->last_num_streams());
561 // Verify that preconnects to unsafe ports are cancelled before they reach
562 // the SocketPool.
563 TEST_P(HttpStreamFactoryTest, PreconnectUnsafePort) {
564 ASSERT_FALSE(IsPortAllowedByDefault(7));
565 ASSERT_FALSE(IsPortAllowedByOverride(7));
567 SpdySessionDependencies session_deps(
568 GetParam(), ProxyService::CreateDirect());
569 scoped_refptr<HttpNetworkSession> session(
570 SpdySessionDependencies::SpdyCreateSession(&session_deps));
571 HttpNetworkSessionPeer peer(session);
572 CapturePreconnectsTransportSocketPool* transport_conn_pool =
573 new CapturePreconnectsTransportSocketPool(
574 session_deps.host_resolver.get(),
575 session_deps.cert_verifier.get());
576 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
577 new MockClientSocketPoolManager);
578 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
579 peer.SetClientSocketPoolManager(
580 mock_pool_manager.PassAs<ClientSocketPoolManager>());
582 PreconnectHelperForURL(1, GURL("http://www.google.com:7"), session.get());
584 EXPECT_EQ(-1, transport_conn_pool->last_num_streams());
587 TEST_P(HttpStreamFactoryTest, JobNotifiesProxy) {
588 const char* kProxyString = "PROXY bad:99; PROXY maybe:80; DIRECT";
589 SpdySessionDependencies session_deps(
590 GetParam(), ProxyService::CreateFixedFromPacResult(kProxyString));
592 // First connection attempt fails
593 StaticSocketDataProvider socket_data1;
594 socket_data1.set_connect_data(MockConnect(ASYNC, ERR_ADDRESS_UNREACHABLE));
595 session_deps.socket_factory->AddSocketDataProvider(&socket_data1);
597 // Second connection attempt succeeds
598 StaticSocketDataProvider socket_data2;
599 socket_data2.set_connect_data(MockConnect(ASYNC, OK));
600 session_deps.socket_factory->AddSocketDataProvider(&socket_data2);
602 scoped_refptr<HttpNetworkSession> session(
603 SpdySessionDependencies::SpdyCreateSession(&session_deps));
605 // Now request a stream. It should succeed using the second proxy in the
606 // list.
607 HttpRequestInfo request_info;
608 request_info.method = "GET";
609 request_info.url = GURL("http://www.google.com");
611 SSLConfig ssl_config;
612 StreamRequestWaiter waiter;
613 scoped_ptr<HttpStreamRequest> request(
614 session->http_stream_factory()->RequestStream(
615 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config,
616 &waiter, BoundNetLog()));
617 waiter.WaitForStream();
619 // The proxy that failed should now be known to the proxy_service as bad.
620 const ProxyRetryInfoMap& retry_info =
621 session->proxy_service()->proxy_retry_info();
622 EXPECT_EQ(1u, retry_info.size());
623 ProxyRetryInfoMap::const_iterator iter = retry_info.find("bad:99");
624 EXPECT_TRUE(iter != retry_info.end());
627 TEST_P(HttpStreamFactoryTest, PrivacyModeDisablesChannelId) {
628 SpdySessionDependencies session_deps(
629 GetParam(), ProxyService::CreateDirect());
631 StaticSocketDataProvider socket_data;
632 socket_data.set_connect_data(MockConnect(ASYNC, OK));
633 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
635 SSLSocketDataProvider ssl(ASYNC, OK);
636 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
638 scoped_refptr<HttpNetworkSession> session(
639 SpdySessionDependencies::SpdyCreateSession(&session_deps));
641 // Set an existing SpdySession in the pool.
642 HostPortPair host_port_pair("www.google.com", 443);
643 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
644 PRIVACY_MODE_ENABLED);
646 HttpRequestInfo request_info;
647 request_info.method = "GET";
648 request_info.url = GURL("https://www.google.com");
649 request_info.load_flags = 0;
650 request_info.privacy_mode = PRIVACY_MODE_DISABLED;
652 SSLConfig ssl_config;
653 StreamRequestWaiter waiter;
654 scoped_ptr<HttpStreamRequest> request(
655 session->http_stream_factory()->RequestStream(
656 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config,
657 &waiter, BoundNetLog()));
658 waiter.WaitForStream();
660 // The stream shouldn't come from spdy as we are using different privacy mode
661 EXPECT_FALSE(request->using_spdy());
663 SSLConfig used_ssl_config = waiter.used_ssl_config();
664 EXPECT_EQ(used_ssl_config.channel_id_enabled, ssl_config.channel_id_enabled);
667 namespace {
668 // Return count of distinct groups in given socket pool.
669 int GetSocketPoolGroupCount(ClientSocketPool* pool) {
670 int count = 0;
671 scoped_ptr<base::DictionaryValue> dict(pool->GetInfoAsValue("", "", false));
672 EXPECT_TRUE(dict != NULL);
673 base::DictionaryValue* groups = NULL;
674 if (dict->GetDictionary("groups", &groups) && (groups != NULL)) {
675 count = static_cast<int>(groups->size());
677 return count;
679 } // namespace
681 TEST_P(HttpStreamFactoryTest, PrivacyModeUsesDifferentSocketPoolGroup) {
682 SpdySessionDependencies session_deps(
683 GetParam(), ProxyService::CreateDirect());
685 StaticSocketDataProvider socket_data;
686 socket_data.set_connect_data(MockConnect(ASYNC, OK));
687 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
689 SSLSocketDataProvider ssl(ASYNC, OK);
690 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
692 scoped_refptr<HttpNetworkSession> session(
693 SpdySessionDependencies::SpdyCreateSession(&session_deps));
694 SSLClientSocketPool* ssl_pool = session->GetSSLSocketPool(
695 HttpNetworkSession::NORMAL_SOCKET_POOL);
697 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 0);
699 HttpRequestInfo request_info;
700 request_info.method = "GET";
701 request_info.url = GURL("https://www.google.com");
702 request_info.load_flags = 0;
703 request_info.privacy_mode = PRIVACY_MODE_DISABLED;
705 SSLConfig ssl_config;
706 StreamRequestWaiter waiter;
708 scoped_ptr<HttpStreamRequest> request1(
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 scoped_ptr<HttpStreamRequest> request2(
717 session->http_stream_factory()->RequestStream(
718 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config,
719 &waiter, BoundNetLog()));
720 waiter.WaitForStream();
722 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 1);
724 request_info.privacy_mode = PRIVACY_MODE_ENABLED;
725 scoped_ptr<HttpStreamRequest> request3(
726 session->http_stream_factory()->RequestStream(
727 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config,
728 &waiter, BoundNetLog()));
729 waiter.WaitForStream();
731 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 2);
734 TEST_P(HttpStreamFactoryTest, GetLoadState) {
735 SpdySessionDependencies session_deps(
736 GetParam(), ProxyService::CreateDirect());
738 StaticSocketDataProvider socket_data;
739 socket_data.set_connect_data(MockConnect(ASYNC, OK));
740 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
742 scoped_refptr<HttpNetworkSession> session(
743 SpdySessionDependencies::SpdyCreateSession(&session_deps));
745 HttpRequestInfo request_info;
746 request_info.method = "GET";
747 request_info.url = GURL("http://www.google.com");
749 SSLConfig ssl_config;
750 StreamRequestWaiter waiter;
751 scoped_ptr<HttpStreamRequest> request(
752 session->http_stream_factory()->RequestStream(
753 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config,
754 &waiter, BoundNetLog()));
756 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, request->GetLoadState());
758 waiter.WaitForStream();
761 TEST_P(HttpStreamFactoryTest, RequestHttpStream) {
762 SpdySessionDependencies session_deps(
763 GetParam(), ProxyService::CreateDirect());
765 StaticSocketDataProvider socket_data;
766 socket_data.set_connect_data(MockConnect(ASYNC, OK));
767 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
769 scoped_refptr<HttpNetworkSession> session(
770 SpdySessionDependencies::SpdyCreateSession(&session_deps));
772 // Now request a stream. It should succeed using the second proxy in the
773 // list.
774 HttpRequestInfo request_info;
775 request_info.method = "GET";
776 request_info.url = GURL("http://www.google.com");
777 request_info.load_flags = 0;
779 SSLConfig ssl_config;
780 StreamRequestWaiter waiter;
781 scoped_ptr<HttpStreamRequest> request(
782 session->http_stream_factory()->RequestStream(
783 request_info,
784 DEFAULT_PRIORITY,
785 ssl_config,
786 ssl_config,
787 &waiter,
788 BoundNetLog()));
789 waiter.WaitForStream();
790 EXPECT_TRUE(waiter.stream_done());
791 ASSERT_TRUE(NULL != waiter.stream());
792 EXPECT_TRUE(NULL == waiter.websocket_stream());
793 EXPECT_FALSE(waiter.stream()->IsSpdyHttpStream());
795 EXPECT_EQ(1, GetSocketPoolGroupCount(
796 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
797 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool(
798 HttpNetworkSession::NORMAL_SOCKET_POOL)));
799 EXPECT_EQ(0, GetSocketPoolGroupCount(
800 session->GetTransportSocketPool(
801 HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
802 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool(
803 HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
804 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
807 TEST_P(HttpStreamFactoryTest, RequestHttpStreamOverSSL) {
808 SpdySessionDependencies session_deps(
809 GetParam(), ProxyService::CreateDirect());
811 MockRead mock_read(ASYNC, OK);
812 StaticSocketDataProvider socket_data(&mock_read, 1, NULL, 0);
813 socket_data.set_connect_data(MockConnect(ASYNC, OK));
814 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
816 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
817 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
819 scoped_refptr<HttpNetworkSession> session(
820 SpdySessionDependencies::SpdyCreateSession(&session_deps));
822 // Now request a stream.
823 HttpRequestInfo request_info;
824 request_info.method = "GET";
825 request_info.url = GURL("https://www.google.com");
826 request_info.load_flags = 0;
828 SSLConfig ssl_config;
829 StreamRequestWaiter waiter;
830 scoped_ptr<HttpStreamRequest> request(
831 session->http_stream_factory()->RequestStream(
832 request_info,
833 DEFAULT_PRIORITY,
834 ssl_config,
835 ssl_config,
836 &waiter,
837 BoundNetLog()));
838 waiter.WaitForStream();
839 EXPECT_TRUE(waiter.stream_done());
840 ASSERT_TRUE(NULL != waiter.stream());
841 EXPECT_TRUE(NULL == waiter.websocket_stream());
842 EXPECT_FALSE(waiter.stream()->IsSpdyHttpStream());
843 EXPECT_EQ(1, GetSocketPoolGroupCount(
844 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
845 EXPECT_EQ(1, GetSocketPoolGroupCount(
846 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
847 EXPECT_EQ(0, GetSocketPoolGroupCount(
848 session->GetTransportSocketPool(
849 HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
850 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool(
851 HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
852 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
855 TEST_P(HttpStreamFactoryTest, RequestHttpStreamOverProxy) {
856 SpdySessionDependencies session_deps(
857 GetParam(), ProxyService::CreateFixed("myproxy:8888"));
859 StaticSocketDataProvider socket_data;
860 socket_data.set_connect_data(MockConnect(ASYNC, OK));
861 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
863 scoped_refptr<HttpNetworkSession> session(
864 SpdySessionDependencies::SpdyCreateSession(&session_deps));
866 // Now request a stream. It should succeed using the second proxy in the
867 // list.
868 HttpRequestInfo request_info;
869 request_info.method = "GET";
870 request_info.url = GURL("http://www.google.com");
871 request_info.load_flags = 0;
873 SSLConfig ssl_config;
874 StreamRequestWaiter waiter;
875 scoped_ptr<HttpStreamRequest> request(
876 session->http_stream_factory()->RequestStream(
877 request_info,
878 DEFAULT_PRIORITY,
879 ssl_config,
880 ssl_config,
881 &waiter,
882 BoundNetLog()));
883 waiter.WaitForStream();
884 EXPECT_TRUE(waiter.stream_done());
885 ASSERT_TRUE(NULL != waiter.stream());
886 EXPECT_TRUE(NULL == waiter.websocket_stream());
887 EXPECT_FALSE(waiter.stream()->IsSpdyHttpStream());
888 EXPECT_EQ(0, GetSocketPoolGroupCount(
889 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
890 EXPECT_EQ(0, GetSocketPoolGroupCount(
891 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
892 EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSocketPoolForHTTPProxy(
893 HttpNetworkSession::NORMAL_SOCKET_POOL,
894 HostPortPair("myproxy", 8888))));
895 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForSSLWithProxy(
896 HttpNetworkSession::NORMAL_SOCKET_POOL,
897 HostPortPair("myproxy", 8888))));
898 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForHTTPProxy(
899 HttpNetworkSession::WEBSOCKET_SOCKET_POOL,
900 HostPortPair("myproxy", 8888))));
901 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForSSLWithProxy(
902 HttpNetworkSession::WEBSOCKET_SOCKET_POOL,
903 HostPortPair("myproxy", 8888))));
904 EXPECT_FALSE(waiter.used_proxy_info().is_direct());
907 TEST_P(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStream) {
908 SpdySessionDependencies session_deps(
909 GetParam(), ProxyService::CreateDirect());
911 StaticSocketDataProvider socket_data;
912 socket_data.set_connect_data(MockConnect(ASYNC, OK));
913 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
915 scoped_refptr<HttpNetworkSession> session(
916 SpdySessionDependencies::SpdyCreateSession(&session_deps));
918 // Now request a stream.
919 HttpRequestInfo request_info;
920 request_info.method = "GET";
921 request_info.url = GURL("ws://www.google.com");
922 request_info.load_flags = 0;
924 SSLConfig ssl_config;
925 StreamRequestWaiter waiter;
926 WebSocketStreamCreateHelper create_helper;
927 scoped_ptr<HttpStreamRequest> request(
928 session->http_stream_factory_for_websocket()
929 ->RequestWebSocketHandshakeStream(request_info,
930 DEFAULT_PRIORITY,
931 ssl_config,
932 ssl_config,
933 &waiter,
934 &create_helper,
935 BoundNetLog()));
936 waiter.WaitForStream();
937 EXPECT_TRUE(waiter.stream_done());
938 EXPECT_TRUE(NULL == waiter.stream());
939 ASSERT_TRUE(NULL != waiter.websocket_stream());
940 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic,
941 waiter.websocket_stream()->type());
942 EXPECT_EQ(0, GetSocketPoolGroupCount(
943 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
944 EXPECT_EQ(0, GetSocketPoolGroupCount(
945 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
946 EXPECT_EQ(0, GetSocketPoolGroupCount(
947 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
948 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
951 TEST_P(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStreamOverSSL) {
952 SpdySessionDependencies session_deps(
953 GetParam(), ProxyService::CreateDirect());
955 MockRead mock_read(ASYNC, OK);
956 StaticSocketDataProvider socket_data(&mock_read, 1, NULL, 0);
957 socket_data.set_connect_data(MockConnect(ASYNC, OK));
958 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
960 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
961 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
963 scoped_refptr<HttpNetworkSession> session(
964 SpdySessionDependencies::SpdyCreateSession(&session_deps));
966 // Now request a stream.
967 HttpRequestInfo request_info;
968 request_info.method = "GET";
969 request_info.url = GURL("wss://www.google.com");
970 request_info.load_flags = 0;
972 SSLConfig ssl_config;
973 StreamRequestWaiter waiter;
974 WebSocketStreamCreateHelper create_helper;
975 scoped_ptr<HttpStreamRequest> request(
976 session->http_stream_factory_for_websocket()
977 ->RequestWebSocketHandshakeStream(request_info,
978 DEFAULT_PRIORITY,
979 ssl_config,
980 ssl_config,
981 &waiter,
982 &create_helper,
983 BoundNetLog()));
984 waiter.WaitForStream();
985 EXPECT_TRUE(waiter.stream_done());
986 EXPECT_TRUE(NULL == waiter.stream());
987 ASSERT_TRUE(NULL != waiter.websocket_stream());
988 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic,
989 waiter.websocket_stream()->type());
990 EXPECT_EQ(0, GetSocketPoolGroupCount(
991 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
992 EXPECT_EQ(0, GetSocketPoolGroupCount(
993 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
994 EXPECT_EQ(1, GetSocketPoolGroupCount(
995 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
996 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
999 TEST_P(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStreamOverProxy) {
1000 SpdySessionDependencies session_deps(
1001 GetParam(), ProxyService::CreateFixed("myproxy:8888"));
1003 MockRead read(SYNCHRONOUS, "HTTP/1.0 200 Connection established\r\n\r\n");
1004 StaticSocketDataProvider socket_data(&read, 1, 0, 0);
1005 socket_data.set_connect_data(MockConnect(ASYNC, OK));
1006 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
1008 scoped_refptr<HttpNetworkSession> session(
1009 SpdySessionDependencies::SpdyCreateSession(&session_deps));
1011 // Now request a stream.
1012 HttpRequestInfo request_info;
1013 request_info.method = "GET";
1014 request_info.url = GURL("ws://www.google.com");
1015 request_info.load_flags = 0;
1017 SSLConfig ssl_config;
1018 StreamRequestWaiter waiter;
1019 WebSocketStreamCreateHelper create_helper;
1020 scoped_ptr<HttpStreamRequest> request(
1021 session->http_stream_factory_for_websocket()
1022 ->RequestWebSocketHandshakeStream(request_info,
1023 DEFAULT_PRIORITY,
1024 ssl_config,
1025 ssl_config,
1026 &waiter,
1027 &create_helper,
1028 BoundNetLog()));
1029 waiter.WaitForStream();
1030 EXPECT_TRUE(waiter.stream_done());
1031 EXPECT_TRUE(NULL == waiter.stream());
1032 ASSERT_TRUE(NULL != waiter.websocket_stream());
1033 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic,
1034 waiter.websocket_stream()->type());
1035 EXPECT_EQ(0, GetSocketPoolGroupCount(
1036 session->GetTransportSocketPool(
1037 HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1038 EXPECT_EQ(0, GetSocketPoolGroupCount(
1039 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1040 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForHTTPProxy(
1041 HttpNetworkSession::NORMAL_SOCKET_POOL,
1042 HostPortPair("myproxy", 8888))));
1043 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForSSLWithProxy(
1044 HttpNetworkSession::NORMAL_SOCKET_POOL,
1045 HostPortPair("myproxy", 8888))));
1046 EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSocketPoolForHTTPProxy(
1047 HttpNetworkSession::WEBSOCKET_SOCKET_POOL,
1048 HostPortPair("myproxy", 8888))));
1049 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForSSLWithProxy(
1050 HttpNetworkSession::WEBSOCKET_SOCKET_POOL,
1051 HostPortPair("myproxy", 8888))));
1052 EXPECT_FALSE(waiter.used_proxy_info().is_direct());
1055 TEST_P(HttpStreamFactoryTest, RequestSpdyHttpStream) {
1056 SpdySessionDependencies session_deps(GetParam(),
1057 ProxyService::CreateDirect());
1059 MockRead mock_read(ASYNC, OK);
1060 DeterministicSocketData socket_data(&mock_read, 1, NULL, 0);
1061 socket_data.set_connect_data(MockConnect(ASYNC, OK));
1062 session_deps.deterministic_socket_factory->AddSocketDataProvider(
1063 &socket_data);
1065 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
1066 ssl_socket_data.SetNextProto(GetParam());
1067 session_deps.deterministic_socket_factory->AddSSLSocketDataProvider(
1068 &ssl_socket_data);
1070 HostPortPair host_port_pair("www.google.com", 443);
1071 scoped_refptr<HttpNetworkSession>
1072 session(SpdySessionDependencies::SpdyCreateSessionDeterministic(
1073 &session_deps));
1075 // Now request a stream.
1076 HttpRequestInfo request_info;
1077 request_info.method = "GET";
1078 request_info.url = GURL("https://www.google.com");
1079 request_info.load_flags = 0;
1081 SSLConfig ssl_config;
1082 StreamRequestWaiter waiter;
1083 scoped_ptr<HttpStreamRequest> request(
1084 session->http_stream_factory()->RequestStream(
1085 request_info,
1086 DEFAULT_PRIORITY,
1087 ssl_config,
1088 ssl_config,
1089 &waiter,
1090 BoundNetLog()));
1091 waiter.WaitForStream();
1092 EXPECT_TRUE(waiter.stream_done());
1093 EXPECT_TRUE(NULL == waiter.websocket_stream());
1094 ASSERT_TRUE(NULL != waiter.stream());
1095 EXPECT_TRUE(waiter.stream()->IsSpdyHttpStream());
1096 EXPECT_EQ(1, GetSocketPoolGroupCount(
1097 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1098 EXPECT_EQ(1, GetSocketPoolGroupCount(
1099 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1100 EXPECT_EQ(0, GetSocketPoolGroupCount(
1101 session->GetTransportSocketPool(
1102 HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1103 EXPECT_EQ(0, GetSocketPoolGroupCount(
1104 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1105 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
1108 // TODO(ricea): This test can be removed once the new WebSocket stack supports
1109 // SPDY. Currently, even if we connect to a SPDY-supporting server, we need to
1110 // use plain SSL.
1111 TEST_P(HttpStreamFactoryTest, RequestWebSocketSpdyHandshakeStreamButGetSSL) {
1112 SpdySessionDependencies session_deps(GetParam(),
1113 ProxyService::CreateDirect());
1115 MockRead mock_read(SYNCHRONOUS, ERR_IO_PENDING);
1116 StaticSocketDataProvider socket_data(&mock_read, 1, NULL, 0);
1117 socket_data.set_connect_data(MockConnect(ASYNC, OK));
1118 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
1120 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
1121 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
1123 HostPortPair host_port_pair("www.google.com", 80);
1124 scoped_refptr<HttpNetworkSession>
1125 session(SpdySessionDependencies::SpdyCreateSession(&session_deps));
1127 // Now request a stream.
1128 HttpRequestInfo request_info;
1129 request_info.method = "GET";
1130 request_info.url = GURL("wss://www.google.com");
1131 request_info.load_flags = 0;
1133 SSLConfig ssl_config;
1134 StreamRequestWaiter waiter1;
1135 WebSocketStreamCreateHelper create_helper;
1136 scoped_ptr<HttpStreamRequest> request1(
1137 session->http_stream_factory_for_websocket()
1138 ->RequestWebSocketHandshakeStream(request_info,
1139 DEFAULT_PRIORITY,
1140 ssl_config,
1141 ssl_config,
1142 &waiter1,
1143 &create_helper,
1144 BoundNetLog()));
1145 waiter1.WaitForStream();
1146 EXPECT_TRUE(waiter1.stream_done());
1147 ASSERT_TRUE(NULL != waiter1.websocket_stream());
1148 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic,
1149 waiter1.websocket_stream()->type());
1150 EXPECT_TRUE(NULL == waiter1.stream());
1152 EXPECT_EQ(0, GetSocketPoolGroupCount(
1153 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1154 EXPECT_EQ(0, GetSocketPoolGroupCount(
1155 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1156 EXPECT_EQ(1, GetSocketPoolGroupCount(
1157 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1158 EXPECT_TRUE(waiter1.used_proxy_info().is_direct());
1161 // TODO(ricea): Re-enable once WebSocket-over-SPDY is implemented.
1162 TEST_P(HttpStreamFactoryTest, DISABLED_RequestWebSocketSpdyHandshakeStream) {
1163 SpdySessionDependencies session_deps(GetParam(),
1164 ProxyService::CreateDirect());
1166 MockRead mock_read(SYNCHRONOUS, ERR_IO_PENDING);
1167 StaticSocketDataProvider socket_data(&mock_read, 1, NULL, 0);
1168 socket_data.set_connect_data(MockConnect(ASYNC, OK));
1169 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
1171 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
1172 ssl_socket_data.SetNextProto(GetParam());
1173 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
1175 HostPortPair host_port_pair("www.google.com", 80);
1176 scoped_refptr<HttpNetworkSession>
1177 session(SpdySessionDependencies::SpdyCreateSession(&session_deps));
1179 // Now request a stream.
1180 HttpRequestInfo request_info;
1181 request_info.method = "GET";
1182 request_info.url = GURL("wss://www.google.com");
1183 request_info.load_flags = 0;
1185 SSLConfig ssl_config;
1186 StreamRequestWaiter waiter1;
1187 WebSocketStreamCreateHelper create_helper;
1188 scoped_ptr<HttpStreamRequest> request1(
1189 session->http_stream_factory_for_websocket()
1190 ->RequestWebSocketHandshakeStream(request_info,
1191 DEFAULT_PRIORITY,
1192 ssl_config,
1193 ssl_config,
1194 &waiter1,
1195 &create_helper,
1196 BoundNetLog()));
1197 waiter1.WaitForStream();
1198 EXPECT_TRUE(waiter1.stream_done());
1199 ASSERT_TRUE(NULL != waiter1.websocket_stream());
1200 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy,
1201 waiter1.websocket_stream()->type());
1202 EXPECT_TRUE(NULL == waiter1.stream());
1204 StreamRequestWaiter waiter2;
1205 scoped_ptr<HttpStreamRequest> request2(
1206 session->http_stream_factory_for_websocket()
1207 ->RequestWebSocketHandshakeStream(request_info,
1208 DEFAULT_PRIORITY,
1209 ssl_config,
1210 ssl_config,
1211 &waiter2,
1212 &create_helper,
1213 BoundNetLog()));
1214 waiter2.WaitForStream();
1215 EXPECT_TRUE(waiter2.stream_done());
1216 ASSERT_TRUE(NULL != waiter2.websocket_stream());
1217 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy,
1218 waiter2.websocket_stream()->type());
1219 EXPECT_TRUE(NULL == waiter2.stream());
1220 EXPECT_NE(waiter2.websocket_stream(), waiter1.websocket_stream());
1221 EXPECT_EQ(static_cast<WebSocketSpdyHandshakeStream*>(
1222 waiter2.websocket_stream())->spdy_session(),
1223 static_cast<WebSocketSpdyHandshakeStream*>(
1224 waiter1.websocket_stream())->spdy_session());
1226 EXPECT_EQ(0, GetSocketPoolGroupCount(
1227 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1228 EXPECT_EQ(0, GetSocketPoolGroupCount(
1229 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1230 EXPECT_EQ(1, GetSocketPoolGroupCount(
1231 session->GetTransportSocketPool(
1232 HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1233 EXPECT_EQ(1, GetSocketPoolGroupCount(
1234 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1235 EXPECT_TRUE(waiter1.used_proxy_info().is_direct());
1238 // TODO(ricea): Re-enable once WebSocket over SPDY is implemented.
1239 TEST_P(HttpStreamFactoryTest, DISABLED_OrphanedWebSocketStream) {
1240 SpdySessionDependencies session_deps(GetParam(),
1241 ProxyService::CreateDirect());
1242 session_deps.use_alternate_protocols = true;
1244 MockRead mock_read(ASYNC, OK);
1245 DeterministicSocketData socket_data(&mock_read, 1, NULL, 0);
1246 socket_data.set_connect_data(MockConnect(ASYNC, OK));
1247 session_deps.deterministic_socket_factory->AddSocketDataProvider(
1248 &socket_data);
1250 MockRead mock_read2(ASYNC, OK);
1251 DeterministicSocketData socket_data2(&mock_read2, 1, NULL, 0);
1252 socket_data2.set_connect_data(MockConnect(ASYNC, ERR_IO_PENDING));
1253 session_deps.deterministic_socket_factory->AddSocketDataProvider(
1254 &socket_data2);
1256 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
1257 ssl_socket_data.SetNextProto(GetParam());
1258 session_deps.deterministic_socket_factory->AddSSLSocketDataProvider(
1259 &ssl_socket_data);
1261 scoped_refptr<HttpNetworkSession>
1262 session(SpdySessionDependencies::SpdyCreateSessionDeterministic(
1263 &session_deps));
1265 // Now request a stream.
1266 HttpRequestInfo request_info;
1267 request_info.method = "GET";
1268 request_info.url = GURL("ws://www.google.com:8888");
1269 request_info.load_flags = 0;
1271 session->http_server_properties()->SetAlternateProtocol(
1272 HostPortPair("www.google.com", 8888),
1273 9999,
1274 NPN_SPDY_3,
1277 SSLConfig ssl_config;
1278 StreamRequestWaiter waiter;
1279 WebSocketStreamCreateHelper create_helper;
1280 scoped_ptr<HttpStreamRequest> request(
1281 session->http_stream_factory_for_websocket()
1282 ->RequestWebSocketHandshakeStream(request_info,
1283 DEFAULT_PRIORITY,
1284 ssl_config,
1285 ssl_config,
1286 &waiter,
1287 &create_helper,
1288 BoundNetLog()));
1289 waiter.WaitForStream();
1290 EXPECT_TRUE(waiter.stream_done());
1291 EXPECT_TRUE(NULL == waiter.stream());
1292 ASSERT_TRUE(NULL != waiter.websocket_stream());
1293 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy,
1294 waiter.websocket_stream()->type());
1296 // Make sure that there was an alternative connection
1297 // which consumes extra connections.
1298 EXPECT_EQ(0, GetSocketPoolGroupCount(
1299 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1300 EXPECT_EQ(0, GetSocketPoolGroupCount(
1301 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
1302 EXPECT_EQ(2, GetSocketPoolGroupCount(
1303 session->GetTransportSocketPool(
1304 HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1305 EXPECT_EQ(1, GetSocketPoolGroupCount(
1306 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1307 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
1309 // Make sure there is no orphaned job. it is already canceled.
1310 ASSERT_EQ(0u, static_cast<HttpStreamFactoryImpl*>(
1311 session->http_stream_factory_for_websocket())->num_orphaned_jobs());
1314 } // namespace
1316 } // namespace net