blob: 130a9324166ce411c1d6ad13f63f597fae3b383b [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]21ee224e2011-11-21 02:17:5310#include "base/bind.h"
11#include "base/bind_helpers.h"
[email protected]58580352010-10-26 04:07:5012#include "base/debug/leak_tracker.h"
[email protected]0ac83682010-01-22 17:46:2713#include "base/logging.h"
[email protected]ecd95ae2010-10-20 23:58:1714#include "base/metrics/field_trial.h"
[email protected]7286e3fc2011-07-19 22:13:2415#include "base/stl_util.h"
[email protected]e83326f2010-07-31 17:29:2516#include "base/string_number_conversions.h"
[email protected]4e5ae20f2010-09-24 04:52:1117#include "base/string_split.h"
[email protected]f1d81922010-07-31 17:47:0918#include "base/string_util.h"
[email protected]3fc40c142011-12-01 13:09:0419#include "base/threading/thread.h"
[email protected]34b99632011-01-01 01:01:0620#include "base/threading/thread_restrictions.h"
[email protected]addb3242011-06-13 21:39:1621#include "build/build_config.h"
[email protected]df2840d2011-02-20 16:32:3222#include "chrome/browser/browser_process.h"
[email protected]3ce02412011-03-01 12:01:1523#include "chrome/browser/extensions/extension_event_router_forwarder.h"
[email protected]cc87500b2011-06-24 20:59:1924#include "chrome/browser/media/media_internals.h"
[email protected]9e743cd2010-03-16 07:03:5325#include "chrome/browser/net/chrome_net_log.h"
[email protected]c38831a12011-10-28 12:44:4926#include "chrome/browser/net/chrome_network_delegate.h"
[email protected]0ee7a3b2010-11-09 06:13:4027#include "chrome/browser/net/chrome_url_request_context.h"
[email protected]1889dc1b2010-10-14 22:03:1328#include "chrome/browser/net/connect_interceptor.h"
[email protected]9e743cd2010-03-16 07:03:5329#include "chrome/browser/net/passive_log_collector.h"
[email protected]6f96cbcb2011-11-04 02:26:0730#include "chrome/browser/net/pref_proxy_config_tracker.h"
[email protected]db0e86dd2011-03-16 14:47:2131#include "chrome/browser/net/proxy_service_factory.h"
[email protected]3b543ab2011-09-17 21:47:0032#include "chrome/browser/net/sdch_dictionary_fetcher.h"
[email protected]bcefe0f2010-11-10 16:19:1033#include "chrome/browser/prefs/pref_service.h"
[email protected]0ac83682010-01-22 17:46:2734#include "chrome/common/chrome_switches.h"
[email protected]bcefe0f2010-11-10 16:19:1035#include "chrome/common/pref_names.h"
[email protected]d9f37932011-05-09 20:09:2436#include "content/browser/gpu/gpu_process_host.h"
[email protected]567812d2011-02-24 17:40:5037#include "content/browser/in_process_webkit/indexed_db_key_utility_client.h"
[email protected]c38831a12011-10-28 12:44:4938#include "content/public/browser/browser_thread.h"
[email protected]5d1fa242011-10-18 23:35:3839#include "content/public/common/content_client.h"
[email protected]36aea2702011-10-26 01:12:2240#include "content/public/common/url_fetcher.h"
[email protected]822581d2010-12-16 17:27:1541#include "net/base/cert_verifier.h"
[email protected]f6c21cb2011-02-16 19:45:4142#include "net/base/cookie_monster.h"
[email protected]273e37d2011-08-11 01:49:1243#include "net/base/default_origin_bound_cert_store.h"
[email protected]2db580532010-10-08 14:32:3744#include "net/base/dnsrr_resolver.h"
[email protected]0ac83682010-01-22 17:46:2745#include "net/base/host_cache.h"
46#include "net/base/host_resolver.h"
[email protected]f2d8c4212010-02-02 00:56:3547#include "net/base/host_resolver_impl.h"
[email protected]86933612010-10-16 23:10:3348#include "net/base/mapped_host_resolver.h"
[email protected]32eaa332010-02-08 22:15:5449#include "net/base/net_util.h"
[email protected]273e37d2011-08-11 01:49:1250#include "net/base/origin_bound_cert_service.h"
[email protected]3b543ab2011-09-17 21:47:0051#include "net/base/sdch_manager.h"
[email protected]4b0112ab2011-07-22 15:58:2052#include "net/dns/async_host_resolver.h"
[email protected]933bc5c62011-04-12 19:08:0253#include "net/ftp/ftp_network_layer.h"
[email protected]eb3cac72010-02-26 21:07:4554#include "net/http/http_auth_filter.h"
[email protected]fa55e192010-02-15 14:25:5055#include "net/http/http_auth_handler_factory.h"
[email protected]2fb629202010-12-23 23:52:5756#include "net/http/http_network_layer.h"
[email protected]57cb0f72011-01-28 06:33:5857#include "net/http/http_network_session.h"
[email protected]17291a022011-10-10 07:32:5358#include "net/http/http_server_properties_impl.h"
[email protected]6104ea5d2011-04-27 21:37:1259#include "net/proxy/proxy_config_service.h"
[email protected]86933612010-10-16 23:10:3360#include "net/proxy/proxy_script_fetcher_impl.h"
[email protected]6104ea5d2011-04-27 21:37:1261#include "net/proxy/proxy_service.h"
[email protected]5f6f83e2011-05-24 18:03:0862#include "net/socket/dns_cert_provenance_checker.h"
[email protected]0ac83682010-01-22 17:46:2763
[email protected]77feb462011-05-16 23:37:2564#if defined(USE_NSS)
65#include "net/ocsp/nss_ocsp.h"
66#endif // defined(USE_NSS)
67
[email protected]6f96cbcb2011-11-04 02:26:0768#if defined(OS_CHROMEOS)
69#include "chrome/browser/chromeos/proxy_config_service_impl.h"
70#endif // defined(OS_CHROMEOS)
71
[email protected]631bb742011-11-02 11:29:3972using content::BrowserThread;
73
[email protected]21ee224e2011-11-21 02:17:5374// The IOThread object must outlive any tasks posted to the IO thread before the
75// Quit task, so base::Bind() calls are not refcounted.
76
[email protected]0ac83682010-01-22 17:46:2777namespace {
78
[email protected]bd0875e2011-03-25 05:13:3579// Custom URLRequestContext used by requests which aren't associated with a
80// particular profile. We need to use a subclass of URLRequestContext in order
81// to provide the correct User-Agent.
82class URLRequestContextWithUserAgent : public net::URLRequestContext {
83 public:
84 virtual const std::string& GetUserAgent(
85 const GURL& url) const OVERRIDE {
[email protected]b75520232011-10-12 23:45:2586 return content::GetUserAgent(url);
[email protected]bd0875e2011-03-25 05:13:3587 }
88};
89
[email protected]77feb462011-05-16 23:37:2590// Used for the "system" URLRequestContext. If this grows more complicated, then
91// consider inheriting directly from URLRequestContext rather than using
92// implementation inheritance.
93class SystemURLRequestContext : public URLRequestContextWithUserAgent {
94 public:
95 SystemURLRequestContext() {
96#if defined(USE_NSS)
97 net::SetURLRequestContextForOCSP(this);
98#endif // defined(USE_NSS)
99 }
100
101 private:
102 virtual ~SystemURLRequestContext() {
103#if defined(USE_NSS)
104 net::SetURLRequestContextForOCSP(NULL);
105#endif // defined(USE_NSS)
106 }
107};
108
[email protected]ee094b82010-08-24 15:55:51109net::HostResolver* CreateGlobalHostResolver(net::NetLog* net_log) {
[email protected]0ac83682010-01-22 17:46:27110 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
[email protected]962b98212010-07-17 03:37:51111
112 size_t parallelism = net::HostResolver::kDefaultParallelism;
113
114 // Use the concurrency override from the command-line, if any.
115 if (command_line.HasSwitch(switches::kHostResolverParallelism)) {
116 std::string s =
117 command_line.GetSwitchValueASCII(switches::kHostResolverParallelism);
118
119 // Parse the switch (it should be a positive integer formatted as decimal).
120 int n;
[email protected]e83326f2010-07-31 17:29:25121 if (base::StringToInt(s, &n) && n > 0) {
[email protected]962b98212010-07-17 03:37:51122 parallelism = static_cast<size_t>(n);
123 } else {
124 LOG(ERROR) << "Invalid switch for host resolver parallelism: " << s;
125 }
[email protected]ecd95ae2010-10-20 23:58:17126 } else {
127 // Set up a field trial to see what impact the total number of concurrent
128 // resolutions have on DNS resolutions.
129 base::FieldTrial::Probability kDivisor = 1000;
130 // For each option (i.e., non-default), we have a fixed probability.
131 base::FieldTrial::Probability kProbabilityPerGroup = 100; // 10%.
132
[email protected]933729bc2011-01-19 18:52:32133 // After June 30, 2011 builds, it will always be in default group
134 // (parallel_default).
[email protected]ad8e04a2010-11-01 04:16:27135 scoped_refptr<base::FieldTrial> trial(
[email protected]933729bc2011-01-19 18:52:32136 new base::FieldTrial(
137 "DnsParallelism", kDivisor, "parallel_default", 2011, 6, 30));
[email protected]ecd95ae2010-10-20 23:58:17138
139 // List options with different counts.
140 // Firefox limits total to 8 in parallel, and default is currently 50.
141 int parallel_6 = trial->AppendGroup("parallel_6", kProbabilityPerGroup);
[email protected]755a93352010-10-29 06:33:59142 int parallel_7 = trial->AppendGroup("parallel_7", kProbabilityPerGroup);
[email protected]ecd95ae2010-10-20 23:58:17143 int parallel_8 = trial->AppendGroup("parallel_8", kProbabilityPerGroup);
[email protected]755a93352010-10-29 06:33:59144 int parallel_9 = trial->AppendGroup("parallel_9", kProbabilityPerGroup);
[email protected]ecd95ae2010-10-20 23:58:17145 int parallel_10 = trial->AppendGroup("parallel_10", kProbabilityPerGroup);
146 int parallel_14 = trial->AppendGroup("parallel_14", kProbabilityPerGroup);
147 int parallel_20 = trial->AppendGroup("parallel_20", kProbabilityPerGroup);
148
[email protected]ecd95ae2010-10-20 23:58:17149 if (trial->group() == parallel_6)
150 parallelism = 6;
[email protected]755a93352010-10-29 06:33:59151 else if (trial->group() == parallel_7)
152 parallelism = 7;
[email protected]ecd95ae2010-10-20 23:58:17153 else if (trial->group() == parallel_8)
154 parallelism = 8;
[email protected]755a93352010-10-29 06:33:59155 else if (trial->group() == parallel_9)
156 parallelism = 9;
[email protected]ecd95ae2010-10-20 23:58:17157 else if (trial->group() == parallel_10)
158 parallelism = 10;
159 else if (trial->group() == parallel_14)
160 parallelism = 14;
161 else if (trial->group() == parallel_20)
162 parallelism = 20;
[email protected]962b98212010-07-17 03:37:51163 }
164
[email protected]06ef6d92011-05-19 04:24:58165 size_t retry_attempts = net::HostResolver::kDefaultRetryAttempts;
166
167 // Use the retry attempts override from the command-line, if any.
168 if (command_line.HasSwitch(switches::kHostResolverRetryAttempts)) {
169 std::string s =
170 command_line.GetSwitchValueASCII(switches::kHostResolverRetryAttempts);
171 // Parse the switch (it should be a non-negative integer).
172 int n;
173 if (base::StringToInt(s, &n) && n >= 0) {
174 retry_attempts = static_cast<size_t>(n);
175 } else {
176 LOG(ERROR) << "Invalid switch for host resolver retry attempts: " << s;
177 }
178 }
179
[email protected]d987cca2011-07-21 12:54:37180 net::HostResolver* global_host_resolver = NULL;
181 if (command_line.HasSwitch(switches::kDnsServer)) {
182 std::string dns_ip_string =
183 command_line.GetSwitchValueASCII(switches::kDnsServer);
184 net::IPAddressNumber dns_ip_number;
185 if (net::ParseIPLiteralToNumber(dns_ip_string, &dns_ip_number)) {
186 global_host_resolver =
187 net::CreateAsyncHostResolver(parallelism, dns_ip_number, net_log);
188 } else {
189 LOG(ERROR) << "Invalid IP address specified for --dns-server: "
190 << dns_ip_string;
191 }
192 }
193
194 if (!global_host_resolver) {
195 global_host_resolver =
[email protected]06ef6d92011-05-19 04:24:58196 net::CreateSystemHostResolver(parallelism, retry_attempts, net_log);
[email protected]d987cca2011-07-21 12:54:37197 }
[email protected]9087aa32010-02-18 08:03:38198
[email protected]0f8f1b432010-03-16 19:06:03199 // Determine if we should disable IPv6 support.
[email protected]9087aa32010-02-18 08:03:38200 if (!command_line.HasSwitch(switches::kEnableIPv6)) {
[email protected]0f8f1b432010-03-16 19:06:03201 if (command_line.HasSwitch(switches::kDisableIPv6)) {
[email protected]46f6e202010-02-26 06:07:25202 global_host_resolver->SetDefaultAddressFamily(net::ADDRESS_FAMILY_IPV4);
[email protected]0f8f1b432010-03-16 19:06:03203 } else {
[email protected]a78f4272011-10-21 19:16:33204 global_host_resolver->ProbeIPv6Support();
[email protected]0f8f1b432010-03-16 19:06:03205 }
[email protected]9087aa32010-02-18 08:03:38206 }
207
[email protected]9087aa32010-02-18 08:03:38208 // If hostname remappings were specified on the command-line, layer these
209 // rules on top of the real host resolver. This allows forwarding all requests
210 // through a designated test server.
[email protected]0f8f1b432010-03-16 19:06:03211 if (!command_line.HasSwitch(switches::kHostResolverRules))
212 return global_host_resolver;
[email protected]0ac83682010-01-22 17:46:27213
[email protected]0f8f1b432010-03-16 19:06:03214 net::MappedHostResolver* remapped_resolver =
215 new net::MappedHostResolver(global_host_resolver);
216 remapped_resolver->SetRulesFromString(
217 command_line.GetSwitchValueASCII(switches::kHostResolverRules));
218 return remapped_resolver;
[email protected]0ac83682010-01-22 17:46:27219}
220
[email protected]58bc7042010-07-07 18:04:14221class LoggingNetworkChangeObserver
[email protected]232a5812011-03-04 22:42:08222 : public net::NetworkChangeNotifier::IPAddressObserver {
[email protected]58bc7042010-07-07 18:04:14223 public:
224 // |net_log| must remain valid throughout our lifetime.
225 explicit LoggingNetworkChangeObserver(net::NetLog* net_log)
226 : net_log_(net_log) {
[email protected]232a5812011-03-04 22:42:08227 net::NetworkChangeNotifier::AddIPAddressObserver(this);
[email protected]58bc7042010-07-07 18:04:14228 }
229
230 ~LoggingNetworkChangeObserver() {
[email protected]232a5812011-03-04 22:42:08231 net::NetworkChangeNotifier::RemoveIPAddressObserver(this);
[email protected]58bc7042010-07-07 18:04:14232 }
233
234 virtual void OnIPAddressChanged() {
[email protected]8e96e502010-10-21 20:57:12235 VLOG(1) << "Observed a change to the network IP addresses";
[email protected]58bc7042010-07-07 18:04:14236
[email protected]d3aaf3f2010-09-02 20:45:55237 net_log_->AddEntry(net::NetLog::TYPE_NETWORK_IP_ADDRESSES_CHANGED,
[email protected]58bc7042010-07-07 18:04:14238 base::TimeTicks::Now(),
[email protected]d2cbfbe2010-08-12 17:38:16239 net::NetLog::Source(),
[email protected]58bc7042010-07-07 18:04:14240 net::NetLog::PHASE_NONE,
241 NULL);
242 }
243
244 private:
245 net::NetLog* net_log_;
246 DISALLOW_COPY_AND_ASSIGN(LoggingNetworkChangeObserver);
247};
248
[email protected]77feb462011-05-16 23:37:25249// Create a separate request context for PAC fetches to avoid reference cycles.
250// See IOThread::Globals for details.
[email protected]aeb53f02011-01-15 00:21:34251scoped_refptr<net::URLRequestContext>
[email protected]2fb629202010-12-23 23:52:57252ConstructProxyScriptFetcherContext(IOThread::Globals* globals,
253 net::NetLog* net_log) {
[email protected]bd0875e2011-03-25 05:13:35254 scoped_refptr<net::URLRequestContext> context(
255 new URLRequestContextWithUserAgent);
[email protected]2fb629202010-12-23 23:52:57256 context->set_net_log(net_log);
257 context->set_host_resolver(globals->host_resolver.get());
258 context->set_cert_verifier(globals->cert_verifier.get());
259 context->set_dnsrr_resolver(globals->dnsrr_resolver.get());
260 context->set_http_auth_handler_factory(
261 globals->http_auth_handler_factory.get());
262 context->set_proxy_service(globals->proxy_script_fetcher_proxy_service.get());
263 context->set_http_transaction_factory(
[email protected]52617df2010-12-24 07:30:01264 globals->proxy_script_fetcher_http_transaction_factory.get());
[email protected]933bc5c62011-04-12 19:08:02265 context->set_ftp_transaction_factory(
266 globals->proxy_script_fetcher_ftp_transaction_factory.get());
[email protected]273e37d2011-08-11 01:49:12267 context->set_cookie_store(globals->system_cookie_store.get());
268 context->set_origin_bound_cert_service(
269 globals->system_origin_bound_cert_service.get());
[email protected]3ce02412011-03-01 12:01:15270 context->set_network_delegate(globals->system_network_delegate.get());
[email protected]db96a882011-10-09 02:01:54271 // TODO(rtenneti): We should probably use HttpServerPropertiesManager for the
272 // system URLRequestContext too. There's no reason this should be tied to a
273 // profile.
[email protected]2fb629202010-12-23 23:52:57274 return context;
275}
276
[email protected]db0e86dd2011-03-16 14:47:21277scoped_refptr<net::URLRequestContext>
278ConstructSystemRequestContext(IOThread::Globals* globals,
279 net::NetLog* net_log) {
[email protected]bd0875e2011-03-25 05:13:35280 scoped_refptr<net::URLRequestContext> context(
[email protected]77feb462011-05-16 23:37:25281 new SystemURLRequestContext);
[email protected]db0e86dd2011-03-16 14:47:21282 context->set_net_log(net_log);
283 context->set_host_resolver(globals->host_resolver.get());
284 context->set_cert_verifier(globals->cert_verifier.get());
285 context->set_dnsrr_resolver(globals->dnsrr_resolver.get());
286 context->set_http_auth_handler_factory(
287 globals->http_auth_handler_factory.get());
288 context->set_proxy_service(globals->system_proxy_service.get());
289 context->set_http_transaction_factory(
290 globals->system_http_transaction_factory.get());
[email protected]933bc5c62011-04-12 19:08:02291 context->set_ftp_transaction_factory(
292 globals->system_ftp_transaction_factory.get());
[email protected]273e37d2011-08-11 01:49:12293 context->set_cookie_store(globals->system_cookie_store.get());
294 context->set_origin_bound_cert_service(
295 globals->system_origin_bound_cert_service.get());
[email protected]db0e86dd2011-03-16 14:47:21296 return context;
297}
298
[email protected]0ac83682010-01-22 17:46:27299} // namespace
300
[email protected]abe2c032011-03-31 18:49:34301class SystemURLRequestContextGetter : public net::URLRequestContextGetter {
[email protected]db0e86dd2011-03-16 14:47:21302 public:
303 explicit SystemURLRequestContextGetter(IOThread* io_thread);
304 virtual ~SystemURLRequestContextGetter();
305
[email protected]abe2c032011-03-31 18:49:34306 // Implementation for net::UrlRequestContextGetter.
[email protected]db0e86dd2011-03-16 14:47:21307 virtual net::URLRequestContext* GetURLRequestContext();
308 virtual scoped_refptr<base::MessageLoopProxy> GetIOMessageLoopProxy() const;
309
310 private:
311 IOThread* const io_thread_; // Weak pointer, owned by BrowserProcess.
312 scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_;
313
314 base::debug::LeakTracker<SystemURLRequestContextGetter> leak_tracker_;
315};
316
317SystemURLRequestContextGetter::SystemURLRequestContextGetter(
318 IOThread* io_thread)
319 : io_thread_(io_thread),
[email protected]2e5b60a22011-11-28 15:56:41320 io_message_loop_proxy_(
321 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)) {
[email protected]db0e86dd2011-03-16 14:47:21322}
323
324SystemURLRequestContextGetter::~SystemURLRequestContextGetter() {}
325
326net::URLRequestContext* SystemURLRequestContextGetter::GetURLRequestContext() {
327 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]addb3242011-06-13 21:39:16328 DCHECK(io_thread_->globals()->system_request_context);
[email protected]db0e86dd2011-03-16 14:47:21329
330 return io_thread_->globals()->system_request_context;
331}
332
333scoped_refptr<base::MessageLoopProxy>
334SystemURLRequestContextGetter::GetIOMessageLoopProxy() const {
335 return io_message_loop_proxy_;
336}
337
[email protected]1889dc1b2010-10-14 22:03:13338IOThread::Globals::Globals() {}
339
340IOThread::Globals::~Globals() {}
341
[email protected]cc87500b2011-06-24 20:59:19342IOThread::Globals::MediaGlobals::MediaGlobals() {}
343
344IOThread::Globals::MediaGlobals::~MediaGlobals() {}
345
[email protected]bcefe0f2010-11-10 16:19:10346// |local_state| is passed in explicitly in order to (1) reduce implicit
347// dependencies and (2) make IOThread more flexible for testing.
[email protected]3ce02412011-03-01 12:01:15348IOThread::IOThread(
349 PrefService* local_state,
350 ChromeNetLog* net_log,
351 ExtensionEventRouterForwarder* extension_event_router_forwarder)
[email protected]2e5b60a22011-11-28 15:56:41352 : net_log_(net_log),
[email protected]3ce02412011-03-01 12:01:15353 extension_event_router_forwarder_(extension_event_router_forwarder),
[email protected]d13c3272010-02-04 00:24:51354 globals_(NULL),
[email protected]4a109492011-09-24 21:00:12355 sdch_manager_(NULL),
[email protected]21ee224e2011-11-21 02:17:53356 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
[email protected]bcefe0f2010-11-10 16:19:10357 // We call RegisterPrefs() here (instead of inside browser_prefs.cc) to make
358 // sure that everything is initialized in the right order.
359 RegisterPrefs(local_state);
360 auth_schemes_ = local_state->GetString(prefs::kAuthSchemes);
361 negotiate_disable_cname_lookup_ = local_state->GetBoolean(
362 prefs::kDisableAuthNegotiateCnameLookup);
363 negotiate_enable_port_ = local_state->GetBoolean(
364 prefs::kEnableAuthNegotiatePort);
365 auth_server_whitelist_ = local_state->GetString(prefs::kAuthServerWhitelist);
366 auth_delegate_whitelist_ = local_state->GetString(
367 prefs::kAuthNegotiateDelegateWhitelist);
[email protected]ac7f3fdb2010-11-12 12:47:05368 gssapi_library_name_ = local_state->GetString(prefs::kGSSAPILibraryName);
[email protected]6f96cbcb2011-11-04 02:26:07369 pref_proxy_config_tracker_.reset(
370 ProxyServiceFactory::CreatePrefProxyConfigTracker(local_state));
[email protected]0a8db0d2011-04-13 15:15:40371 ChromeNetworkDelegate::InitializeReferrersEnabled(&system_enable_referrers_,
372 local_state);
[email protected]4d45a6de2011-05-13 05:20:18373 ssl_config_service_manager_.reset(
374 SSLConfigServiceManager::CreateDefaultManager(local_state));
[email protected]2e5b60a22011-11-28 15:56:41375
376 BrowserThread::SetDelegate(BrowserThread::IO, this);
[email protected]bcefe0f2010-11-10 16:19:10377}
[email protected]0ac83682010-01-22 17:46:27378
379IOThread::~IOThread() {
[email protected]2e5b60a22011-11-28 15:56:41380 // This isn't needed for production code, but in tests, IOThread may
381 // be multiply constructed.
382 BrowserThread::SetDelegate(BrowserThread::IO, NULL);
383
[email protected]6f96cbcb2011-11-04 02:26:07384 if (pref_proxy_config_tracker_.get())
[email protected]db0e86dd2011-03-16 14:47:21385 pref_proxy_config_tracker_->DetachFromPrefService();
[email protected]d13c3272010-02-04 00:24:51386 DCHECK(!globals_);
[email protected]0ac83682010-01-22 17:46:27387}
388
[email protected]d13c3272010-02-04 00:24:51389IOThread::Globals* IOThread::globals() {
[email protected]f8b3ef82010-10-11 02:45:52390 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]d13c3272010-02-04 00:24:51391 return globals_;
[email protected]0ac83682010-01-22 17:46:27392}
393
[email protected]b2fcd0e2010-12-01 15:19:40394ChromeNetLog* IOThread::net_log() {
395 return net_log_;
396}
397
[email protected]abe2c032011-03-31 18:49:34398net::URLRequestContextGetter* IOThread::system_url_request_context_getter() {
[email protected]db0e86dd2011-03-16 14:47:21399 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
400 if (!system_url_request_context_getter_) {
[email protected]addb3242011-06-13 21:39:16401 InitSystemRequestContext();
[email protected]db0e86dd2011-03-16 14:47:21402 }
403 return system_url_request_context_getter_;
404}
405
[email protected]0ac83682010-01-22 17:46:27406void IOThread::Init() {
[email protected]ba74b0d22010-10-23 05:19:20407 // Though this thread is called the "IO" thread, it actually just routes
408 // messages around; it shouldn't be allowed to perform any blocking disk I/O.
409 base::ThreadRestrictions::SetIOAllowed(false);
[email protected]ba74b0d22010-10-23 05:19:20410
[email protected]2e5b60a22011-11-28 15:56:41411 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]70b92342010-10-12 05:54:06412
413#if defined(USE_NSS)
414 net::SetMessageLoopForOCSP();
[email protected]ecd95ae2010-10-20 23:58:17415#endif // defined(USE_NSS)
[email protected]70b92342010-10-12 05:54:06416
[email protected]d13c3272010-02-04 00:24:51417 DCHECK(!globals_);
418 globals_ = new Globals;
419
[email protected]cc87500b2011-06-24 20:59:19420 globals_->media.media_internals.reset(new MediaInternals());
421
[email protected]58bc7042010-07-07 18:04:14422 // Add an observer that will emit network change events to the ChromeNetLog.
423 // Assuming NetworkChangeNotifier dispatches in FIFO order, we should be
424 // logging the network change before other IO thread consumers respond to it.
425 network_change_observer_.reset(
[email protected]b2fcd0e2010-12-01 15:19:40426 new LoggingNetworkChangeObserver(net_log_));
[email protected]58bc7042010-07-07 18:04:14427
[email protected]3ce02412011-03-01 12:01:15428 globals_->extension_event_router_forwarder =
429 extension_event_router_forwarder_;
430 globals_->system_network_delegate.reset(new ChromeNetworkDelegate(
[email protected]0a8db0d2011-04-13 15:15:40431 extension_event_router_forwarder_,
[email protected]c357acb42011-06-09 20:52:42432 NULL,
[email protected]673514522011-07-13 18:17:18433 NULL,
[email protected]6a5f77c32011-09-04 19:19:59434 NULL,
[email protected]a8c1e7452011-05-14 06:17:07435 &system_enable_referrers_));
[email protected]73c45322010-10-01 23:57:54436 globals_->host_resolver.reset(
[email protected]b2fcd0e2010-12-01 15:19:40437 CreateGlobalHostResolver(net_log_));
[email protected]822581d2010-12-16 17:27:15438 globals_->cert_verifier.reset(new net::CertVerifier);
[email protected]2db580532010-10-08 14:32:37439 globals_->dnsrr_resolver.reset(new net::DnsRRResolver);
[email protected]4d45a6de2011-05-13 05:20:18440 globals_->ssl_config_service = GetSSLConfigService();
[email protected]65d34382010-07-01 18:12:26441 globals_->http_auth_handler_factory.reset(CreateDefaultAuthHandlerFactory(
[email protected]73c45322010-10-01 23:57:54442 globals_->host_resolver.get()));
[email protected]17291a022011-10-10 07:32:53443 globals_->http_server_properties.reset(new net::HttpServerPropertiesImpl);
[email protected]2fb629202010-12-23 23:52:57444 // For the ProxyScriptFetcher, we use a direct ProxyService.
[email protected]6104ea5d2011-04-27 21:37:12445 globals_->proxy_script_fetcher_proxy_service.reset(
446 net::ProxyService::CreateDirectWithNetLog(net_log_));
[email protected]273e37d2011-08-11 01:49:12447 // In-memory cookie store.
448 globals_->system_cookie_store = new net::CookieMonster(NULL, NULL);
449 // In-memory origin-bound cert store.
450 globals_->system_origin_bound_cert_service.reset(
451 new net::OriginBoundCertService(
452 new net::DefaultOriginBoundCertStore(NULL)));
[email protected]9e1bdd32011-02-03 21:48:34453 net::HttpNetworkSession::Params session_params;
454 session_params.host_resolver = globals_->host_resolver.get();
455 session_params.cert_verifier = globals_->cert_verifier.get();
[email protected]273e37d2011-08-11 01:49:12456 session_params.origin_bound_cert_service =
457 globals_->system_origin_bound_cert_service.get();
[email protected]9e1bdd32011-02-03 21:48:34458 session_params.proxy_service =
459 globals_->proxy_script_fetcher_proxy_service.get();
460 session_params.http_auth_handler_factory =
461 globals_->http_auth_handler_factory.get();
[email protected]0651b812011-02-24 00:22:50462 session_params.network_delegate = globals_->system_network_delegate.get();
[email protected]db96a882011-10-09 02:01:54463 // TODO(rtenneti): We should probably use HttpServerPropertiesManager for the
464 // system URLRequestContext too. There's no reason this should be tied to a
465 // profile.
[email protected]17291a022011-10-10 07:32:53466 session_params.http_server_properties =
467 globals_->http_server_properties.get();
[email protected]9e1bdd32011-02-03 21:48:34468 session_params.net_log = net_log_;
469 session_params.ssl_config_service = globals_->ssl_config_service;
[email protected]57cb0f72011-01-28 06:33:58470 scoped_refptr<net::HttpNetworkSession> network_session(
[email protected]9e1bdd32011-02-03 21:48:34471 new net::HttpNetworkSession(session_params));
[email protected]57cb0f72011-01-28 06:33:58472 globals_->proxy_script_fetcher_http_transaction_factory.reset(
473 new net::HttpNetworkLayer(network_session));
[email protected]933bc5c62011-04-12 19:08:02474 globals_->proxy_script_fetcher_ftp_transaction_factory.reset(
475 new net::FtpNetworkLayer(globals_->host_resolver.get()));
[email protected]2fb629202010-12-23 23:52:57476
[email protected]273e37d2011-08-11 01:49:12477 globals_->proxy_script_fetcher_context =
[email protected]2fb629202010-12-23 23:52:57478 ConstructProxyScriptFetcherContext(globals_, net_log_);
[email protected]4a109492011-09-24 21:00:12479
480 sdch_manager_ = new net::SdchManager();
481 sdch_manager_->set_sdch_fetcher(new SdchDictionaryFetcher);
[email protected]2e5b60a22011-11-28 15:56:41482
483 // InitSystemRequestContext turns right around and posts a task back
484 // to the IO thread, so we can't let it run until we know the IO
485 // thread has started.
486 //
487 // Note that since we are at BrowserThread::Init time, the UI thread
488 // is blocked waiting for the thread to start. Therefore, posting
489 // this task to the main thread's message loop here is guaranteed to
490 // get it onto the message loop while the IOThread object still
491 // exists. However, the message might not be processed on the UI
492 // thread until after IOThread is gone, so use a weak pointer.
493 BrowserThread::PostTask(BrowserThread::UI,
494 FROM_HERE,
495 base::Bind(&IOThread::InitSystemRequestContext,
496 weak_factory_.GetWeakPtr()));
497
498 // We constructed the weak pointer on the IO thread but it will be
499 // used on the UI thread. Call this to avoid a thread checker
500 // error.
501 weak_factory_.DetachFromThread();
[email protected]0ac83682010-01-22 17:46:27502}
503
[email protected]2a92cd92010-04-27 00:01:41504void IOThread::CleanUp() {
[email protected]4a109492011-09-24 21:00:12505 delete sdch_manager_;
506 sdch_manager_ = NULL;
507
[email protected]0ee7a3b2010-11-09 06:13:40508 // Step 1: Kill all things that might be holding onto
[email protected]aeb53f02011-01-15 00:21:34509 // net::URLRequest/net::URLRequestContexts.
[email protected]0ee7a3b2010-11-09 06:13:40510
[email protected]59a3b362010-10-21 21:52:41511#if defined(USE_NSS)
512 net::ShutdownOCSP();
513#endif // defined(USE_NSS)
514
[email protected]0b1ad312010-10-22 01:01:38515 // Destroy all URLRequests started by URLFetchers.
[email protected]36aea2702011-10-26 01:12:22516 content::URLFetcher::CancelAll();
[email protected]0b1ad312010-10-22 01:01:38517
[email protected]5377d892011-01-21 18:25:43518 IndexedDBKeyUtilityClient::Shutdown();
519
[email protected]325a71f2010-05-21 23:05:27520 // If any child processes are still running, terminate them and
[email protected]d27893f62010-07-03 05:47:42521 // and delete the BrowserChildProcessHost instances to release whatever
[email protected]325a71f2010-05-21 23:05:27522 // IO thread only resources they are referencing.
[email protected]d27893f62010-07-03 05:47:42523 BrowserChildProcessHost::TerminateAll();
[email protected]325a71f2010-05-21 23:05:27524
[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]db0e86dd2011-03-16 14:47:21533 system_proxy_config_service_.reset();
534
[email protected]d13c3272010-02-04 00:24:51535 delete globals_;
536 globals_ = NULL;
[email protected]0ac83682010-01-22 17:46:27537
[email protected]569c7602011-03-03 20:40:32538 // net::URLRequest instances must NOT outlive the IO thread.
539 base::debug::LeakTracker<net::URLRequest>::CheckForLeaks();
[email protected]2a92cd92010-04-27 00:01:41540
[email protected]db0e86dd2011-03-16 14:47:21541 base::debug::LeakTracker<SystemURLRequestContextGetter>::CheckForLeaks();
[email protected]0ac83682010-01-22 17:46:27542}
543
[email protected]bcefe0f2010-11-10 16:19:10544// static
545void IOThread::RegisterPrefs(PrefService* local_state) {
546 local_state->RegisterStringPref(prefs::kAuthSchemes,
547 "basic,digest,ntlm,negotiate");
548 local_state->RegisterBooleanPref(prefs::kDisableAuthNegotiateCnameLookup,
549 false);
550 local_state->RegisterBooleanPref(prefs::kEnableAuthNegotiatePort, false);
551 local_state->RegisterStringPref(prefs::kAuthServerWhitelist, "");
552 local_state->RegisterStringPref(prefs::kAuthNegotiateDelegateWhitelist, "");
[email protected]ac7f3fdb2010-11-12 12:47:05553 local_state->RegisterStringPref(prefs::kGSSAPILibraryName, "");
[email protected]0a8db0d2011-04-13 15:15:40554 local_state->RegisterBooleanPref(prefs::kEnableReferrers, true);
[email protected]bcefe0f2010-11-10 16:19:10555}
556
[email protected]65d34382010-07-01 18:12:26557net::HttpAuthHandlerFactory* IOThread::CreateDefaultAuthHandlerFactory(
558 net::HostResolver* resolver) {
[email protected]9030a632010-11-19 20:12:09559 net::HttpAuthFilterWhitelist* auth_filter_default_credentials = NULL;
560 if (!auth_server_whitelist_.empty()) {
561 auth_filter_default_credentials =
562 new net::HttpAuthFilterWhitelist(auth_server_whitelist_);
563 }
564 net::HttpAuthFilterWhitelist* auth_filter_delegate = NULL;
565 if (!auth_delegate_whitelist_.empty()) {
566 auth_filter_delegate =
567 new net::HttpAuthFilterWhitelist(auth_delegate_whitelist_);
568 }
[email protected]b4955e7d2010-04-16 20:22:30569 globals_->url_security_manager.reset(
[email protected]d201b200e2010-08-27 17:35:02570 net::URLSecurityManager::Create(auth_filter_default_credentials,
571 auth_filter_delegate));
[email protected]b7304162010-08-23 17:42:29572 std::vector<std::string> supported_schemes;
[email protected]bcefe0f2010-11-10 16:19:10573 base::SplitString(auth_schemes_, ',', &supported_schemes);
[email protected]b7304162010-08-23 17:42:29574
575 return net::HttpAuthHandlerRegistryFactory::Create(
576 supported_schemes,
577 globals_->url_security_manager.get(),
578 resolver,
[email protected]ac7f3fdb2010-11-12 12:47:05579 gssapi_library_name_,
[email protected]bcefe0f2010-11-10 16:19:10580 negotiate_disable_cname_lookup_,
581 negotiate_enable_port_);
[email protected]eb3cac72010-02-26 21:07:45582}
583
[email protected]d6f37fc2011-02-13 23:58:41584void IOThread::ClearHostCache() {
585 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
586
[email protected]489d1a82011-10-12 03:09:11587 net::HostCache* host_cache = globals_->host_resolver->GetHostCache();
588 if (host_cache)
589 host_cache->clear();
[email protected]0ac83682010-01-22 17:46:27590}
[email protected]db0e86dd2011-03-16 14:47:21591
[email protected]4d45a6de2011-05-13 05:20:18592net::SSLConfigService* IOThread::GetSSLConfigService() {
593 return ssl_config_service_manager_->Get();
594}
595
[email protected]db0e86dd2011-03-16 14:47:21596void IOThread::InitSystemRequestContext() {
[email protected]addb3242011-06-13 21:39:16597 if (system_url_request_context_getter_)
598 return;
[email protected]63e26822011-07-16 19:07:35599 // If we're in unit_tests, IOThread may not be run.
[email protected]dd483702011-12-02 14:47:42600 if (!BrowserThread::IsMessageLoopValid(BrowserThread::IO))
[email protected]63e26822011-07-16 19:07:35601 return;
[email protected]6f96cbcb2011-11-04 02:26:07602 ChromeProxyConfigService* proxy_config_service =
603 ProxyServiceFactory::CreateProxyConfigService();
604 system_proxy_config_service_.reset(proxy_config_service);
605 if (pref_proxy_config_tracker_.get()) {
606 pref_proxy_config_tracker_->SetChromeProxyConfigService(
607 proxy_config_service);
608 }
[email protected]addb3242011-06-13 21:39:16609 system_url_request_context_getter_ =
610 new SystemURLRequestContextGetter(this);
[email protected]2e5b60a22011-11-28 15:56:41611 // Safe to post an unretained this pointer, since IOThread is
612 // guaranteed to outlive the IO BrowserThread.
[email protected]dd483702011-12-02 14:47:42613 BrowserThread::PostTask(
614 BrowserThread::IO,
615 FROM_HERE,
616 base::Bind(&IOThread::InitSystemRequestContextOnIOThread,
617 base::Unretained(this)));
[email protected]addb3242011-06-13 21:39:16618}
619
620void IOThread::InitSystemRequestContextOnIOThread() {
[email protected]db0e86dd2011-03-16 14:47:21621 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]6104ea5d2011-04-27 21:37:12622 DCHECK(!globals_->system_proxy_service.get());
[email protected]db0e86dd2011-03-16 14:47:21623 DCHECK(system_proxy_config_service_.get());
624
625 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
[email protected]6104ea5d2011-04-27 21:37:12626 globals_->system_proxy_service.reset(
[email protected]db0e86dd2011-03-16 14:47:21627 ProxyServiceFactory::CreateProxyService(
628 net_log_,
629 globals_->proxy_script_fetcher_context,
630 system_proxy_config_service_.release(),
[email protected]6104ea5d2011-04-27 21:37:12631 command_line));
[email protected]db0e86dd2011-03-16 14:47:21632 net::HttpNetworkSession::Params system_params;
633 system_params.host_resolver = globals_->host_resolver.get();
634 system_params.cert_verifier = globals_->cert_verifier.get();
[email protected]273e37d2011-08-11 01:49:12635 system_params.origin_bound_cert_service =
636 globals_->system_origin_bound_cert_service.get();
[email protected]db0e86dd2011-03-16 14:47:21637 system_params.dnsrr_resolver = globals_->dnsrr_resolver.get();
638 system_params.dns_cert_checker = NULL;
639 system_params.ssl_host_info_factory = NULL;
640 system_params.proxy_service = globals_->system_proxy_service.get();
641 system_params.ssl_config_service = globals_->ssl_config_service.get();
642 system_params.http_auth_handler_factory =
643 globals_->http_auth_handler_factory.get();
[email protected]17291a022011-10-10 07:32:53644 system_params.http_server_properties = globals_->http_server_properties.get();
[email protected]db0e86dd2011-03-16 14:47:21645 system_params.network_delegate = globals_->system_network_delegate.get();
646 system_params.net_log = net_log_;
647 globals_->system_http_transaction_factory.reset(
648 new net::HttpNetworkLayer(
649 new net::HttpNetworkSession(system_params)));
[email protected]933bc5c62011-04-12 19:08:02650 globals_->system_ftp_transaction_factory.reset(
651 new net::FtpNetworkLayer(globals_->host_resolver.get()));
[email protected]db0e86dd2011-03-16 14:47:21652 globals_->system_request_context =
653 ConstructSystemRequestContext(globals_, net_log_);
654}