OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 "chrome/browser/net/connection_tester.h" | 5 #include "chrome/browser/net/connection_tester.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/compiler_specific.h" | 8 #include "base/compiler_specific.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
| 11 #include "base/thread_restrictions.h" |
11 #include "base/utf_string_conversions.h" | 12 #include "base/utf_string_conversions.h" |
12 #include "chrome/browser/importer/firefox_proxy_settings.h" | 13 #include "chrome/browser/importer/firefox_proxy_settings.h" |
13 #include "chrome/browser/io_thread.h" | |
14 #include "chrome/common/chrome_switches.h" | 14 #include "chrome/common/chrome_switches.h" |
15 #include "net/base/cert_verifier.h" | 15 #include "net/base/cert_verifier.h" |
16 #include "net/base/cookie_monster.h" | 16 #include "net/base/cookie_monster.h" |
17 #include "net/base/dnsrr_resolver.h" | 17 #include "net/base/dnsrr_resolver.h" |
18 #include "net/base/host_resolver.h" | 18 #include "net/base/host_resolver.h" |
19 #include "net/base/host_resolver_impl.h" | 19 #include "net/base/host_resolver_impl.h" |
20 #include "net/base/io_buffer.h" | 20 #include "net/base/io_buffer.h" |
21 #include "net/base/net_errors.h" | 21 #include "net/base/net_errors.h" |
22 #include "net/base/net_util.h" | 22 #include "net/base/net_util.h" |
23 #include "net/base/ssl_config_service_defaults.h" | 23 #include "net/base/ssl_config_service_defaults.h" |
24 #include "net/disk_cache/disk_cache.h" | 24 #include "net/disk_cache/disk_cache.h" |
25 #include "net/ftp/ftp_network_layer.h" | 25 #include "net/ftp/ftp_network_layer.h" |
26 #include "net/http/http_auth_handler_factory.h" | 26 #include "net/http/http_auth_handler_factory.h" |
27 #include "net/http/http_cache.h" | 27 #include "net/http/http_cache.h" |
28 #include "net/http/http_network_layer.h" | 28 #include "net/http/http_network_layer.h" |
29 #include "net/proxy/proxy_config_service_fixed.h" | 29 #include "net/proxy/proxy_config_service_fixed.h" |
| 30 #include "net/proxy/proxy_script_fetcher_impl.h" |
30 #include "net/url_request/url_request.h" | 31 #include "net/url_request/url_request.h" |
31 #include "net/url_request/url_request_context.h" | 32 #include "net/url_request/url_request_context.h" |
32 | 33 |
33 namespace { | 34 namespace { |
34 | 35 |
35 // ExperimentURLRequestContext ------------------------------------------------ | 36 // ExperimentURLRequestContext ------------------------------------------------ |
36 | 37 |
37 // An instance of ExperimentURLRequestContext is created for each experiment | 38 // An instance of ExperimentURLRequestContext is created for each experiment |
38 // run by ConnectionTester. The class initializes network dependencies according | 39 // run by ConnectionTester. The class initializes network dependencies according |
39 // to the specified "experiment". | 40 // to the specified "experiment". |
40 class ExperimentURLRequestContext : public URLRequestContext { | 41 class ExperimentURLRequestContext : public URLRequestContext { |
41 public: | 42 public: |
42 explicit ExperimentURLRequestContext(IOThread* io_thread) | 43 explicit ExperimentURLRequestContext(URLRequestContext* proxy_request_context) |
43 : io_thread_(io_thread) {} | 44 : proxy_request_context_(proxy_request_context) {} |
44 | 45 |
45 int Init(const ConnectionTester::Experiment& experiment) { | 46 int Init(const ConnectionTester::Experiment& experiment) { |
46 int rv; | 47 int rv; |
47 | 48 |
48 // Create a custom HostResolver for this experiment. | 49 // Create a custom HostResolver for this experiment. |
49 rv = CreateHostResolver(experiment.host_resolver_experiment, | 50 rv = CreateHostResolver(experiment.host_resolver_experiment, |
50 &host_resolver_); | 51 &host_resolver_); |
51 if (rv != net::OK) | 52 if (rv != net::OK) |
52 return rv; // Failure. | 53 return rv; // Failure. |
53 | 54 |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
122 return net::ERR_UNEXPECTED; | 123 return net::ERR_UNEXPECTED; |
123 } | 124 } |
124 } | 125 } |
125 | 126 |
126 // Creates a proxy config service for |experiment|. On success returns net::OK | 127 // Creates a proxy config service for |experiment|. On success returns net::OK |
127 // and fills |config_service| with a new pointer. Otherwise returns a network | 128 // and fills |config_service| with a new pointer. Otherwise returns a network |
128 // error code. | 129 // error code. |
129 int CreateProxyConfigService( | 130 int CreateProxyConfigService( |
130 ConnectionTester::ProxySettingsExperiment experiment, | 131 ConnectionTester::ProxySettingsExperiment experiment, |
131 scoped_ptr<net::ProxyConfigService>* config_service) { | 132 scoped_ptr<net::ProxyConfigService>* config_service) { |
| 133 scoped_ptr<base::ThreadRestrictions::ScopedAllowIO> allow_io; |
132 switch (experiment) { | 134 switch (experiment) { |
133 case ConnectionTester::PROXY_EXPERIMENT_USE_SYSTEM_SETTINGS: | 135 case ConnectionTester::PROXY_EXPERIMENT_USE_SYSTEM_SETTINGS: |
134 return CreateSystemProxyConfigService(config_service); | 136 return CreateSystemProxyConfigService(config_service); |
135 case ConnectionTester::PROXY_EXPERIMENT_USE_FIREFOX_SETTINGS: | 137 case ConnectionTester::PROXY_EXPERIMENT_USE_FIREFOX_SETTINGS: |
| 138 // http://crbug.com/67664: This call can lead to blocking IO on the IO |
| 139 // thread. This is a bug and should be fixed. |
| 140 allow_io.reset(new base::ThreadRestrictions::ScopedAllowIO); |
136 return CreateFirefoxProxyConfigService(config_service); | 141 return CreateFirefoxProxyConfigService(config_service); |
137 case ConnectionTester::PROXY_EXPERIMENT_USE_AUTO_DETECT: | 142 case ConnectionTester::PROXY_EXPERIMENT_USE_AUTO_DETECT: |
138 config_service->reset(new net::ProxyConfigServiceFixed( | 143 config_service->reset(new net::ProxyConfigServiceFixed( |
139 net::ProxyConfig::CreateAutoDetect())); | 144 net::ProxyConfig::CreateAutoDetect())); |
140 return net::OK; | 145 return net::OK; |
141 case ConnectionTester::PROXY_EXPERIMENT_USE_DIRECT: | 146 case ConnectionTester::PROXY_EXPERIMENT_USE_DIRECT: |
142 config_service->reset(new net::ProxyConfigServiceFixed( | 147 config_service->reset(new net::ProxyConfigServiceFixed( |
143 net::ProxyConfig::CreateDirect())); | 148 net::ProxyConfig::CreateDirect())); |
144 return net::OK; | 149 return net::OK; |
145 default: | 150 default: |
(...skipping 17 matching lines...) Expand all Loading... |
163 if (CommandLine::ForCurrentProcess()->HasSwitch( | 168 if (CommandLine::ForCurrentProcess()->HasSwitch( |
164 switches::kSingleProcess)) { | 169 switches::kSingleProcess)) { |
165 // We can't create a standard proxy resolver in single-process mode. | 170 // We can't create a standard proxy resolver in single-process mode. |
166 // Rather than falling-back to some other implementation, fail. | 171 // Rather than falling-back to some other implementation, fail. |
167 return net::ERR_NOT_IMPLEMENTED; | 172 return net::ERR_NOT_IMPLEMENTED; |
168 } | 173 } |
169 | 174 |
170 *proxy_service = net::ProxyService::CreateUsingV8ProxyResolver( | 175 *proxy_service = net::ProxyService::CreateUsingV8ProxyResolver( |
171 config_service.release(), | 176 config_service.release(), |
172 0u, | 177 0u, |
173 io_thread_->CreateAndRegisterProxyScriptFetcher(this), | 178 new net::ProxyScriptFetcherImpl(proxy_request_context_), |
174 host_resolver(), | 179 host_resolver(), |
175 NULL); | 180 NULL); |
176 | 181 |
177 return net::OK; | 182 return net::OK; |
178 } | 183 } |
179 | 184 |
180 // Creates a proxy config service that pulls from the system proxy settings. | 185 // Creates a proxy config service that pulls from the system proxy settings. |
181 // On success returns net::OK and fills |config_service| with a new pointer. | 186 // On success returns net::OK and fills |config_service| with a new pointer. |
182 // Otherwise returns a network error code. | 187 // Otherwise returns a network error code. |
183 int CreateSystemProxyConfigService( | 188 int CreateSystemProxyConfigService( |
(...skipping 26 matching lines...) Expand all Loading... |
210 | 215 |
211 net::ProxyConfig config; | 216 net::ProxyConfig config; |
212 if (firefox_settings.ToProxyConfig(&config)) { | 217 if (firefox_settings.ToProxyConfig(&config)) { |
213 config_service->reset(new net::ProxyConfigServiceFixed(config)); | 218 config_service->reset(new net::ProxyConfigServiceFixed(config)); |
214 return net::OK; | 219 return net::OK; |
215 } | 220 } |
216 | 221 |
217 return net::ERR_FAILED; | 222 return net::ERR_FAILED; |
218 } | 223 } |
219 | 224 |
220 IOThread* io_thread_; | 225 const scoped_refptr<URLRequestContext> proxy_request_context_; |
221 }; | 226 }; |
222 | 227 |
223 } // namespace | 228 } // namespace |
224 | 229 |
225 // ConnectionTester::TestRunner ---------------------------------------------- | 230 // ConnectionTester::TestRunner ---------------------------------------------- |
226 | 231 |
227 // TestRunner is a helper class for running an individual experiment. It can | 232 // TestRunner is a helper class for running an individual experiment. It can |
228 // be deleted any time after it is started, and this will abort the request. | 233 // be deleted any time after it is started, and this will abort the request. |
229 class ConnectionTester::TestRunner : public net::URLRequest::Delegate { | 234 class ConnectionTester::TestRunner : public net::URLRequest::Delegate { |
230 public: | 235 public: |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
298 if (!request->status().is_success()) { | 303 if (!request->status().is_success()) { |
299 DCHECK_NE(net::ERR_IO_PENDING, request->status().os_error()); | 304 DCHECK_NE(net::ERR_IO_PENDING, request->status().os_error()); |
300 result = request->status().os_error(); | 305 result = request->status().os_error(); |
301 } | 306 } |
302 tester_->OnExperimentCompleted(result); | 307 tester_->OnExperimentCompleted(result); |
303 } | 308 } |
304 | 309 |
305 void ConnectionTester::TestRunner::Run(const Experiment& experiment) { | 310 void ConnectionTester::TestRunner::Run(const Experiment& experiment) { |
306 // Try to create a URLRequestContext for this experiment. | 311 // Try to create a URLRequestContext for this experiment. |
307 scoped_refptr<ExperimentURLRequestContext> context( | 312 scoped_refptr<ExperimentURLRequestContext> context( |
308 new ExperimentURLRequestContext(tester_->io_thread_)); | 313 new ExperimentURLRequestContext(tester_->proxy_request_context_)); |
309 int rv = context->Init(experiment); | 314 int rv = context->Init(experiment); |
310 if (rv != net::OK) { | 315 if (rv != net::OK) { |
311 // Complete the experiment with a failure. | 316 // Complete the experiment with a failure. |
312 tester_->OnExperimentCompleted(rv); | 317 tester_->OnExperimentCompleted(rv); |
313 return; | 318 return; |
314 } | 319 } |
315 | 320 |
316 // Fetch a request using the experimental context. | 321 // Fetch a request using the experimental context. |
317 request_.reset(new net::URLRequest(experiment.url, this)); | 322 request_.reset(new net::URLRequest(experiment.url, this)); |
318 request_->set_context(context); | 323 request_->set_context(context); |
319 request_->Start(); | 324 request_->Start(); |
320 } | 325 } |
321 | 326 |
322 // ConnectionTester ---------------------------------------------------------- | 327 // ConnectionTester ---------------------------------------------------------- |
323 | 328 |
324 ConnectionTester::ConnectionTester(Delegate* delegate, IOThread* io_thread) | 329 ConnectionTester::ConnectionTester(Delegate* delegate, |
325 : delegate_(delegate), io_thread_(io_thread) { | 330 URLRequestContext* proxy_request_context) |
| 331 : delegate_(delegate), proxy_request_context_(proxy_request_context) { |
326 DCHECK(delegate); | 332 DCHECK(delegate); |
327 DCHECK(io_thread); | 333 DCHECK(proxy_request_context); |
328 } | 334 } |
329 | 335 |
330 ConnectionTester::~ConnectionTester() { | 336 ConnectionTester::~ConnectionTester() { |
331 // Cancellation happens automatically by deleting test_runner_. | 337 // Cancellation happens automatically by deleting test_runner_. |
332 } | 338 } |
333 | 339 |
334 void ConnectionTester::RunAllTests(const GURL& url) { | 340 void ConnectionTester::RunAllTests(const GURL& url) { |
335 // Select all possible experiments to run. (In no particular order). | 341 // Select all possible experiments to run. (In no particular order). |
336 // It is possible that some of these experiments are actually duplicates. | 342 // It is possible that some of these experiments are actually duplicates. |
337 GetAllPossibleExperimentCombinations(url, &remaining_experiments_); | 343 GetAllPossibleExperimentCombinations(url, &remaining_experiments_); |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
415 | 421 |
416 // Notify the delegate of completion. | 422 // Notify the delegate of completion. |
417 delegate_->OnCompletedConnectionTestExperiment(current, result); | 423 delegate_->OnCompletedConnectionTestExperiment(current, result); |
418 | 424 |
419 if (remaining_experiments_.empty()) { | 425 if (remaining_experiments_.empty()) { |
420 delegate_->OnCompletedConnectionTestSuite(); | 426 delegate_->OnCompletedConnectionTestSuite(); |
421 } else { | 427 } else { |
422 StartNextExperiment(); | 428 StartNextExperiment(); |
423 } | 429 } |
424 } | 430 } |
OLD | NEW |