OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "net/http/http_stream_factory_impl.h" | |
6 | |
7 #include <string> | |
8 #include <vector> | |
9 | |
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" | |
41 | |
42 namespace net { | |
43 | |
44 namespace { | |
45 | |
46 class MockWebSocketHandshakeStream : public WebSocketHandshakeStreamBase { | |
47 public: | |
48 enum StreamType { | |
49 kStreamTypeBasic, | |
50 kStreamTypeSpdy, | |
51 }; | |
52 | |
53 explicit MockWebSocketHandshakeStream(StreamType type) : type_(type) {} | |
54 | |
55 ~MockWebSocketHandshakeStream() override {} | |
56 | |
57 StreamType type() const { | |
58 return type_; | |
59 } | |
60 | |
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; | |
67 } | |
68 int SendRequest(const HttpRequestHeaders& request_headers, | |
69 HttpResponseInfo* response, | |
70 const CompletionCallback& callback) override { | |
71 return ERR_IO_PENDING; | |
72 } | |
73 int ReadResponseHeaders(const CompletionCallback& callback) override { | |
74 return ERR_IO_PENDING; | |
75 } | |
76 int ReadResponseBody(IOBuffer* buf, | |
77 int buf_len, | |
78 const CompletionCallback& callback) override { | |
79 return ERR_IO_PENDING; | |
80 } | |
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; | |
90 } | |
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; } | |
98 | |
99 scoped_ptr<WebSocketStream> Upgrade() override { | |
100 return scoped_ptr<WebSocketStream>(); | |
101 } | |
102 | |
103 private: | |
104 const StreamType type_; | |
105 }; | |
106 | |
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) {} | |
115 | |
116 | |
117 void WaitForPreconnects() { | |
118 while (!preconnect_done_) { | |
119 waiting_for_preconnect_ = true; | |
120 base::MessageLoop::current()->Run(); | |
121 waiting_for_preconnect_ = false; | |
122 } | |
123 } | |
124 | |
125 private: | |
126 // HttpStreamFactoryImpl methods. | |
127 void OnPreconnectsCompleteInternal() override { | |
128 preconnect_done_ = true; | |
129 if (waiting_for_preconnect_) | |
130 base::MessageLoop::current()->Quit(); | |
131 } | |
132 | |
133 bool preconnect_done_; | |
134 bool waiting_for_preconnect_; | |
135 }; | |
136 | |
137 class StreamRequestWaiter : public HttpStreamRequest::Delegate { | |
138 public: | |
139 StreamRequestWaiter() | |
140 : waiting_for_stream_(false), | |
141 stream_done_(false) {} | |
142 | |
143 // HttpStreamRequest::Delegate | |
144 | |
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; | |
154 } | |
155 | |
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; | |
166 } | |
167 | |
168 void OnStreamFailed(int status, const SSLConfig& used_ssl_config) override {} | |
169 | |
170 void OnCertificateError(int status, | |
171 const SSLConfig& used_ssl_config, | |
172 const SSLInfo& ssl_info) override {} | |
173 | |
174 void OnNeedsProxyAuth(const HttpResponseInfo& proxy_response, | |
175 const SSLConfig& used_ssl_config, | |
176 const ProxyInfo& used_proxy_info, | |
177 HttpAuthController* auth_controller) override {} | |
178 | |
179 void OnNeedsClientAuth(const SSLConfig& used_ssl_config, | |
180 SSLCertRequestInfo* cert_info) override {} | |
181 | |
182 void OnHttpsProxyTunnelResponse(const HttpResponseInfo& response_info, | |
183 const SSLConfig& used_ssl_config, | |
184 const ProxyInfo& used_proxy_info, | |
185 HttpStream* stream) override {} | |
186 | |
187 void WaitForStream() { | |
188 while (!stream_done_) { | |
189 waiting_for_stream_ = true; | |
190 base::MessageLoop::current()->Run(); | |
191 waiting_for_stream_ = false; | |
192 } | |
193 } | |
194 | |
195 const SSLConfig& used_ssl_config() const { | |
196 return used_ssl_config_; | |
197 } | |
198 | |
199 const ProxyInfo& used_proxy_info() const { | |
200 return used_proxy_info_; | |
201 } | |
202 | |
203 HttpStream* stream() { | |
204 return stream_.get(); | |
205 } | |
206 | |
207 MockWebSocketHandshakeStream* websocket_stream() { | |
208 return static_cast<MockWebSocketHandshakeStream*>(websocket_stream_.get()); | |
209 } | |
210 | |
211 bool stream_done() const { return stream_done_; } | |
212 | |
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_; | |
220 | |
221 DISALLOW_COPY_AND_ASSIGN(StreamRequestWaiter); | |
222 }; | |
223 | |
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) {} | |
230 | |
231 ~WebSocketSpdyHandshakeStream() override {} | |
232 | |
233 SpdySession* spdy_session() { return spdy_session_.get(); } | |
234 | |
235 private: | |
236 base::WeakPtr<SpdySession> spdy_session_; | |
237 }; | |
238 | |
239 class WebSocketBasicHandshakeStream : public MockWebSocketHandshakeStream { | |
240 public: | |
241 explicit WebSocketBasicHandshakeStream( | |
242 scoped_ptr<ClientSocketHandle> connection) | |
243 : MockWebSocketHandshakeStream(kStreamTypeBasic), | |
244 connection_(connection.Pass()) {} | |
245 | |
246 ~WebSocketBasicHandshakeStream() override { | |
247 connection_->socket()->Disconnect(); | |
248 } | |
249 | |
250 ClientSocketHandle* connection() { return connection_.get(); } | |
251 | |
252 private: | |
253 scoped_ptr<ClientSocketHandle> connection_; | |
254 }; | |
255 | |
256 class WebSocketStreamCreateHelper | |
257 : public WebSocketHandshakeStreamBase::CreateHelper { | |
258 public: | |
259 ~WebSocketStreamCreateHelper() override {} | |
260 | |
261 WebSocketHandshakeStreamBase* CreateBasicStream( | |
262 scoped_ptr<ClientSocketHandle> connection, | |
263 bool using_proxy) override { | |
264 return new WebSocketBasicHandshakeStream(connection.Pass()); | |
265 } | |
266 | |
267 WebSocketHandshakeStreamBase* CreateSpdyStream( | |
268 const base::WeakPtr<SpdySession>& spdy_session, | |
269 bool use_relative_url) override { | |
270 return new WebSocketSpdyHandshakeStream(spdy_session); | |
271 } | |
272 }; | |
273 | |
274 struct TestCase { | |
275 int num_streams; | |
276 bool ssl; | |
277 }; | |
278 | |
279 TestCase kTests[] = { | |
280 { 1, false }, | |
281 { 2, false }, | |
282 { 1, true}, | |
283 { 2, true}, | |
284 }; | |
285 | |
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); | |
295 | |
296 HttpRequestInfo request; | |
297 request.method = "GET"; | |
298 request.url = url; | |
299 request.load_flags = 0; | |
300 | |
301 session->http_stream_factory()->PreconnectStreams( | |
302 num_streams, request, DEFAULT_PRIORITY, ssl_config, ssl_config); | |
303 mock_factory->WaitForPreconnects(); | |
304 }; | |
305 | |
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); | |
311 }; | |
312 | |
313 template<typename ParentPool> | |
314 class CapturePreconnectsSocketPool : public ParentPool { | |
315 public: | |
316 CapturePreconnectsSocketPool(HostResolver* host_resolver, | |
317 CertVerifier* cert_verifier); | |
318 | |
319 int last_num_streams() const { | |
320 return last_num_streams_; | |
321 } | |
322 | |
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; | |
331 } | |
332 | |
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; | |
338 } | |
339 | |
340 virtual void CancelRequest(const std::string& group_name, | |
341 ClientSocketHandle* handle) override { | |
342 ADD_FAILURE(); | |
343 } | |
344 virtual void ReleaseSocket(const std::string& group_name, | |
345 scoped_ptr<StreamSocket> socket, | |
346 int id) override { | |
347 ADD_FAILURE(); | |
348 } | |
349 virtual void CloseIdleSockets() override { | |
350 ADD_FAILURE(); | |
351 } | |
352 virtual int IdleSocketCount() const override { | |
353 ADD_FAILURE(); | |
354 return 0; | |
355 } | |
356 virtual int IdleSocketCountInGroup( | |
357 const std::string& group_name) const override { | |
358 ADD_FAILURE(); | |
359 return 0; | |
360 } | |
361 virtual LoadState GetLoadState( | |
362 const std::string& group_name, | |
363 const ClientSocketHandle* handle) const override { | |
364 ADD_FAILURE(); | |
365 return LOAD_STATE_IDLE; | |
366 } | |
367 virtual base::TimeDelta ConnectionTimeout() const override { | |
368 return base::TimeDelta(); | |
369 } | |
370 | |
371 private: | |
372 int last_num_streams_; | |
373 }; | |
374 | |
375 typedef CapturePreconnectsSocketPool<TransportClientSocketPool> | |
376 CapturePreconnectsTransportSocketPool; | |
377 typedef CapturePreconnectsSocketPool<HttpProxyClientSocketPool> | |
378 CapturePreconnectsHttpProxySocketPool; | |
379 typedef CapturePreconnectsSocketPool<SOCKSClientSocketPool> | |
380 CapturePreconnectsSOCKSSocketPool; | |
381 typedef CapturePreconnectsSocketPool<SSLClientSocketPool> | |
382 CapturePreconnectsSSLSocketPool; | |
383 | |
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) {} | |
389 | |
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) { | |
396 } | |
397 | |
398 template <> | |
399 CapturePreconnectsSSLSocketPool::CapturePreconnectsSocketPool( | |
400 HostResolver* /* host_resolver */, | |
401 CertVerifier* cert_verifier) | |
402 : SSLClientSocketPool(0, | |
403 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) { | |
419 } | |
420 | |
421 class HttpStreamFactoryTest : public ::testing::Test, | |
422 public ::testing::WithParamInterface<NextProto> { | |
423 }; | |
424 | |
425 INSTANTIATE_TEST_CASE_P( | |
426 NextProto, | |
427 HttpStreamFactoryTest, | |
428 testing::Values(kProtoSPDY31, kProtoSPDY4_14, kProtoSPDY4_15)); | |
429 | |
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()); | |
455 } | |
456 } | |
457 | |
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()); | |
484 } | |
485 } | |
486 | |
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()); | |
513 } | |
514 } | |
515 | |
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); | |
523 | |
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)); | |
529 | |
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()); | |
551 } | |
552 } | |
553 | |
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)); | |
559 | |
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()); | |
573 | |
574 PreconnectHelperForURL(1, GURL("http://www.google.com:7"), session.get()); | |
575 | |
576 EXPECT_EQ(-1, transport_conn_pool->last_num_streams()); | |
577 } | |
578 | |
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)); | |
583 | |
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); | |
588 | |
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); | |
593 | |
594 scoped_refptr<HttpNetworkSession> session( | |
595 SpdySessionDependencies::SpdyCreateSession(&session_deps)); | |
596 | |
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"); | |
602 | |
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(); | |
610 | |
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()); | |
617 } | |
618 | |
619 TEST_P(HttpStreamFactoryTest, PrivacyModeDisablesChannelId) { | |
620 SpdySessionDependencies session_deps( | |
621 GetParam(), ProxyService::CreateDirect()); | |
622 | |
623 StaticSocketDataProvider socket_data; | |
624 socket_data.set_connect_data(MockConnect(ASYNC, OK)); | |
625 session_deps.socket_factory->AddSocketDataProvider(&socket_data); | |
626 | |
627 SSLSocketDataProvider ssl(ASYNC, OK); | |
628 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl); | |
629 | |
630 scoped_refptr<HttpNetworkSession> session( | |
631 SpdySessionDependencies::SpdyCreateSession(&session_deps)); | |
632 | |
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); | |
637 | |
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; | |
643 | |
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(); | |
651 | |
652 // The stream shouldn't come from spdy as we are using different privacy mode | |
653 EXPECT_FALSE(request->using_spdy()); | |
654 | |
655 SSLConfig used_ssl_config = waiter.used_ssl_config(); | |
656 EXPECT_EQ(used_ssl_config.channel_id_enabled, ssl_config.channel_id_enabled); | |
657 } | |
658 | |
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()); | |
668 } | |
669 return count; | |
670 } | |
671 } // namespace | |
672 | |
673 TEST_P(HttpStreamFactoryTest, PrivacyModeUsesDifferentSocketPoolGroup) { | |
674 SpdySessionDependencies session_deps( | |
675 GetParam(), ProxyService::CreateDirect()); | |
676 | |
677 StaticSocketDataProvider socket_data; | |
678 socket_data.set_connect_data(MockConnect(ASYNC, OK)); | |
679 session_deps.socket_factory->AddSocketDataProvider(&socket_data); | |
680 | |
681 SSLSocketDataProvider ssl(ASYNC, OK); | |
682 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl); | |
683 | |
684 scoped_refptr<HttpNetworkSession> session( | |
685 SpdySessionDependencies::SpdyCreateSession(&session_deps)); | |
686 SSLClientSocketPool* ssl_pool = session->GetSSLSocketPool( | |
687 HttpNetworkSession::NORMAL_SOCKET_POOL); | |
688 | |
689 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 0); | |
690 | |
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; | |
696 | |
697 SSLConfig ssl_config; | |
698 StreamRequestWaiter waiter; | |
699 | |
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(); | |
705 | |
706 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 1); | |
707 | |
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(); | |
713 | |
714 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 1); | |
715 | |
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(); | |
722 | |
723 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 2); | |
724 } | |
725 | |
726 TEST_P(HttpStreamFactoryTest, GetLoadState) { | |
727 SpdySessionDependencies session_deps( | |
728 GetParam(), ProxyService::CreateDirect()); | |
729 | |
730 StaticSocketDataProvider socket_data; | |
731 socket_data.set_connect_data(MockConnect(ASYNC, OK)); | |
732 session_deps.socket_factory->AddSocketDataProvider(&socket_data); | |
733 | |
734 scoped_refptr<HttpNetworkSession> session( | |
735 SpdySessionDependencies::SpdyCreateSession(&session_deps)); | |
736 | |
737 HttpRequestInfo request_info; | |
738 request_info.method = "GET"; | |
739 request_info.url = GURL("http://www.google.com"); | |
740 | |
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())); | |
747 | |
748 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, request->GetLoadState()); | |
749 | |
750 waiter.WaitForStream(); | |
751 } | |
752 | |
753 TEST_P(HttpStreamFactoryTest, RequestHttpStream) { | |
754 SpdySessionDependencies session_deps( | |
755 GetParam(), ProxyService::CreateDirect()); | |
756 | |
757 StaticSocketDataProvider socket_data; | |
758 socket_data.set_connect_data(MockConnect(ASYNC, OK)); | |
759 session_deps.socket_factory->AddSocketDataProvider(&socket_data); | |
760 | |
761 scoped_refptr<HttpNetworkSession> session( | |
762 SpdySessionDependencies::SpdyCreateSession(&session_deps)); | |
763 | |
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; | |
770 | |
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()); | |
786 | |
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()); | |
797 } | |
798 | |
799 TEST_P(HttpStreamFactoryTest, RequestHttpStreamOverSSL) { | |
800 SpdySessionDependencies session_deps( | |
801 GetParam(), ProxyService::CreateDirect()); | |
802 | |
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); | |
807 | |
808 SSLSocketDataProvider ssl_socket_data(ASYNC, OK); | |
809 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data); | |
810 | |
811 scoped_refptr<HttpNetworkSession> session( | |
812 SpdySessionDependencies::SpdyCreateSession(&session_deps)); | |
813 | |
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; | |
819 | |
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()); | |
845 } | |
846 | |
847 TEST_P(HttpStreamFactoryTest, RequestHttpStreamOverProxy) { | |
848 SpdySessionDependencies session_deps( | |
849 GetParam(), ProxyService::CreateFixed("myproxy:8888")); | |
850 | |
851 StaticSocketDataProvider socket_data; | |
852 socket_data.set_connect_data(MockConnect(ASYNC, OK)); | |
853 session_deps.socket_factory->AddSocketDataProvider(&socket_data); | |
854 | |
855 scoped_refptr<HttpNetworkSession> session( | |
856 SpdySessionDependencies::SpdyCreateSession(&session_deps)); | |
857 | |
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; | |
864 | |
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()); | |
897 } | |
898 | |
899 TEST_P(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStream) { | |
900 SpdySessionDependencies session_deps( | |
901 GetParam(), ProxyService::CreateDirect()); | |
902 | |
903 StaticSocketDataProvider socket_data; | |
904 socket_data.set_connect_data(MockConnect(ASYNC, OK)); | |
905 session_deps.socket_factory->AddSocketDataProvider(&socket_data); | |
906 | |
907 scoped_refptr<HttpNetworkSession> session( | |
908 SpdySessionDependencies::SpdyCreateSession(&session_deps)); | |
909 | |
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; | |
915 | |
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()); | |
941 } | |
942 | |
943 TEST_P(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStreamOverSSL) { | |
944 SpdySessionDependencies session_deps( | |
945 GetParam(), ProxyService::CreateDirect()); | |
946 | |
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); | |
951 | |
952 SSLSocketDataProvider ssl_socket_data(ASYNC, OK); | |
953 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data); | |
954 | |
955 scoped_refptr<HttpNetworkSession> session( | |
956 SpdySessionDependencies::SpdyCreateSession(&session_deps)); | |
957 | |
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; | |
963 | |
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()); | |
989 } | |
990 | |
991 TEST_P(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStreamOverProxy) { | |
992 SpdySessionDependencies session_deps( | |
993 GetParam(), ProxyService::CreateFixed("myproxy:8888")); | |
994 | |
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); | |
999 | |
1000 scoped_refptr<HttpNetworkSession> session( | |
1001 SpdySessionDependencies::SpdyCreateSession(&session_deps)); | |
1002 | |
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; | |
1008 | |
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()); | |
1045 } | |
1046 | |
1047 TEST_P(HttpStreamFactoryTest, RequestSpdyHttpStream) { | |
1048 SpdySessionDependencies session_deps(GetParam(), | |
1049 ProxyService::CreateDirect()); | |
1050 | |
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); | |
1056 | |
1057 SSLSocketDataProvider ssl_socket_data(ASYNC, OK); | |
1058 ssl_socket_data.SetNextProto(GetParam()); | |
1059 session_deps.deterministic_socket_factory->AddSSLSocketDataProvider( | |
1060 &ssl_socket_data); | |
1061 | |
1062 HostPortPair host_port_pair("www.google.com", 443); | |
1063 scoped_refptr<HttpNetworkSession> | |
1064 session(SpdySessionDependencies::SpdyCreateSessionDeterministic( | |
1065 &session_deps)); | |
1066 | |
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; | |
1072 | |
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()); | |
1098 } | |
1099 | |
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()); | |
1106 | |
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); | |
1111 | |
1112 SSLSocketDataProvider ssl_socket_data(ASYNC, OK); | |
1113 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data); | |
1114 | |
1115 HostPortPair host_port_pair("www.google.com", 80); | |
1116 scoped_refptr<HttpNetworkSession> | |
1117 session(SpdySessionDependencies::SpdyCreateSession(&session_deps)); | |
1118 | |
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; | |
1124 | |
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()); | |
1143 | |
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()); | |
1151 } | |
1152 | |
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()); | |
1157 | |
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); | |
1162 | |
1163 SSLSocketDataProvider ssl_socket_data(ASYNC, OK); | |
1164 ssl_socket_data.SetNextProto(GetParam()); | |
1165 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data); | |
1166 | |
1167 HostPortPair host_port_pair("www.google.com", 80); | |
1168 scoped_refptr<HttpNetworkSession> | |
1169 session(SpdySessionDependencies::SpdyCreateSession(&session_deps)); | |
1170 | |
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; | |
1176 | |
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()); | |
1195 | |
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()); | |
1217 | |
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()); | |
1228 } | |
1229 | |
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; | |
1235 | |
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); | |
1241 | |
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); | |
1247 | |
1248 SSLSocketDataProvider ssl_socket_data(ASYNC, OK); | |
1249 ssl_socket_data.SetNextProto(GetParam()); | |
1250 session_deps.deterministic_socket_factory->AddSSLSocketDataProvider( | |
1251 &ssl_socket_data); | |
1252 | |
1253 scoped_refptr<HttpNetworkSession> | |
1254 session(SpdySessionDependencies::SpdyCreateSessionDeterministic( | |
1255 &session_deps)); | |
1256 | |
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; | |
1262 | |
1263 session->http_server_properties()->SetAlternateProtocol( | |
1264 HostPortPair("www.google.com", 8888), 9999, NPN_SPDY_3, 1.0); | |
1265 | |
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()); | |
1284 | |
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()); | |
1297 | |
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()); | |
1301 } | |
1302 | |
1303 } // namespace | |
1304 | |
1305 } // namespace net | |
OLD | NEW |