blob: aa22c10504b2f22517f3e352939e831cbac3f330 [file] [log] [blame]
[email protected]aeb53f02011-01-15 00:21:341// Copyright (c) 2011 The Chromium Authors. All rights reserved.
[email protected]0ac83682010-01-22 17:46:272// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/io_thread.h"
[email protected]e83326f2010-07-31 17:29:256
[email protected]bcefe0f2010-11-10 16:19:107#include <vector>
8
[email protected]0ac83682010-01-22 17:46:279#include "base/command_line.h"
[email protected]58580352010-10-26 04:07:5010#include "base/debug/leak_tracker.h"
[email protected]0ac83682010-01-22 17:46:2711#include "base/logging.h"
[email protected]ecd95ae2010-10-20 23:58:1712#include "base/metrics/field_trial.h"
[email protected]86933612010-10-16 23:10:3313#include "base/stl_util-inl.h"
[email protected]e83326f2010-07-31 17:29:2514#include "base/string_number_conversions.h"
[email protected]4e5ae20f2010-09-24 04:52:1115#include "base/string_split.h"
[email protected]f1d81922010-07-31 17:47:0916#include "base/string_util.h"
[email protected]34b99632011-01-01 01:01:0617#include "base/threading/thread_restrictions.h"
[email protected]addb3242011-06-13 21:39:1618#include "build/build_config.h"
[email protected]df2840d2011-02-20 16:32:3219#include "chrome/browser/browser_process.h"
[email protected]3ce02412011-03-01 12:01:1520#include "chrome/browser/extensions/extension_event_router_forwarder.h"
21#include "chrome/browser/net/chrome_network_delegate.h"
[email protected]9e743cd2010-03-16 07:03:5322#include "chrome/browser/net/chrome_net_log.h"
[email protected]0ee7a3b2010-11-09 06:13:4023#include "chrome/browser/net/chrome_url_request_context.h"
[email protected]1889dc1b2010-10-14 22:03:1324#include "chrome/browser/net/connect_interceptor.h"
[email protected]9e743cd2010-03-16 07:03:5325#include "chrome/browser/net/passive_log_collector.h"
[email protected]86933612010-10-16 23:10:3326#include "chrome/browser/net/predictor_api.h"
[email protected]db0e86dd2011-03-16 14:47:2127#include "chrome/browser/net/pref_proxy_config_service.h"
28#include "chrome/browser/net/proxy_service_factory.h"
[email protected]bcefe0f2010-11-10 16:19:1029#include "chrome/browser/prefs/pref_service.h"
[email protected]0ac83682010-01-22 17:46:2730#include "chrome/common/chrome_switches.h"
[email protected]bcefe0f2010-11-10 16:19:1031#include "chrome/common/pref_names.h"
[email protected]567812d2011-02-24 17:40:5032#include "content/browser/browser_thread.h"
[email protected]d9f37932011-05-09 20:09:2433#include "content/browser/gpu/gpu_process_host.h"
[email protected]567812d2011-02-24 17:40:5034#include "content/browser/in_process_webkit/indexed_db_key_utility_client.h"
[email protected]e9b42c12011-06-01 01:34:2335#include "content/common/url_fetcher.h"
[email protected]822581d2010-12-16 17:27:1536#include "net/base/cert_verifier.h"
[email protected]f6c21cb2011-02-16 19:45:4137#include "net/base/cookie_monster.h"
[email protected]2db580532010-10-08 14:32:3738#include "net/base/dnsrr_resolver.h"
[email protected]0ac83682010-01-22 17:46:2739#include "net/base/host_cache.h"
40#include "net/base/host_resolver.h"
[email protected]f2d8c4212010-02-02 00:56:3541#include "net/base/host_resolver_impl.h"
[email protected]86933612010-10-16 23:10:3342#include "net/base/mapped_host_resolver.h"
[email protected]32eaa332010-02-08 22:15:5443#include "net/base/net_util.h"
[email protected]933bc5c62011-04-12 19:08:0244#include "net/ftp/ftp_network_layer.h"
[email protected]eb3cac72010-02-26 21:07:4545#include "net/http/http_auth_filter.h"
[email protected]fa55e192010-02-15 14:25:5046#include "net/http/http_auth_handler_factory.h"
[email protected]2fb629202010-12-23 23:52:5747#include "net/http/http_network_layer.h"
[email protected]57cb0f72011-01-28 06:33:5848#include "net/http/http_network_session.h"
[email protected]6104ea5d2011-04-27 21:37:1249#include "net/proxy/proxy_config_service.h"
[email protected]86933612010-10-16 23:10:3350#include "net/proxy/proxy_script_fetcher_impl.h"
[email protected]6104ea5d2011-04-27 21:37:1251#include "net/proxy/proxy_service.h"
[email protected]5f6f83e2011-05-24 18:03:0852#include "net/socket/dns_cert_provenance_checker.h"
[email protected]bd0875e2011-03-25 05:13:3553#include "webkit/glue/webkit_glue.h"
[email protected]0ac83682010-01-22 17:46:2754
[email protected]77feb462011-05-16 23:37:2555#if defined(USE_NSS)
56#include "net/ocsp/nss_ocsp.h"
57#endif // defined(USE_NSS)
58
[email protected]0ac83682010-01-22 17:46:2759namespace {
60
[email protected]bd0875e2011-03-25 05:13:3561// Custom URLRequestContext used by requests which aren't associated with a
62// particular profile. We need to use a subclass of URLRequestContext in order
63// to provide the correct User-Agent.
64class URLRequestContextWithUserAgent : public net::URLRequestContext {
65 public:
66 virtual const std::string& GetUserAgent(
67 const GURL& url) const OVERRIDE {
68 return webkit_glue::GetUserAgent(url);
69 }
70};
71
[email protected]77feb462011-05-16 23:37:2572// Used for the "system" URLRequestContext. If this grows more complicated, then
73// consider inheriting directly from URLRequestContext rather than using
74// implementation inheritance.
75class SystemURLRequestContext : public URLRequestContextWithUserAgent {
76 public:
77 SystemURLRequestContext() {
78#if defined(USE_NSS)
79 net::SetURLRequestContextForOCSP(this);
80#endif // defined(USE_NSS)
81 }
82
83 private:
84 virtual ~SystemURLRequestContext() {
85#if defined(USE_NSS)
86 net::SetURLRequestContextForOCSP(NULL);
87#endif // defined(USE_NSS)
88 }
89};
90
[email protected]ee094b82010-08-24 15:55:5191net::HostResolver* CreateGlobalHostResolver(net::NetLog* net_log) {
[email protected]0ac83682010-01-22 17:46:2792 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
[email protected]962b98212010-07-17 03:37:5193
94 size_t parallelism = net::HostResolver::kDefaultParallelism;
95
96 // Use the concurrency override from the command-line, if any.
97 if (command_line.HasSwitch(switches::kHostResolverParallelism)) {
98 std::string s =
99 command_line.GetSwitchValueASCII(switches::kHostResolverParallelism);
100
101 // Parse the switch (it should be a positive integer formatted as decimal).
102 int n;
[email protected]e83326f2010-07-31 17:29:25103 if (base::StringToInt(s, &n) && n > 0) {
[email protected]962b98212010-07-17 03:37:51104 parallelism = static_cast<size_t>(n);
105 } else {
106 LOG(ERROR) << "Invalid switch for host resolver parallelism: " << s;
107 }
[email protected]ecd95ae2010-10-20 23:58:17108 } else {
109 // Set up a field trial to see what impact the total number of concurrent
110 // resolutions have on DNS resolutions.
111 base::FieldTrial::Probability kDivisor = 1000;
112 // For each option (i.e., non-default), we have a fixed probability.
113 base::FieldTrial::Probability kProbabilityPerGroup = 100; // 10%.
114
[email protected]933729bc2011-01-19 18:52:32115 // After June 30, 2011 builds, it will always be in default group
116 // (parallel_default).
[email protected]ad8e04a2010-11-01 04:16:27117 scoped_refptr<base::FieldTrial> trial(
[email protected]933729bc2011-01-19 18:52:32118 new base::FieldTrial(
119 "DnsParallelism", kDivisor, "parallel_default", 2011, 6, 30));
[email protected]ecd95ae2010-10-20 23:58:17120
121 // List options with different counts.
122 // Firefox limits total to 8 in parallel, and default is currently 50.
123 int parallel_6 = trial->AppendGroup("parallel_6", kProbabilityPerGroup);
[email protected]755a93352010-10-29 06:33:59124 int parallel_7 = trial->AppendGroup("parallel_7", kProbabilityPerGroup);
[email protected]ecd95ae2010-10-20 23:58:17125 int parallel_8 = trial->AppendGroup("parallel_8", kProbabilityPerGroup);
[email protected]755a93352010-10-29 06:33:59126 int parallel_9 = trial->AppendGroup("parallel_9", kProbabilityPerGroup);
[email protected]ecd95ae2010-10-20 23:58:17127 int parallel_10 = trial->AppendGroup("parallel_10", kProbabilityPerGroup);
128 int parallel_14 = trial->AppendGroup("parallel_14", kProbabilityPerGroup);
129 int parallel_20 = trial->AppendGroup("parallel_20", kProbabilityPerGroup);
130
[email protected]ecd95ae2010-10-20 23:58:17131 if (trial->group() == parallel_6)
132 parallelism = 6;
[email protected]755a93352010-10-29 06:33:59133 else if (trial->group() == parallel_7)
134 parallelism = 7;
[email protected]ecd95ae2010-10-20 23:58:17135 else if (trial->group() == parallel_8)
136 parallelism = 8;
[email protected]755a93352010-10-29 06:33:59137 else if (trial->group() == parallel_9)
138 parallelism = 9;
[email protected]ecd95ae2010-10-20 23:58:17139 else if (trial->group() == parallel_10)
140 parallelism = 10;
141 else if (trial->group() == parallel_14)
142 parallelism = 14;
143 else if (trial->group() == parallel_20)
144 parallelism = 20;
[email protected]962b98212010-07-17 03:37:51145 }
146
[email protected]06ef6d92011-05-19 04:24:58147 size_t retry_attempts = net::HostResolver::kDefaultRetryAttempts;
148
149 // Use the retry attempts override from the command-line, if any.
150 if (command_line.HasSwitch(switches::kHostResolverRetryAttempts)) {
151 std::string s =
152 command_line.GetSwitchValueASCII(switches::kHostResolverRetryAttempts);
153 // Parse the switch (it should be a non-negative integer).
154 int n;
155 if (base::StringToInt(s, &n) && n >= 0) {
156 retry_attempts = static_cast<size_t>(n);
157 } else {
158 LOG(ERROR) << "Invalid switch for host resolver retry attempts: " << s;
159 }
160 }
161
[email protected]962b98212010-07-17 03:37:51162 net::HostResolver* global_host_resolver =
[email protected]06ef6d92011-05-19 04:24:58163 net::CreateSystemHostResolver(parallelism, retry_attempts, net_log);
[email protected]9087aa32010-02-18 08:03:38164
[email protected]0f8f1b432010-03-16 19:06:03165 // Determine if we should disable IPv6 support.
[email protected]9087aa32010-02-18 08:03:38166 if (!command_line.HasSwitch(switches::kEnableIPv6)) {
[email protected]0f8f1b432010-03-16 19:06:03167 if (command_line.HasSwitch(switches::kDisableIPv6)) {
[email protected]46f6e202010-02-26 06:07:25168 global_host_resolver->SetDefaultAddressFamily(net::ADDRESS_FAMILY_IPV4);
[email protected]0f8f1b432010-03-16 19:06:03169 } else {
170 net::HostResolverImpl* host_resolver_impl =
171 global_host_resolver->GetAsHostResolverImpl();
172 if (host_resolver_impl != NULL) {
[email protected]780f8492010-09-16 04:12:15173 // Use probe to decide if support is warranted.
174 host_resolver_impl->ProbeIPv6Support();
[email protected]0f8f1b432010-03-16 19:06:03175 }
176 }
[email protected]9087aa32010-02-18 08:03:38177 }
178
[email protected]9087aa32010-02-18 08:03:38179 // If hostname remappings were specified on the command-line, layer these
180 // rules on top of the real host resolver. This allows forwarding all requests
181 // through a designated test server.
[email protected]0f8f1b432010-03-16 19:06:03182 if (!command_line.HasSwitch(switches::kHostResolverRules))
183 return global_host_resolver;
[email protected]0ac83682010-01-22 17:46:27184
[email protected]0f8f1b432010-03-16 19:06:03185 net::MappedHostResolver* remapped_resolver =
186 new net::MappedHostResolver(global_host_resolver);
187 remapped_resolver->SetRulesFromString(
188 command_line.GetSwitchValueASCII(switches::kHostResolverRules));
189 return remapped_resolver;
[email protected]0ac83682010-01-22 17:46:27190}
191
[email protected]58bc7042010-07-07 18:04:14192class LoggingNetworkChangeObserver
[email protected]232a5812011-03-04 22:42:08193 : public net::NetworkChangeNotifier::IPAddressObserver {
[email protected]58bc7042010-07-07 18:04:14194 public:
195 // |net_log| must remain valid throughout our lifetime.
196 explicit LoggingNetworkChangeObserver(net::NetLog* net_log)
197 : net_log_(net_log) {
[email protected]232a5812011-03-04 22:42:08198 net::NetworkChangeNotifier::AddIPAddressObserver(this);
[email protected]58bc7042010-07-07 18:04:14199 }
200
201 ~LoggingNetworkChangeObserver() {
[email protected]232a5812011-03-04 22:42:08202 net::NetworkChangeNotifier::RemoveIPAddressObserver(this);
[email protected]58bc7042010-07-07 18:04:14203 }
204
205 virtual void OnIPAddressChanged() {
[email protected]8e96e502010-10-21 20:57:12206 VLOG(1) << "Observed a change to the network IP addresses";
[email protected]58bc7042010-07-07 18:04:14207
[email protected]d3aaf3f2010-09-02 20:45:55208 net_log_->AddEntry(net::NetLog::TYPE_NETWORK_IP_ADDRESSES_CHANGED,
[email protected]58bc7042010-07-07 18:04:14209 base::TimeTicks::Now(),
[email protected]d2cbfbe2010-08-12 17:38:16210 net::NetLog::Source(),
[email protected]58bc7042010-07-07 18:04:14211 net::NetLog::PHASE_NONE,
212 NULL);
213 }
214
215 private:
216 net::NetLog* net_log_;
217 DISALLOW_COPY_AND_ASSIGN(LoggingNetworkChangeObserver);
218};
219
[email protected]77feb462011-05-16 23:37:25220// Create a separate request context for PAC fetches to avoid reference cycles.
221// See IOThread::Globals for details.
[email protected]aeb53f02011-01-15 00:21:34222scoped_refptr<net::URLRequestContext>
[email protected]2fb629202010-12-23 23:52:57223ConstructProxyScriptFetcherContext(IOThread::Globals* globals,
224 net::NetLog* net_log) {
[email protected]bd0875e2011-03-25 05:13:35225 scoped_refptr<net::URLRequestContext> context(
226 new URLRequestContextWithUserAgent);
[email protected]2fb629202010-12-23 23:52:57227 context->set_net_log(net_log);
228 context->set_host_resolver(globals->host_resolver.get());
229 context->set_cert_verifier(globals->cert_verifier.get());
230 context->set_dnsrr_resolver(globals->dnsrr_resolver.get());
231 context->set_http_auth_handler_factory(
232 globals->http_auth_handler_factory.get());
233 context->set_proxy_service(globals->proxy_script_fetcher_proxy_service.get());
234 context->set_http_transaction_factory(
[email protected]52617df2010-12-24 07:30:01235 globals->proxy_script_fetcher_http_transaction_factory.get());
[email protected]933bc5c62011-04-12 19:08:02236 context->set_ftp_transaction_factory(
237 globals->proxy_script_fetcher_ftp_transaction_factory.get());
[email protected]2fb629202010-12-23 23:52:57238 // In-memory cookie store.
239 context->set_cookie_store(new net::CookieMonster(NULL, NULL));
[email protected]3ce02412011-03-01 12:01:15240 context->set_network_delegate(globals->system_network_delegate.get());
[email protected]2fb629202010-12-23 23:52:57241 return context;
242}
243
[email protected]db0e86dd2011-03-16 14:47:21244scoped_refptr<net::URLRequestContext>
245ConstructSystemRequestContext(IOThread::Globals* globals,
246 net::NetLog* net_log) {
[email protected]bd0875e2011-03-25 05:13:35247 scoped_refptr<net::URLRequestContext> context(
[email protected]77feb462011-05-16 23:37:25248 new SystemURLRequestContext);
[email protected]db0e86dd2011-03-16 14:47:21249 context->set_net_log(net_log);
250 context->set_host_resolver(globals->host_resolver.get());
251 context->set_cert_verifier(globals->cert_verifier.get());
252 context->set_dnsrr_resolver(globals->dnsrr_resolver.get());
253 context->set_http_auth_handler_factory(
254 globals->http_auth_handler_factory.get());
255 context->set_proxy_service(globals->system_proxy_service.get());
256 context->set_http_transaction_factory(
257 globals->system_http_transaction_factory.get());
[email protected]933bc5c62011-04-12 19:08:02258 context->set_ftp_transaction_factory(
259 globals->system_ftp_transaction_factory.get());
[email protected]db0e86dd2011-03-16 14:47:21260 // In-memory cookie store.
261 context->set_cookie_store(new net::CookieMonster(NULL, NULL));
262 return context;
263}
264
[email protected]0ac83682010-01-22 17:46:27265} // namespace
266
[email protected]abe2c032011-03-31 18:49:34267class SystemURLRequestContextGetter : public net::URLRequestContextGetter {
[email protected]db0e86dd2011-03-16 14:47:21268 public:
269 explicit SystemURLRequestContextGetter(IOThread* io_thread);
270 virtual ~SystemURLRequestContextGetter();
271
[email protected]abe2c032011-03-31 18:49:34272 // Implementation for net::UrlRequestContextGetter.
[email protected]db0e86dd2011-03-16 14:47:21273 virtual net::URLRequestContext* GetURLRequestContext();
274 virtual scoped_refptr<base::MessageLoopProxy> GetIOMessageLoopProxy() const;
275
276 private:
277 IOThread* const io_thread_; // Weak pointer, owned by BrowserProcess.
278 scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_;
279
280 base::debug::LeakTracker<SystemURLRequestContextGetter> leak_tracker_;
281};
282
283SystemURLRequestContextGetter::SystemURLRequestContextGetter(
284 IOThread* io_thread)
285 : io_thread_(io_thread),
286 io_message_loop_proxy_(io_thread->message_loop_proxy()) {
287}
288
289SystemURLRequestContextGetter::~SystemURLRequestContextGetter() {}
290
291net::URLRequestContext* SystemURLRequestContextGetter::GetURLRequestContext() {
292 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]addb3242011-06-13 21:39:16293 DCHECK(io_thread_->globals()->system_request_context);
[email protected]db0e86dd2011-03-16 14:47:21294
295 return io_thread_->globals()->system_request_context;
296}
297
298scoped_refptr<base::MessageLoopProxy>
299SystemURLRequestContextGetter::GetIOMessageLoopProxy() const {
300 return io_message_loop_proxy_;
301}
302
[email protected]0ac83682010-01-22 17:46:27303// The IOThread object must outlive any tasks posted to the IO thread before the
304// Quit task.
[email protected]c56428f22010-06-16 02:17:23305DISABLE_RUNNABLE_METHOD_REFCOUNT(IOThread);
[email protected]0ac83682010-01-22 17:46:27306
[email protected]1889dc1b2010-10-14 22:03:13307IOThread::Globals::Globals() {}
308
309IOThread::Globals::~Globals() {}
310
[email protected]bcefe0f2010-11-10 16:19:10311// |local_state| is passed in explicitly in order to (1) reduce implicit
312// dependencies and (2) make IOThread more flexible for testing.
[email protected]3ce02412011-03-01 12:01:15313IOThread::IOThread(
314 PrefService* local_state,
315 ChromeNetLog* net_log,
316 ExtensionEventRouterForwarder* extension_event_router_forwarder)
[email protected]f8b3ef82010-10-11 02:45:52317 : BrowserProcessSubThread(BrowserThread::IO),
[email protected]b2fcd0e2010-12-01 15:19:40318 net_log_(net_log),
[email protected]3ce02412011-03-01 12:01:15319 extension_event_router_forwarder_(extension_event_router_forwarder),
[email protected]d13c3272010-02-04 00:24:51320 globals_(NULL),
[email protected]c5629c32010-06-23 01:22:43321 speculative_interceptor_(NULL),
[email protected]addb3242011-06-13 21:39:16322 predictor_(NULL),
323 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {
[email protected]bcefe0f2010-11-10 16:19:10324 // We call RegisterPrefs() here (instead of inside browser_prefs.cc) to make
325 // sure that everything is initialized in the right order.
326 RegisterPrefs(local_state);
327 auth_schemes_ = local_state->GetString(prefs::kAuthSchemes);
328 negotiate_disable_cname_lookup_ = local_state->GetBoolean(
329 prefs::kDisableAuthNegotiateCnameLookup);
330 negotiate_enable_port_ = local_state->GetBoolean(
331 prefs::kEnableAuthNegotiatePort);
332 auth_server_whitelist_ = local_state->GetString(prefs::kAuthServerWhitelist);
333 auth_delegate_whitelist_ = local_state->GetString(
334 prefs::kAuthNegotiateDelegateWhitelist);
[email protected]ac7f3fdb2010-11-12 12:47:05335 gssapi_library_name_ = local_state->GetString(prefs::kGSSAPILibraryName);
[email protected]db0e86dd2011-03-16 14:47:21336 pref_proxy_config_tracker_ = new PrefProxyConfigTracker(local_state);
[email protected]0a8db0d2011-04-13 15:15:40337 ChromeNetworkDelegate::InitializeReferrersEnabled(&system_enable_referrers_,
338 local_state);
[email protected]4d45a6de2011-05-13 05:20:18339 ssl_config_service_manager_.reset(
340 SSLConfigServiceManager::CreateDefaultManager(local_state));
[email protected]addb3242011-06-13 21:39:16341 MessageLoop::current()->PostTask(FROM_HERE,
342 method_factory_.NewRunnableMethod(
343 &IOThread::InitSystemRequestContext));
[email protected]bcefe0f2010-11-10 16:19:10344}
[email protected]0ac83682010-01-22 17:46:27345
346IOThread::~IOThread() {
[email protected]db0e86dd2011-03-16 14:47:21347 if (pref_proxy_config_tracker_)
348 pref_proxy_config_tracker_->DetachFromPrefService();
[email protected]0ac83682010-01-22 17:46:27349 // We cannot rely on our base class to stop the thread since we want our
350 // CleanUp function to run.
351 Stop();
[email protected]d13c3272010-02-04 00:24:51352 DCHECK(!globals_);
[email protected]0ac83682010-01-22 17:46:27353}
354
[email protected]d13c3272010-02-04 00:24:51355IOThread::Globals* IOThread::globals() {
[email protected]f8b3ef82010-10-11 02:45:52356 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]d13c3272010-02-04 00:24:51357 return globals_;
[email protected]0ac83682010-01-22 17:46:27358}
359
[email protected]b2fcd0e2010-12-01 15:19:40360ChromeNetLog* IOThread::net_log() {
361 return net_log_;
362}
363
[email protected]74be069e82010-06-25 00:12:49364void IOThread::InitNetworkPredictor(
[email protected]0ac83682010-01-22 17:46:27365 bool prefetching_enabled,
[email protected]74be069e82010-06-25 00:12:49366 base::TimeDelta max_dns_queue_delay,
[email protected]755a93352010-10-29 06:33:59367 size_t max_speculative_parallel_resolves,
[email protected]c5629c32010-06-23 01:22:43368 const chrome_common_net::UrlList& startup_urls,
[email protected]760d970a2010-05-18 00:39:18369 ListValue* referral_list,
370 bool preconnect_enabled) {
[email protected]f8b3ef82010-10-11 02:45:52371 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
[email protected]0ac83682010-01-22 17:46:27372 message_loop()->PostTask(
373 FROM_HERE,
374 NewRunnableMethod(
375 this,
[email protected]74be069e82010-06-25 00:12:49376 &IOThread::InitNetworkPredictorOnIOThread,
[email protected]755a93352010-10-29 06:33:59377 prefetching_enabled, max_dns_queue_delay,
378 max_speculative_parallel_resolves,
[email protected]c5629c32010-06-23 01:22:43379 startup_urls, referral_list, preconnect_enabled));
[email protected]0ac83682010-01-22 17:46:27380}
381
[email protected]0ee7a3b2010-11-09 06:13:40382void IOThread::RegisterURLRequestContextGetter(
383 ChromeURLRequestContextGetter* url_request_context_getter) {
384 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
385 std::list<ChromeURLRequestContextGetter*>::const_iterator it =
386 std::find(url_request_context_getters_.begin(),
387 url_request_context_getters_.end(),
388 url_request_context_getter);
389 DCHECK(it == url_request_context_getters_.end());
390 url_request_context_getters_.push_back(url_request_context_getter);
391}
392
393void IOThread::UnregisterURLRequestContextGetter(
394 ChromeURLRequestContextGetter* url_request_context_getter) {
395 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
396 std::list<ChromeURLRequestContextGetter*>::iterator it =
397 std::find(url_request_context_getters_.begin(),
398 url_request_context_getters_.end(),
399 url_request_context_getter);
400 DCHECK(it != url_request_context_getters_.end());
401 // This does not scale, but we shouldn't have many URLRequestContextGetters in
402 // the first place, so this should be fine.
403 url_request_context_getters_.erase(it);
404}
405
[email protected]0ac83682010-01-22 17:46:27406void IOThread::ChangedToOnTheRecord() {
[email protected]f8b3ef82010-10-11 02:45:52407 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
[email protected]0ac83682010-01-22 17:46:27408 message_loop()->PostTask(
409 FROM_HERE,
410 NewRunnableMethod(
411 this,
412 &IOThread::ChangedToOnTheRecordOnIOThread));
413}
414
[email protected]abe2c032011-03-31 18:49:34415net::URLRequestContextGetter* IOThread::system_url_request_context_getter() {
[email protected]db0e86dd2011-03-16 14:47:21416 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
417 if (!system_url_request_context_getter_) {
[email protected]addb3242011-06-13 21:39:16418 InitSystemRequestContext();
[email protected]db0e86dd2011-03-16 14:47:21419 }
420 return system_url_request_context_getter_;
421}
422
[email protected]df2840d2011-02-20 16:32:32423void IOThread::ClearNetworkingHistory() {
424 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
425 ClearHostCache();
426 // Discard acrued data used to speculate in the future.
427 chrome_browser_net::DiscardInitialNavigationHistory();
428 if (predictor_)
429 predictor_->DiscardAllResults();
430}
431
[email protected]0ac83682010-01-22 17:46:27432void IOThread::Init() {
[email protected]ba74b0d22010-10-23 05:19:20433 // Though this thread is called the "IO" thread, it actually just routes
434 // messages around; it shouldn't be allowed to perform any blocking disk I/O.
435 base::ThreadRestrictions::SetIOAllowed(false);
[email protected]ba74b0d22010-10-23 05:19:20436
[email protected]0ac83682010-01-22 17:46:27437 BrowserProcessSubThread::Init();
438
[email protected]70b92342010-10-12 05:54:06439 DCHECK_EQ(MessageLoop::TYPE_IO, message_loop()->type());
440
441#if defined(USE_NSS)
442 net::SetMessageLoopForOCSP();
[email protected]ecd95ae2010-10-20 23:58:17443#endif // defined(USE_NSS)
[email protected]70b92342010-10-12 05:54:06444
[email protected]d13c3272010-02-04 00:24:51445 DCHECK(!globals_);
446 globals_ = new Globals;
447
[email protected]58bc7042010-07-07 18:04:14448 // Add an observer that will emit network change events to the ChromeNetLog.
449 // Assuming NetworkChangeNotifier dispatches in FIFO order, we should be
450 // logging the network change before other IO thread consumers respond to it.
451 network_change_observer_.reset(
[email protected]b2fcd0e2010-12-01 15:19:40452 new LoggingNetworkChangeObserver(net_log_));
[email protected]58bc7042010-07-07 18:04:14453
[email protected]3ce02412011-03-01 12:01:15454 globals_->extension_event_router_forwarder =
455 extension_event_router_forwarder_;
456 globals_->system_network_delegate.reset(new ChromeNetworkDelegate(
[email protected]0a8db0d2011-04-13 15:15:40457 extension_event_router_forwarder_,
[email protected]c357acb42011-06-09 20:52:42458 NULL,
[email protected]0a8db0d2011-04-13 15:15:40459 Profile::kInvalidProfileId,
[email protected]a8c1e7452011-05-14 06:17:07460 &system_enable_referrers_));
[email protected]73c45322010-10-01 23:57:54461 globals_->host_resolver.reset(
[email protected]b2fcd0e2010-12-01 15:19:40462 CreateGlobalHostResolver(net_log_));
[email protected]822581d2010-12-16 17:27:15463 globals_->cert_verifier.reset(new net::CertVerifier);
[email protected]2db580532010-10-08 14:32:37464 globals_->dnsrr_resolver.reset(new net::DnsRRResolver);
[email protected]4d45a6de2011-05-13 05:20:18465 globals_->ssl_config_service = GetSSLConfigService();
[email protected]65d34382010-07-01 18:12:26466 globals_->http_auth_handler_factory.reset(CreateDefaultAuthHandlerFactory(
[email protected]73c45322010-10-01 23:57:54467 globals_->host_resolver.get()));
[email protected]2fb629202010-12-23 23:52:57468 // For the ProxyScriptFetcher, we use a direct ProxyService.
[email protected]6104ea5d2011-04-27 21:37:12469 globals_->proxy_script_fetcher_proxy_service.reset(
470 net::ProxyService::CreateDirectWithNetLog(net_log_));
[email protected]9e1bdd32011-02-03 21:48:34471 net::HttpNetworkSession::Params session_params;
472 session_params.host_resolver = globals_->host_resolver.get();
473 session_params.cert_verifier = globals_->cert_verifier.get();
474 session_params.proxy_service =
475 globals_->proxy_script_fetcher_proxy_service.get();
476 session_params.http_auth_handler_factory =
477 globals_->http_auth_handler_factory.get();
[email protected]0651b812011-02-24 00:22:50478 session_params.network_delegate = globals_->system_network_delegate.get();
[email protected]9e1bdd32011-02-03 21:48:34479 session_params.net_log = net_log_;
480 session_params.ssl_config_service = globals_->ssl_config_service;
[email protected]57cb0f72011-01-28 06:33:58481 scoped_refptr<net::HttpNetworkSession> network_session(
[email protected]9e1bdd32011-02-03 21:48:34482 new net::HttpNetworkSession(session_params));
[email protected]57cb0f72011-01-28 06:33:58483 globals_->proxy_script_fetcher_http_transaction_factory.reset(
484 new net::HttpNetworkLayer(network_session));
[email protected]933bc5c62011-04-12 19:08:02485 globals_->proxy_script_fetcher_ftp_transaction_factory.reset(
486 new net::FtpNetworkLayer(globals_->host_resolver.get()));
[email protected]2fb629202010-12-23 23:52:57487
[email protected]aeb53f02011-01-15 00:21:34488 scoped_refptr<net::URLRequestContext> proxy_script_fetcher_context =
[email protected]2fb629202010-12-23 23:52:57489 ConstructProxyScriptFetcherContext(globals_, net_log_);
490 globals_->proxy_script_fetcher_context = proxy_script_fetcher_context;
[email protected]0ac83682010-01-22 17:46:27491}
492
[email protected]2a92cd92010-04-27 00:01:41493void IOThread::CleanUp() {
[email protected]0ee7a3b2010-11-09 06:13:40494 // Step 1: Kill all things that might be holding onto
[email protected]aeb53f02011-01-15 00:21:34495 // net::URLRequest/net::URLRequestContexts.
[email protected]0ee7a3b2010-11-09 06:13:40496
[email protected]59a3b362010-10-21 21:52:41497#if defined(USE_NSS)
498 net::ShutdownOCSP();
499#endif // defined(USE_NSS)
500
[email protected]0b1ad312010-10-22 01:01:38501 // Destroy all URLRequests started by URLFetchers.
502 URLFetcher::CancelAll();
503
[email protected]5377d892011-01-21 18:25:43504 IndexedDBKeyUtilityClient::Shutdown();
505
[email protected]325a71f2010-05-21 23:05:27506 // If any child processes are still running, terminate them and
[email protected]d27893f62010-07-03 05:47:42507 // and delete the BrowserChildProcessHost instances to release whatever
[email protected]325a71f2010-05-21 23:05:27508 // IO thread only resources they are referencing.
[email protected]d27893f62010-07-03 05:47:42509 BrowserChildProcessHost::TerminateAll();
[email protected]325a71f2010-05-21 23:05:27510
[email protected]0ee7a3b2010-11-09 06:13:40511 std::list<ChromeURLRequestContextGetter*> url_request_context_getters;
512 url_request_context_getters.swap(url_request_context_getters_);
513 for (std::list<ChromeURLRequestContextGetter*>::iterator it =
514 url_request_context_getters.begin();
515 it != url_request_context_getters.end(); ++it) {
516 ChromeURLRequestContextGetter* getter = *it;
[email protected]361fe8a2010-11-24 17:20:49517 // Stop all pending certificate provenance check uploads
518 net::DnsCertProvenanceChecker* checker =
519 getter->GetURLRequestContext()->dns_cert_checker();
520 if (checker)
521 checker->Shutdown();
[email protected]0ee7a3b2010-11-09 06:13:40522 getter->ReleaseURLRequestContext();
523 }
524
[email protected]db0e86dd2011-03-16 14:47:21525 system_url_request_context_getter_ = NULL;
526
[email protected]aeb53f02011-01-15 00:21:34527 // Step 2: Release objects that the net::URLRequestContext could have been
528 // pointing to.
[email protected]0ee7a3b2010-11-09 06:13:40529
530 // This must be reset before the ChromeNetLog is destroyed.
531 network_change_observer_.reset();
532
[email protected]0ac83682010-01-22 17:46:27533 // Not initialized in Init(). May not be initialized.
[email protected]74be069e82010-06-25 00:12:49534 if (predictor_) {
535 predictor_->Shutdown();
[email protected]0ac83682010-01-22 17:46:27536
[email protected]74be069e82010-06-25 00:12:49537 // TODO(willchan): Stop reference counting Predictor. It's owned by
[email protected]0ac83682010-01-22 17:46:27538 // IOThread now.
[email protected]74be069e82010-06-25 00:12:49539 predictor_->Release();
540 predictor_ = NULL;
541 chrome_browser_net::FreePredictorResources();
[email protected]0ac83682010-01-22 17:46:27542 }
543
[email protected]c5629c32010-06-23 01:22:43544 // Deletion will unregister this interceptor.
545 delete speculative_interceptor_;
546 speculative_interceptor_ = NULL;
547
[email protected]e4d2dd822010-02-05 20:57:33548 // TODO(eroman): hack for http://crbug.com/15513
[email protected]970210c2010-02-19 20:27:02549 if (globals_->host_resolver->GetAsHostResolverImpl()) {
550 globals_->host_resolver.get()->GetAsHostResolverImpl()->Shutdown();
[email protected]e4d2dd822010-02-05 20:57:33551 }
[email protected]0ac83682010-01-22 17:46:27552
[email protected]db0e86dd2011-03-16 14:47:21553 system_proxy_config_service_.reset();
554
[email protected]d13c3272010-02-04 00:24:51555 delete globals_;
556 globals_ = NULL;
[email protected]0ac83682010-01-22 17:46:27557
[email protected]569c7602011-03-03 20:40:32558 // net::URLRequest instances must NOT outlive the IO thread.
559 base::debug::LeakTracker<net::URLRequest>::CheckForLeaks();
[email protected]2a92cd92010-04-27 00:01:41560
[email protected]db0e86dd2011-03-16 14:47:21561 base::debug::LeakTracker<SystemURLRequestContextGetter>::CheckForLeaks();
562
[email protected]0ee7a3b2010-11-09 06:13:40563 // This will delete the |notification_service_|. Make sure it's done after
564 // anything else can reference it.
[email protected]569c7602011-03-03 20:40:32565 BrowserProcessSubThread::CleanUp();
[email protected]0ac83682010-01-22 17:46:27566}
567
[email protected]bcefe0f2010-11-10 16:19:10568// static
569void IOThread::RegisterPrefs(PrefService* local_state) {
570 local_state->RegisterStringPref(prefs::kAuthSchemes,
571 "basic,digest,ntlm,negotiate");
572 local_state->RegisterBooleanPref(prefs::kDisableAuthNegotiateCnameLookup,
573 false);
574 local_state->RegisterBooleanPref(prefs::kEnableAuthNegotiatePort, false);
575 local_state->RegisterStringPref(prefs::kAuthServerWhitelist, "");
576 local_state->RegisterStringPref(prefs::kAuthNegotiateDelegateWhitelist, "");
[email protected]ac7f3fdb2010-11-12 12:47:05577 local_state->RegisterStringPref(prefs::kGSSAPILibraryName, "");
[email protected]40850a52011-05-26 22:07:35578 local_state->RegisterBooleanPref(prefs::kAllowCrossOriginAuthPrompt, false);
[email protected]0a8db0d2011-04-13 15:15:40579 local_state->RegisterBooleanPref(prefs::kEnableReferrers, true);
[email protected]bcefe0f2010-11-10 16:19:10580}
581
[email protected]65d34382010-07-01 18:12:26582net::HttpAuthHandlerFactory* IOThread::CreateDefaultAuthHandlerFactory(
583 net::HostResolver* resolver) {
[email protected]9030a632010-11-19 20:12:09584 net::HttpAuthFilterWhitelist* auth_filter_default_credentials = NULL;
585 if (!auth_server_whitelist_.empty()) {
586 auth_filter_default_credentials =
587 new net::HttpAuthFilterWhitelist(auth_server_whitelist_);
588 }
589 net::HttpAuthFilterWhitelist* auth_filter_delegate = NULL;
590 if (!auth_delegate_whitelist_.empty()) {
591 auth_filter_delegate =
592 new net::HttpAuthFilterWhitelist(auth_delegate_whitelist_);
593 }
[email protected]b4955e7d2010-04-16 20:22:30594 globals_->url_security_manager.reset(
[email protected]d201b200e2010-08-27 17:35:02595 net::URLSecurityManager::Create(auth_filter_default_credentials,
596 auth_filter_delegate));
[email protected]b7304162010-08-23 17:42:29597 std::vector<std::string> supported_schemes;
[email protected]bcefe0f2010-11-10 16:19:10598 base::SplitString(auth_schemes_, ',', &supported_schemes);
[email protected]b7304162010-08-23 17:42:29599
600 return net::HttpAuthHandlerRegistryFactory::Create(
601 supported_schemes,
602 globals_->url_security_manager.get(),
603 resolver,
[email protected]ac7f3fdb2010-11-12 12:47:05604 gssapi_library_name_,
[email protected]bcefe0f2010-11-10 16:19:10605 negotiate_disable_cname_lookup_,
606 negotiate_enable_port_);
[email protected]eb3cac72010-02-26 21:07:45607}
608
[email protected]74be069e82010-06-25 00:12:49609void IOThread::InitNetworkPredictorOnIOThread(
[email protected]0ac83682010-01-22 17:46:27610 bool prefetching_enabled,
[email protected]74be069e82010-06-25 00:12:49611 base::TimeDelta max_dns_queue_delay,
[email protected]755a93352010-10-29 06:33:59612 size_t max_speculative_parallel_resolves,
[email protected]c5629c32010-06-23 01:22:43613 const chrome_common_net::UrlList& startup_urls,
[email protected]760d970a2010-05-18 00:39:18614 ListValue* referral_list,
615 bool preconnect_enabled) {
[email protected]f8b3ef82010-10-11 02:45:52616 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]74be069e82010-06-25 00:12:49617 CHECK(!predictor_);
[email protected]0ac83682010-01-22 17:46:27618
[email protected]74be069e82010-06-25 00:12:49619 chrome_browser_net::EnablePredictor(prefetching_enabled);
[email protected]0ac83682010-01-22 17:46:27620
[email protected]74be069e82010-06-25 00:12:49621 predictor_ = new chrome_browser_net::Predictor(
[email protected]73c45322010-10-01 23:57:54622 globals_->host_resolver.get(),
[email protected]74be069e82010-06-25 00:12:49623 max_dns_queue_delay,
[email protected]755a93352010-10-29 06:33:59624 max_speculative_parallel_resolves,
[email protected]760d970a2010-05-18 00:39:18625 preconnect_enabled);
[email protected]74be069e82010-06-25 00:12:49626 predictor_->AddRef();
[email protected]0ac83682010-01-22 17:46:27627
[email protected]f4ef861ba2010-07-28 22:37:23628 // Speculative_interceptor_ is used to predict subresource usage.
629 DCHECK(!speculative_interceptor_);
630 speculative_interceptor_ = new chrome_browser_net::ConnectInterceptor;
631
[email protected]bff1f512010-08-15 15:13:49632 FinalizePredictorInitialization(predictor_, startup_urls, referral_list);
[email protected]0ac83682010-01-22 17:46:27633}
634
635void IOThread::ChangedToOnTheRecordOnIOThread() {
[email protected]f8b3ef82010-10-11 02:45:52636 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]0ac83682010-01-22 17:46:27637
[email protected]74be069e82010-06-25 00:12:49638 if (predictor_) {
[email protected]0ac83682010-01-22 17:46:27639 // Destroy all evidence of our OTR session.
[email protected]df2840d2011-02-20 16:32:32640 // Note: OTR mode never saves InitialNavigationHistory data.
[email protected]74be069e82010-06-25 00:12:49641 predictor_->Predictor::DiscardAllResults();
[email protected]0ac83682010-01-22 17:46:27642 }
643
644 // Clear the host cache to avoid showing entries from the OTR session
645 // in about:net-internals.
[email protected]d6f37fc2011-02-13 23:58:41646 ClearHostCache();
647
648 // Clear all of the passively logged data.
649 // TODO(eroman): this is a bit heavy handed, really all we need to do is
[email protected]2c910b72011-03-08 21:16:32650 // clear the data pertaining to incognito context.
[email protected]d6f37fc2011-02-13 23:58:41651 net_log_->ClearAllPassivelyCapturedEvents();
652}
653
654void IOThread::ClearHostCache() {
655 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
656
[email protected]970210c2010-02-19 20:27:02657 if (globals_->host_resolver->GetAsHostResolverImpl()) {
658 net::HostCache* host_cache =
659 globals_->host_resolver.get()->GetAsHostResolverImpl()->cache();
[email protected]f2d8c4212010-02-02 00:56:35660 if (host_cache)
661 host_cache->clear();
662 }
[email protected]0ac83682010-01-22 17:46:27663}
[email protected]db0e86dd2011-03-16 14:47:21664
[email protected]4d45a6de2011-05-13 05:20:18665net::SSLConfigService* IOThread::GetSSLConfigService() {
666 return ssl_config_service_manager_->Get();
667}
668
[email protected]db0e86dd2011-03-16 14:47:21669void IOThread::InitSystemRequestContext() {
[email protected]addb3242011-06-13 21:39:16670 if (system_url_request_context_getter_)
671 return;
672 system_proxy_config_service_.reset(
673 ProxyServiceFactory::CreateProxyConfigService(
674 pref_proxy_config_tracker_));
675 system_url_request_context_getter_ =
676 new SystemURLRequestContextGetter(this);
677 message_loop()->PostTask(
678 FROM_HERE,
679 NewRunnableMethod(
680 this,
681 &IOThread::InitSystemRequestContextOnIOThread));
682}
683
684void IOThread::InitSystemRequestContextOnIOThread() {
[email protected]db0e86dd2011-03-16 14:47:21685 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]6104ea5d2011-04-27 21:37:12686 DCHECK(!globals_->system_proxy_service.get());
[email protected]db0e86dd2011-03-16 14:47:21687 DCHECK(system_proxy_config_service_.get());
688
689 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
[email protected]6104ea5d2011-04-27 21:37:12690 globals_->system_proxy_service.reset(
[email protected]db0e86dd2011-03-16 14:47:21691 ProxyServiceFactory::CreateProxyService(
692 net_log_,
693 globals_->proxy_script_fetcher_context,
694 system_proxy_config_service_.release(),
[email protected]6104ea5d2011-04-27 21:37:12695 command_line));
[email protected]db0e86dd2011-03-16 14:47:21696 net::HttpNetworkSession::Params system_params;
697 system_params.host_resolver = globals_->host_resolver.get();
698 system_params.cert_verifier = globals_->cert_verifier.get();
699 system_params.dnsrr_resolver = globals_->dnsrr_resolver.get();
700 system_params.dns_cert_checker = NULL;
701 system_params.ssl_host_info_factory = NULL;
702 system_params.proxy_service = globals_->system_proxy_service.get();
703 system_params.ssl_config_service = globals_->ssl_config_service.get();
704 system_params.http_auth_handler_factory =
705 globals_->http_auth_handler_factory.get();
706 system_params.network_delegate = globals_->system_network_delegate.get();
707 system_params.net_log = net_log_;
708 globals_->system_http_transaction_factory.reset(
709 new net::HttpNetworkLayer(
710 new net::HttpNetworkSession(system_params)));
[email protected]933bc5c62011-04-12 19:08:02711 globals_->system_ftp_transaction_factory.reset(
712 new net::FtpNetworkLayer(globals_->host_resolver.get()));
[email protected]db0e86dd2011-03-16 14:47:21713 globals_->system_request_context =
714 ConstructSystemRequestContext(globals_, net_log_);
715}