OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/http/http_stream_factory_impl.h" | 5 #include "net/http/http_stream_factory_impl.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
10 #include "net/base/capturing_net_log.h" | |
11 #include "net/base/cert_verifier.h" | 10 #include "net/base/cert_verifier.h" |
12 #include "net/base/mock_host_resolver.h" | 11 #include "net/base/mock_host_resolver.h" |
13 #include "net/base/net_log.h" | 12 #include "net/base/net_log.h" |
14 #include "net/base/ssl_config_service_defaults.h" | 13 #include "net/base/ssl_config_service_defaults.h" |
15 #include "net/base/test_completion_callback.h" | 14 #include "net/base/test_completion_callback.h" |
16 #include "net/http/http_auth_handler_factory.h" | 15 #include "net/http/http_auth_handler_factory.h" |
17 #include "net/http/http_network_session.h" | 16 #include "net/http/http_network_session.h" |
18 #include "net/http/http_network_session_peer.h" | 17 #include "net/http/http_network_session_peer.h" |
19 #include "net/http/http_request_info.h" | 18 #include "net/http/http_request_info.h" |
20 #include "net/http/http_server_properties_impl.h" | 19 #include "net/http/http_server_properties_impl.h" |
(...skipping 21 matching lines...) Expand all Loading... |
42 void WaitForPreconnects() { | 41 void WaitForPreconnects() { |
43 while (!preconnect_done_) { | 42 while (!preconnect_done_) { |
44 waiting_for_preconnect_ = true; | 43 waiting_for_preconnect_ = true; |
45 MessageLoop::current()->Run(); | 44 MessageLoop::current()->Run(); |
46 waiting_for_preconnect_ = false; | 45 waiting_for_preconnect_ = false; |
47 } | 46 } |
48 } | 47 } |
49 | 48 |
50 private: | 49 private: |
51 // HttpStreamFactoryImpl methods. | 50 // HttpStreamFactoryImpl methods. |
52 virtual void OnPreconnectsCompleteInternal() { | 51 virtual void OnPreconnectsCompleteInternal() OVERRIDE { |
53 preconnect_done_ = true; | 52 preconnect_done_ = true; |
54 if (waiting_for_preconnect_) | 53 if (waiting_for_preconnect_) |
55 MessageLoop::current()->Quit(); | 54 MessageLoop::current()->Quit(); |
56 } | 55 } |
57 | 56 |
58 bool preconnect_done_; | 57 bool preconnect_done_; |
59 bool waiting_for_preconnect_; | 58 bool waiting_for_preconnect_; |
60 }; | 59 }; |
61 | 60 |
62 class StreamRequestWaiter : public HttpStreamRequest::Delegate { | 61 class StreamRequestWaiter : public HttpStreamRequest::Delegate { |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 bool ssl; | 154 bool ssl; |
156 }; | 155 }; |
157 | 156 |
158 TestCase kTests[] = { | 157 TestCase kTests[] = { |
159 { 1, false }, | 158 { 1, false }, |
160 { 2, false }, | 159 { 2, false }, |
161 { 1, true}, | 160 { 1, true}, |
162 { 2, true}, | 161 { 2, true}, |
163 }; | 162 }; |
164 | 163 |
165 void PreconnectHelper(const TestCase& test, | 164 void PreconnectHelperForURL(int num_streams, |
166 HttpNetworkSession* session) { | 165 const GURL& url, |
| 166 HttpNetworkSession* session) { |
167 HttpNetworkSessionPeer peer(session); | 167 HttpNetworkSessionPeer peer(session); |
168 MockHttpStreamFactoryImpl* mock_factory = | 168 MockHttpStreamFactoryImpl* mock_factory = |
169 new MockHttpStreamFactoryImpl(session); | 169 new MockHttpStreamFactoryImpl(session); |
170 peer.SetHttpStreamFactory(mock_factory); | 170 peer.SetHttpStreamFactory(mock_factory); |
171 SSLConfig ssl_config; | 171 SSLConfig ssl_config; |
172 session->ssl_config_service()->GetSSLConfig(&ssl_config); | 172 session->ssl_config_service()->GetSSLConfig(&ssl_config); |
173 | 173 |
174 HttpRequestInfo request; | 174 HttpRequestInfo request; |
175 request.method = "GET"; | 175 request.method = "GET"; |
176 request.url = test.ssl ? GURL("https://www.google.com") : | 176 request.url = url; |
177 GURL("http://www.google.com"); | |
178 request.load_flags = 0; | 177 request.load_flags = 0; |
179 | 178 |
180 ProxyInfo proxy_info; | 179 session->http_stream_factory()->PreconnectStreams( |
181 TestOldCompletionCallback callback; | 180 num_streams, request, ssl_config, ssl_config, BoundNetLog()); |
| 181 mock_factory->WaitForPreconnects(); |
| 182 }; |
182 | 183 |
183 session->http_stream_factory()->PreconnectStreams( | 184 void PreconnectHelper(const TestCase& test, |
184 test.num_streams, request, ssl_config, ssl_config, BoundNetLog()); | 185 HttpNetworkSession* session) { |
185 mock_factory->WaitForPreconnects(); | 186 GURL url = test.ssl ? GURL("https://www.google.com") : |
| 187 GURL("http://www.google.com"); |
| 188 PreconnectHelperForURL(test.num_streams, url, session); |
186 }; | 189 }; |
187 | 190 |
188 template<typename ParentPool> | 191 template<typename ParentPool> |
189 class CapturePreconnectsSocketPool : public ParentPool { | 192 class CapturePreconnectsSocketPool : public ParentPool { |
190 public: | 193 public: |
191 CapturePreconnectsSocketPool(HostResolver* host_resolver, | 194 CapturePreconnectsSocketPool(HostResolver* host_resolver, |
192 CertVerifier* cert_verifier); | 195 CertVerifier* cert_verifier); |
193 | 196 |
194 int last_num_streams() const { | 197 int last_num_streams() const { |
195 return last_num_streams_; | 198 return last_num_streams_; |
196 } | 199 } |
197 | 200 |
198 virtual int RequestSocket(const std::string& group_name, | 201 virtual int RequestSocket(const std::string& group_name, |
199 const void* socket_params, | 202 const void* socket_params, |
200 RequestPriority priority, | 203 RequestPriority priority, |
201 ClientSocketHandle* handle, | 204 ClientSocketHandle* handle, |
202 OldCompletionCallback* callback, | 205 OldCompletionCallback* callback, |
203 const BoundNetLog& net_log) { | 206 const BoundNetLog& net_log) OVERRIDE { |
204 ADD_FAILURE(); | 207 ADD_FAILURE(); |
205 return ERR_UNEXPECTED; | 208 return ERR_UNEXPECTED; |
206 } | 209 } |
207 | 210 |
208 virtual void RequestSockets(const std::string& group_name, | 211 virtual void RequestSockets(const std::string& group_name, |
209 const void* socket_params, | 212 const void* socket_params, |
210 int num_sockets, | 213 int num_sockets, |
211 const BoundNetLog& net_log) { | 214 const BoundNetLog& net_log) OVERRIDE { |
212 last_num_streams_ = num_sockets; | 215 last_num_streams_ = num_sockets; |
213 } | 216 } |
214 | 217 |
215 virtual void CancelRequest(const std::string& group_name, | 218 virtual void CancelRequest(const std::string& group_name, |
216 ClientSocketHandle* handle) { | 219 ClientSocketHandle* handle) OVERRIDE { |
217 ADD_FAILURE(); | 220 ADD_FAILURE(); |
218 } | 221 } |
219 virtual void ReleaseSocket(const std::string& group_name, | 222 virtual void ReleaseSocket(const std::string& group_name, |
220 StreamSocket* socket, | 223 StreamSocket* socket, |
221 int id) { | 224 int id) OVERRIDE { |
222 ADD_FAILURE(); | 225 ADD_FAILURE(); |
223 } | 226 } |
224 virtual void CloseIdleSockets() { | 227 virtual void CloseIdleSockets() OVERRIDE { |
225 ADD_FAILURE(); | 228 ADD_FAILURE(); |
226 } | 229 } |
227 virtual int IdleSocketCount() const { | 230 virtual int IdleSocketCount() const OVERRIDE { |
228 ADD_FAILURE(); | 231 ADD_FAILURE(); |
229 return 0; | 232 return 0; |
230 } | 233 } |
231 virtual int IdleSocketCountInGroup(const std::string& group_name) const { | 234 virtual int IdleSocketCountInGroup( |
| 235 const std::string& group_name) const OVERRIDE { |
232 ADD_FAILURE(); | 236 ADD_FAILURE(); |
233 return 0; | 237 return 0; |
234 } | 238 } |
235 virtual LoadState GetLoadState(const std::string& group_name, | 239 virtual LoadState GetLoadState( |
236 const ClientSocketHandle* handle) const { | 240 const std::string& group_name, |
| 241 const ClientSocketHandle* handle) const OVERRIDE { |
237 ADD_FAILURE(); | 242 ADD_FAILURE(); |
238 return LOAD_STATE_IDLE; | 243 return LOAD_STATE_IDLE; |
239 } | 244 } |
240 virtual base::TimeDelta ConnectionTimeout() const { | 245 virtual base::TimeDelta ConnectionTimeout() const OVERRIDE { |
241 return base::TimeDelta(); | 246 return base::TimeDelta(); |
242 } | 247 } |
243 | 248 |
244 private: | 249 private: |
245 int last_num_streams_; | 250 int last_num_streams_; |
246 }; | 251 }; |
247 | 252 |
248 typedef CapturePreconnectsSocketPool<TransportClientSocketPool> | 253 typedef CapturePreconnectsSocketPool<TransportClientSocketPool> |
249 CapturePreconnectsTransportSocketPool; | 254 CapturePreconnectsTransportSocketPool; |
250 typedef CapturePreconnectsSocketPool<HttpProxyClientSocketPool> | 255 typedef CapturePreconnectsSocketPool<HttpProxyClientSocketPool> |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
382 PreconnectHelper(kTests[i], session); | 387 PreconnectHelper(kTests[i], session); |
383 // We shouldn't be preconnecting if we have an existing session, which is | 388 // We shouldn't be preconnecting if we have an existing session, which is |
384 // the case for https://www.google.com. | 389 // the case for https://www.google.com. |
385 if (kTests[i].ssl) | 390 if (kTests[i].ssl) |
386 EXPECT_EQ(-1, ssl_conn_pool->last_num_streams()); | 391 EXPECT_EQ(-1, ssl_conn_pool->last_num_streams()); |
387 else | 392 else |
388 EXPECT_EQ(kTests[i].num_streams, transport_conn_pool->last_num_streams()); | 393 EXPECT_EQ(kTests[i].num_streams, transport_conn_pool->last_num_streams()); |
389 } | 394 } |
390 } | 395 } |
391 | 396 |
| 397 // Verify that preconnects to unsafe ports are cancelled before they reach |
| 398 // the SocketPool. |
| 399 TEST(HttpStreamFactoryTest, PreconnectUnsafePort) { |
| 400 ASSERT_FALSE(IsPortAllowedByDefault(7)); |
| 401 ASSERT_FALSE(IsPortAllowedByOverride(7)); |
| 402 |
| 403 SessionDependencies session_deps(ProxyService::CreateDirect()); |
| 404 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); |
| 405 HttpNetworkSessionPeer peer(session); |
| 406 CapturePreconnectsTransportSocketPool* transport_conn_pool = |
| 407 new CapturePreconnectsTransportSocketPool( |
| 408 session_deps.host_resolver.get(), |
| 409 session_deps.cert_verifier.get()); |
| 410 MockClientSocketPoolManager* mock_pool_manager = |
| 411 new MockClientSocketPoolManager; |
| 412 mock_pool_manager->SetTransportSocketPool(transport_conn_pool); |
| 413 peer.SetClientSocketPoolManager(mock_pool_manager); |
| 414 |
| 415 PreconnectHelperForURL(1, GURL("http://www.google.com:7"), session); |
| 416 |
| 417 EXPECT_EQ(-1, transport_conn_pool->last_num_streams()); |
| 418 } |
| 419 |
392 TEST(HttpStreamFactoryTest, JobNotifiesProxy) { | 420 TEST(HttpStreamFactoryTest, JobNotifiesProxy) { |
393 const char* kProxyString = "PROXY bad:99; PROXY maybe:80; DIRECT"; | 421 const char* kProxyString = "PROXY bad:99; PROXY maybe:80; DIRECT"; |
394 SessionDependencies session_deps( | 422 SessionDependencies session_deps( |
395 ProxyService::CreateFixedFromPacResult(kProxyString)); | 423 ProxyService::CreateFixedFromPacResult(kProxyString)); |
396 | 424 |
397 // First connection attempt fails | 425 // First connection attempt fails |
398 StaticSocketDataProvider socket_data1; | 426 StaticSocketDataProvider socket_data1; |
399 socket_data1.set_connect_data(MockConnect(true, ERR_ADDRESS_UNREACHABLE)); | 427 socket_data1.set_connect_data(MockConnect(true, ERR_ADDRESS_UNREACHABLE)); |
400 session_deps.socket_factory.AddSocketDataProvider(&socket_data1); | 428 session_deps.socket_factory.AddSocketDataProvider(&socket_data1); |
401 | 429 |
402 // Second connection attempt succeeds | 430 // Second connection attempt succeeds |
403 StaticSocketDataProvider socket_data2; | 431 StaticSocketDataProvider socket_data2; |
404 socket_data2.set_connect_data(MockConnect(true, OK)); | 432 socket_data2.set_connect_data(MockConnect(true, OK)); |
405 session_deps.socket_factory.AddSocketDataProvider(&socket_data2); | 433 session_deps.socket_factory.AddSocketDataProvider(&socket_data2); |
406 | 434 |
407 CapturingBoundNetLog log(CapturingNetLog::kUnbounded); | |
408 EXPECT_TRUE(log.bound().IsLoggingAllEvents()); | |
409 | |
410 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); | 435 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); |
411 | 436 |
412 // Now request a stream. It should succeed using the second proxy in the | 437 // Now request a stream. It should succeed using the second proxy in the |
413 // list. | 438 // list. |
414 HttpRequestInfo request_info; | 439 HttpRequestInfo request_info; |
415 request_info.method = "GET"; | 440 request_info.method = "GET"; |
416 request_info.url = GURL("http://www.google.com"); | 441 request_info.url = GURL("http://www.google.com"); |
417 request_info.load_flags = 0; | 442 request_info.load_flags = 0; |
418 | 443 |
419 SSLConfig ssl_config; | 444 SSLConfig ssl_config; |
420 StreamRequestWaiter waiter; | 445 StreamRequestWaiter waiter; |
421 scoped_ptr<HttpStreamRequest> request( | 446 scoped_ptr<HttpStreamRequest> request( |
422 session->http_stream_factory()->RequestStream(request_info, ssl_config, | 447 session->http_stream_factory()->RequestStream(request_info, ssl_config, |
423 ssl_config, &waiter, | 448 ssl_config, &waiter, |
424 log.bound())); | 449 BoundNetLog())); |
425 waiter.WaitForStream(); | 450 waiter.WaitForStream(); |
426 | 451 |
427 // The proxy that failed should now be known to the proxy_service as bad. | 452 // The proxy that failed should now be known to the proxy_service as bad. |
428 const ProxyRetryInfoMap& retry_info = | 453 const ProxyRetryInfoMap& retry_info = |
429 session->proxy_service()->proxy_retry_info(); | 454 session->proxy_service()->proxy_retry_info(); |
430 EXPECT_EQ(1u, retry_info.size()); | 455 EXPECT_EQ(1u, retry_info.size()); |
431 ProxyRetryInfoMap::const_iterator iter = retry_info.find("bad:99"); | 456 ProxyRetryInfoMap::const_iterator iter = retry_info.find("bad:99"); |
432 EXPECT_TRUE(iter != retry_info.end()); | 457 EXPECT_TRUE(iter != retry_info.end()); |
433 } | 458 } |
434 | 459 |
435 } // namespace | 460 } // namespace |
436 | 461 |
437 } // namespace net | 462 } // namespace net |
OLD | NEW |