blob: 34c18ff00766938cad307a7b2adad3956728ced8 [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]df2840d2011-02-20 16:32:3218#include "chrome/browser/browser_process.h"
[email protected]3ce02412011-03-01 12:01:1519#include "chrome/browser/extensions/extension_event_router_forwarder.h"
20#include "chrome/browser/net/chrome_network_delegate.h"
[email protected]9e743cd2010-03-16 07:03:5321#include "chrome/browser/net/chrome_net_log.h"
[email protected]0ee7a3b2010-11-09 06:13:4022#include "chrome/browser/net/chrome_url_request_context.h"
[email protected]1889dc1b2010-10-14 22:03:1323#include "chrome/browser/net/connect_interceptor.h"
[email protected]9e743cd2010-03-16 07:03:5324#include "chrome/browser/net/passive_log_collector.h"
[email protected]86933612010-10-16 23:10:3325#include "chrome/browser/net/predictor_api.h"
[email protected]bcefe0f2010-11-10 16:19:1026#include "chrome/browser/prefs/pref_service.h"
[email protected]0ac83682010-01-22 17:46:2727#include "chrome/common/chrome_switches.h"
[email protected]2258c1c92010-10-28 17:51:1928#include "chrome/common/net/raw_host_resolver_proc.h"
[email protected]68d2a05f2010-05-07 21:39:5529#include "chrome/common/net/url_fetcher.h"
[email protected]bcefe0f2010-11-10 16:19:1030#include "chrome/common/pref_names.h"
[email protected]567812d2011-02-24 17:40:5031#include "content/browser/browser_thread.h"
32#include "content/browser/gpu_process_host.h"
33#include "content/browser/in_process_webkit/indexed_db_key_utility_client.h"
[email protected]822581d2010-12-16 17:27:1534#include "net/base/cert_verifier.h"
[email protected]f6c21cb2011-02-16 19:45:4135#include "net/base/cookie_monster.h"
[email protected]2db580532010-10-08 14:32:3736#include "net/base/dnsrr_resolver.h"
[email protected]0ac83682010-01-22 17:46:2737#include "net/base/host_cache.h"
38#include "net/base/host_resolver.h"
[email protected]f2d8c4212010-02-02 00:56:3539#include "net/base/host_resolver_impl.h"
[email protected]86933612010-10-16 23:10:3340#include "net/base/mapped_host_resolver.h"
[email protected]32eaa332010-02-08 22:15:5441#include "net/base/net_util.h"
[email protected]eb3cac72010-02-26 21:07:4542#include "net/http/http_auth_filter.h"
[email protected]fa55e192010-02-15 14:25:5043#include "net/http/http_auth_handler_factory.h"
[email protected]2fb629202010-12-23 23:52:5744#include "net/http/http_network_layer.h"
[email protected]57cb0f72011-01-28 06:33:5845#include "net/http/http_network_session.h"
[email protected]70b92342010-10-12 05:54:0646#if defined(USE_NSS)
47#include "net/ocsp/nss_ocsp.h"
48#endif // defined(USE_NSS)
[email protected]86933612010-10-16 23:10:3349#include "net/proxy/proxy_script_fetcher_impl.h"
[email protected]0ac83682010-01-22 17:46:2750
51namespace {
52
[email protected]ee094b82010-08-24 15:55:5153net::HostResolver* CreateGlobalHostResolver(net::NetLog* net_log) {
[email protected]0ac83682010-01-22 17:46:2754 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
[email protected]962b98212010-07-17 03:37:5155
56 size_t parallelism = net::HostResolver::kDefaultParallelism;
57
58 // Use the concurrency override from the command-line, if any.
59 if (command_line.HasSwitch(switches::kHostResolverParallelism)) {
60 std::string s =
61 command_line.GetSwitchValueASCII(switches::kHostResolverParallelism);
62
63 // Parse the switch (it should be a positive integer formatted as decimal).
64 int n;
[email protected]e83326f2010-07-31 17:29:2565 if (base::StringToInt(s, &n) && n > 0) {
[email protected]962b98212010-07-17 03:37:5166 parallelism = static_cast<size_t>(n);
67 } else {
68 LOG(ERROR) << "Invalid switch for host resolver parallelism: " << s;
69 }
[email protected]ecd95ae2010-10-20 23:58:1770 } else {
71 // Set up a field trial to see what impact the total number of concurrent
72 // resolutions have on DNS resolutions.
73 base::FieldTrial::Probability kDivisor = 1000;
74 // For each option (i.e., non-default), we have a fixed probability.
75 base::FieldTrial::Probability kProbabilityPerGroup = 100; // 10%.
76
[email protected]933729bc2011-01-19 18:52:3277 // After June 30, 2011 builds, it will always be in default group
78 // (parallel_default).
[email protected]ad8e04a2010-11-01 04:16:2779 scoped_refptr<base::FieldTrial> trial(
[email protected]933729bc2011-01-19 18:52:3280 new base::FieldTrial(
81 "DnsParallelism", kDivisor, "parallel_default", 2011, 6, 30));
[email protected]ecd95ae2010-10-20 23:58:1782
83 // List options with different counts.
84 // Firefox limits total to 8 in parallel, and default is currently 50.
85 int parallel_6 = trial->AppendGroup("parallel_6", kProbabilityPerGroup);
[email protected]755a93352010-10-29 06:33:5986 int parallel_7 = trial->AppendGroup("parallel_7", kProbabilityPerGroup);
[email protected]ecd95ae2010-10-20 23:58:1787 int parallel_8 = trial->AppendGroup("parallel_8", kProbabilityPerGroup);
[email protected]755a93352010-10-29 06:33:5988 int parallel_9 = trial->AppendGroup("parallel_9", kProbabilityPerGroup);
[email protected]ecd95ae2010-10-20 23:58:1789 int parallel_10 = trial->AppendGroup("parallel_10", kProbabilityPerGroup);
90 int parallel_14 = trial->AppendGroup("parallel_14", kProbabilityPerGroup);
91 int parallel_20 = trial->AppendGroup("parallel_20", kProbabilityPerGroup);
92
[email protected]ecd95ae2010-10-20 23:58:1793 if (trial->group() == parallel_6)
94 parallelism = 6;
[email protected]755a93352010-10-29 06:33:5995 else if (trial->group() == parallel_7)
96 parallelism = 7;
[email protected]ecd95ae2010-10-20 23:58:1797 else if (trial->group() == parallel_8)
98 parallelism = 8;
[email protected]755a93352010-10-29 06:33:5999 else if (trial->group() == parallel_9)
100 parallelism = 9;
[email protected]ecd95ae2010-10-20 23:58:17101 else if (trial->group() == parallel_10)
102 parallelism = 10;
103 else if (trial->group() == parallel_14)
104 parallelism = 14;
105 else if (trial->group() == parallel_20)
106 parallelism = 20;
[email protected]962b98212010-07-17 03:37:51107 }
108
[email protected]2258c1c92010-10-28 17:51:19109 // Use the specified DNS server for doing raw resolutions if requested
110 // from the command-line.
111 scoped_refptr<net::HostResolverProc> resolver_proc;
112 if (command_line.HasSwitch(switches::kDnsServer)) {
113 std::string dns_ip_string =
114 command_line.GetSwitchValueASCII(switches::kDnsServer);
115 net::IPAddressNumber dns_ip_number;
116 if (net::ParseIPLiteralToNumber(dns_ip_string, &dns_ip_number)) {
117 resolver_proc =
118 new chrome_common_net::RawHostResolverProc(dns_ip_number, NULL);
119 } else {
120 LOG(ERROR) << "Invalid IP address specified for --dns-server: "
121 << dns_ip_string;
122 }
123 }
124
[email protected]962b98212010-07-17 03:37:51125 net::HostResolver* global_host_resolver =
[email protected]2258c1c92010-10-28 17:51:19126 net::CreateSystemHostResolver(parallelism, resolver_proc.get(), net_log);
[email protected]9087aa32010-02-18 08:03:38127
[email protected]0f8f1b432010-03-16 19:06:03128 // Determine if we should disable IPv6 support.
[email protected]9087aa32010-02-18 08:03:38129 if (!command_line.HasSwitch(switches::kEnableIPv6)) {
[email protected]0f8f1b432010-03-16 19:06:03130 if (command_line.HasSwitch(switches::kDisableIPv6)) {
[email protected]46f6e202010-02-26 06:07:25131 global_host_resolver->SetDefaultAddressFamily(net::ADDRESS_FAMILY_IPV4);
[email protected]0f8f1b432010-03-16 19:06:03132 } else {
133 net::HostResolverImpl* host_resolver_impl =
134 global_host_resolver->GetAsHostResolverImpl();
135 if (host_resolver_impl != NULL) {
[email protected]780f8492010-09-16 04:12:15136 // Use probe to decide if support is warranted.
137 host_resolver_impl->ProbeIPv6Support();
[email protected]0f8f1b432010-03-16 19:06:03138 }
139 }
[email protected]9087aa32010-02-18 08:03:38140 }
141
[email protected]9087aa32010-02-18 08:03:38142 // If hostname remappings were specified on the command-line, layer these
143 // rules on top of the real host resolver. This allows forwarding all requests
144 // through a designated test server.
[email protected]0f8f1b432010-03-16 19:06:03145 if (!command_line.HasSwitch(switches::kHostResolverRules))
146 return global_host_resolver;
[email protected]0ac83682010-01-22 17:46:27147
[email protected]0f8f1b432010-03-16 19:06:03148 net::MappedHostResolver* remapped_resolver =
149 new net::MappedHostResolver(global_host_resolver);
150 remapped_resolver->SetRulesFromString(
151 command_line.GetSwitchValueASCII(switches::kHostResolverRules));
152 return remapped_resolver;
[email protected]0ac83682010-01-22 17:46:27153}
154
[email protected]58bc7042010-07-07 18:04:14155class LoggingNetworkChangeObserver
156 : public net::NetworkChangeNotifier::Observer {
157 public:
158 // |net_log| must remain valid throughout our lifetime.
159 explicit LoggingNetworkChangeObserver(net::NetLog* net_log)
160 : net_log_(net_log) {
161 net::NetworkChangeNotifier::AddObserver(this);
162 }
163
164 ~LoggingNetworkChangeObserver() {
165 net::NetworkChangeNotifier::RemoveObserver(this);
166 }
167
168 virtual void OnIPAddressChanged() {
[email protected]8e96e502010-10-21 20:57:12169 VLOG(1) << "Observed a change to the network IP addresses";
[email protected]58bc7042010-07-07 18:04:14170
[email protected]d3aaf3f2010-09-02 20:45:55171 net_log_->AddEntry(net::NetLog::TYPE_NETWORK_IP_ADDRESSES_CHANGED,
[email protected]58bc7042010-07-07 18:04:14172 base::TimeTicks::Now(),
[email protected]d2cbfbe2010-08-12 17:38:16173 net::NetLog::Source(),
[email protected]58bc7042010-07-07 18:04:14174 net::NetLog::PHASE_NONE,
175 NULL);
176 }
177
178 private:
179 net::NetLog* net_log_;
180 DISALLOW_COPY_AND_ASSIGN(LoggingNetworkChangeObserver);
181};
182
[email protected]aeb53f02011-01-15 00:21:34183scoped_refptr<net::URLRequestContext>
[email protected]2fb629202010-12-23 23:52:57184ConstructProxyScriptFetcherContext(IOThread::Globals* globals,
185 net::NetLog* net_log) {
[email protected]aeb53f02011-01-15 00:21:34186 scoped_refptr<net::URLRequestContext> context(new net::URLRequestContext);
[email protected]2fb629202010-12-23 23:52:57187 context->set_net_log(net_log);
188 context->set_host_resolver(globals->host_resolver.get());
189 context->set_cert_verifier(globals->cert_verifier.get());
190 context->set_dnsrr_resolver(globals->dnsrr_resolver.get());
191 context->set_http_auth_handler_factory(
192 globals->http_auth_handler_factory.get());
193 context->set_proxy_service(globals->proxy_script_fetcher_proxy_service.get());
194 context->set_http_transaction_factory(
[email protected]52617df2010-12-24 07:30:01195 globals->proxy_script_fetcher_http_transaction_factory.get());
[email protected]2fb629202010-12-23 23:52:57196 // In-memory cookie store.
197 context->set_cookie_store(new net::CookieMonster(NULL, NULL));
[email protected]3ce02412011-03-01 12:01:15198 context->set_network_delegate(globals->system_network_delegate.get());
[email protected]2fb629202010-12-23 23:52:57199 return context;
200}
201
[email protected]0ac83682010-01-22 17:46:27202} // namespace
203
204// The IOThread object must outlive any tasks posted to the IO thread before the
205// Quit task.
[email protected]c56428f22010-06-16 02:17:23206DISABLE_RUNNABLE_METHOD_REFCOUNT(IOThread);
[email protected]0ac83682010-01-22 17:46:27207
[email protected]1889dc1b2010-10-14 22:03:13208IOThread::Globals::Globals() {}
209
210IOThread::Globals::~Globals() {}
211
[email protected]bcefe0f2010-11-10 16:19:10212// |local_state| is passed in explicitly in order to (1) reduce implicit
213// dependencies and (2) make IOThread more flexible for testing.
[email protected]3ce02412011-03-01 12:01:15214IOThread::IOThread(
215 PrefService* local_state,
216 ChromeNetLog* net_log,
217 ExtensionEventRouterForwarder* extension_event_router_forwarder)
[email protected]f8b3ef82010-10-11 02:45:52218 : BrowserProcessSubThread(BrowserThread::IO),
[email protected]b2fcd0e2010-12-01 15:19:40219 net_log_(net_log),
[email protected]3ce02412011-03-01 12:01:15220 extension_event_router_forwarder_(extension_event_router_forwarder),
[email protected]d13c3272010-02-04 00:24:51221 globals_(NULL),
[email protected]c5629c32010-06-23 01:22:43222 speculative_interceptor_(NULL),
[email protected]bcefe0f2010-11-10 16:19:10223 predictor_(NULL) {
224 // We call RegisterPrefs() here (instead of inside browser_prefs.cc) to make
225 // sure that everything is initialized in the right order.
226 RegisterPrefs(local_state);
227 auth_schemes_ = local_state->GetString(prefs::kAuthSchemes);
228 negotiate_disable_cname_lookup_ = local_state->GetBoolean(
229 prefs::kDisableAuthNegotiateCnameLookup);
230 negotiate_enable_port_ = local_state->GetBoolean(
231 prefs::kEnableAuthNegotiatePort);
232 auth_server_whitelist_ = local_state->GetString(prefs::kAuthServerWhitelist);
233 auth_delegate_whitelist_ = local_state->GetString(
234 prefs::kAuthNegotiateDelegateWhitelist);
[email protected]ac7f3fdb2010-11-12 12:47:05235 gssapi_library_name_ = local_state->GetString(prefs::kGSSAPILibraryName);
[email protected]bcefe0f2010-11-10 16:19:10236}
[email protected]0ac83682010-01-22 17:46:27237
238IOThread::~IOThread() {
239 // We cannot rely on our base class to stop the thread since we want our
240 // CleanUp function to run.
241 Stop();
[email protected]d13c3272010-02-04 00:24:51242 DCHECK(!globals_);
[email protected]0ac83682010-01-22 17:46:27243}
244
[email protected]d13c3272010-02-04 00:24:51245IOThread::Globals* IOThread::globals() {
[email protected]f8b3ef82010-10-11 02:45:52246 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]d13c3272010-02-04 00:24:51247 return globals_;
[email protected]0ac83682010-01-22 17:46:27248}
249
[email protected]b2fcd0e2010-12-01 15:19:40250ChromeNetLog* IOThread::net_log() {
251 return net_log_;
252}
253
[email protected]74be069e82010-06-25 00:12:49254void IOThread::InitNetworkPredictor(
[email protected]0ac83682010-01-22 17:46:27255 bool prefetching_enabled,
[email protected]74be069e82010-06-25 00:12:49256 base::TimeDelta max_dns_queue_delay,
[email protected]755a93352010-10-29 06:33:59257 size_t max_speculative_parallel_resolves,
[email protected]c5629c32010-06-23 01:22:43258 const chrome_common_net::UrlList& startup_urls,
[email protected]760d970a2010-05-18 00:39:18259 ListValue* referral_list,
260 bool preconnect_enabled) {
[email protected]f8b3ef82010-10-11 02:45:52261 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
[email protected]0ac83682010-01-22 17:46:27262 message_loop()->PostTask(
263 FROM_HERE,
264 NewRunnableMethod(
265 this,
[email protected]74be069e82010-06-25 00:12:49266 &IOThread::InitNetworkPredictorOnIOThread,
[email protected]755a93352010-10-29 06:33:59267 prefetching_enabled, max_dns_queue_delay,
268 max_speculative_parallel_resolves,
[email protected]c5629c32010-06-23 01:22:43269 startup_urls, referral_list, preconnect_enabled));
[email protected]0ac83682010-01-22 17:46:27270}
271
[email protected]0ee7a3b2010-11-09 06:13:40272void IOThread::RegisterURLRequestContextGetter(
273 ChromeURLRequestContextGetter* url_request_context_getter) {
274 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
275 std::list<ChromeURLRequestContextGetter*>::const_iterator it =
276 std::find(url_request_context_getters_.begin(),
277 url_request_context_getters_.end(),
278 url_request_context_getter);
279 DCHECK(it == url_request_context_getters_.end());
280 url_request_context_getters_.push_back(url_request_context_getter);
281}
282
283void IOThread::UnregisterURLRequestContextGetter(
284 ChromeURLRequestContextGetter* url_request_context_getter) {
285 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
286 std::list<ChromeURLRequestContextGetter*>::iterator it =
287 std::find(url_request_context_getters_.begin(),
288 url_request_context_getters_.end(),
289 url_request_context_getter);
290 DCHECK(it != url_request_context_getters_.end());
291 // This does not scale, but we shouldn't have many URLRequestContextGetters in
292 // the first place, so this should be fine.
293 url_request_context_getters_.erase(it);
294}
295
[email protected]0ac83682010-01-22 17:46:27296void IOThread::ChangedToOnTheRecord() {
[email protected]f8b3ef82010-10-11 02:45:52297 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
[email protected]0ac83682010-01-22 17:46:27298 message_loop()->PostTask(
299 FROM_HERE,
300 NewRunnableMethod(
301 this,
302 &IOThread::ChangedToOnTheRecordOnIOThread));
303}
304
[email protected]df2840d2011-02-20 16:32:32305void IOThread::ClearNetworkingHistory() {
306 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
307 ClearHostCache();
308 // Discard acrued data used to speculate in the future.
309 chrome_browser_net::DiscardInitialNavigationHistory();
310 if (predictor_)
311 predictor_->DiscardAllResults();
312}
313
[email protected]0ac83682010-01-22 17:46:27314void IOThread::Init() {
[email protected]ba74b0d22010-10-23 05:19:20315 // Though this thread is called the "IO" thread, it actually just routes
316 // messages around; it shouldn't be allowed to perform any blocking disk I/O.
317 base::ThreadRestrictions::SetIOAllowed(false);
[email protected]ba74b0d22010-10-23 05:19:20318
[email protected]0ac83682010-01-22 17:46:27319 BrowserProcessSubThread::Init();
320
[email protected]70b92342010-10-12 05:54:06321 DCHECK_EQ(MessageLoop::TYPE_IO, message_loop()->type());
322
323#if defined(USE_NSS)
324 net::SetMessageLoopForOCSP();
[email protected]ecd95ae2010-10-20 23:58:17325#endif // defined(USE_NSS)
[email protected]70b92342010-10-12 05:54:06326
[email protected]d13c3272010-02-04 00:24:51327 DCHECK(!globals_);
328 globals_ = new Globals;
329
[email protected]58bc7042010-07-07 18:04:14330 // Add an observer that will emit network change events to the ChromeNetLog.
331 // Assuming NetworkChangeNotifier dispatches in FIFO order, we should be
332 // logging the network change before other IO thread consumers respond to it.
333 network_change_observer_.reset(
[email protected]b2fcd0e2010-12-01 15:19:40334 new LoggingNetworkChangeObserver(net_log_));
[email protected]58bc7042010-07-07 18:04:14335
[email protected]3ce02412011-03-01 12:01:15336 globals_->extension_event_router_forwarder =
337 extension_event_router_forwarder_;
338 globals_->system_network_delegate.reset(new ChromeNetworkDelegate(
339 extension_event_router_forwarder_, Profile::kInvalidProfileId));
[email protected]73c45322010-10-01 23:57:54340 globals_->host_resolver.reset(
[email protected]b2fcd0e2010-12-01 15:19:40341 CreateGlobalHostResolver(net_log_));
[email protected]822581d2010-12-16 17:27:15342 globals_->cert_verifier.reset(new net::CertVerifier);
[email protected]2db580532010-10-08 14:32:37343 globals_->dnsrr_resolver.reset(new net::DnsRRResolver);
[email protected]2fb629202010-12-23 23:52:57344 // TODO(willchan): Use the real SSLConfigService.
345 globals_->ssl_config_service =
346 net::SSLConfigService::CreateSystemSSLConfigService();
[email protected]65d34382010-07-01 18:12:26347 globals_->http_auth_handler_factory.reset(CreateDefaultAuthHandlerFactory(
[email protected]73c45322010-10-01 23:57:54348 globals_->host_resolver.get()));
[email protected]2fb629202010-12-23 23:52:57349 // For the ProxyScriptFetcher, we use a direct ProxyService.
350 globals_->proxy_script_fetcher_proxy_service =
351 net::ProxyService::CreateDirectWithNetLog(net_log_);
[email protected]9e1bdd32011-02-03 21:48:34352 net::HttpNetworkSession::Params session_params;
353 session_params.host_resolver = globals_->host_resolver.get();
354 session_params.cert_verifier = globals_->cert_verifier.get();
355 session_params.proxy_service =
356 globals_->proxy_script_fetcher_proxy_service.get();
357 session_params.http_auth_handler_factory =
358 globals_->http_auth_handler_factory.get();
[email protected]0651b812011-02-24 00:22:50359 session_params.network_delegate = globals_->system_network_delegate.get();
[email protected]9e1bdd32011-02-03 21:48:34360 session_params.net_log = net_log_;
361 session_params.ssl_config_service = globals_->ssl_config_service;
[email protected]57cb0f72011-01-28 06:33:58362 scoped_refptr<net::HttpNetworkSession> network_session(
[email protected]9e1bdd32011-02-03 21:48:34363 new net::HttpNetworkSession(session_params));
[email protected]57cb0f72011-01-28 06:33:58364 globals_->proxy_script_fetcher_http_transaction_factory.reset(
365 new net::HttpNetworkLayer(network_session));
[email protected]2fb629202010-12-23 23:52:57366
[email protected]aeb53f02011-01-15 00:21:34367 scoped_refptr<net::URLRequestContext> proxy_script_fetcher_context =
[email protected]2fb629202010-12-23 23:52:57368 ConstructProxyScriptFetcherContext(globals_, net_log_);
369 globals_->proxy_script_fetcher_context = proxy_script_fetcher_context;
[email protected]0ac83682010-01-22 17:46:27370}
371
[email protected]2a92cd92010-04-27 00:01:41372void IOThread::CleanUp() {
[email protected]0ee7a3b2010-11-09 06:13:40373 // Step 1: Kill all things that might be holding onto
[email protected]aeb53f02011-01-15 00:21:34374 // net::URLRequest/net::URLRequestContexts.
[email protected]0ee7a3b2010-11-09 06:13:40375
[email protected]59a3b362010-10-21 21:52:41376#if defined(USE_NSS)
377 net::ShutdownOCSP();
378#endif // defined(USE_NSS)
379
[email protected]0b1ad312010-10-22 01:01:38380 // Destroy all URLRequests started by URLFetchers.
381 URLFetcher::CancelAll();
382
[email protected]5377d892011-01-21 18:25:43383 IndexedDBKeyUtilityClient::Shutdown();
384
[email protected]325a71f2010-05-21 23:05:27385 // If any child processes are still running, terminate them and
[email protected]d27893f62010-07-03 05:47:42386 // and delete the BrowserChildProcessHost instances to release whatever
[email protected]325a71f2010-05-21 23:05:27387 // IO thread only resources they are referencing.
[email protected]d27893f62010-07-03 05:47:42388 BrowserChildProcessHost::TerminateAll();
[email protected]325a71f2010-05-21 23:05:27389
[email protected]0ee7a3b2010-11-09 06:13:40390 std::list<ChromeURLRequestContextGetter*> url_request_context_getters;
391 url_request_context_getters.swap(url_request_context_getters_);
392 for (std::list<ChromeURLRequestContextGetter*>::iterator it =
393 url_request_context_getters.begin();
394 it != url_request_context_getters.end(); ++it) {
395 ChromeURLRequestContextGetter* getter = *it;
[email protected]361fe8a2010-11-24 17:20:49396 // Stop all pending certificate provenance check uploads
397 net::DnsCertProvenanceChecker* checker =
398 getter->GetURLRequestContext()->dns_cert_checker();
399 if (checker)
400 checker->Shutdown();
[email protected]0ee7a3b2010-11-09 06:13:40401 getter->ReleaseURLRequestContext();
402 }
403
[email protected]aeb53f02011-01-15 00:21:34404 // Step 2: Release objects that the net::URLRequestContext could have been
405 // pointing to.
[email protected]0ee7a3b2010-11-09 06:13:40406
407 // This must be reset before the ChromeNetLog is destroyed.
408 network_change_observer_.reset();
409
[email protected]0ac83682010-01-22 17:46:27410 // Not initialized in Init(). May not be initialized.
[email protected]74be069e82010-06-25 00:12:49411 if (predictor_) {
412 predictor_->Shutdown();
[email protected]0ac83682010-01-22 17:46:27413
[email protected]74be069e82010-06-25 00:12:49414 // TODO(willchan): Stop reference counting Predictor. It's owned by
[email protected]0ac83682010-01-22 17:46:27415 // IOThread now.
[email protected]74be069e82010-06-25 00:12:49416 predictor_->Release();
417 predictor_ = NULL;
418 chrome_browser_net::FreePredictorResources();
[email protected]0ac83682010-01-22 17:46:27419 }
420
[email protected]c5629c32010-06-23 01:22:43421 // Deletion will unregister this interceptor.
422 delete speculative_interceptor_;
423 speculative_interceptor_ = NULL;
424
[email protected]e4d2dd822010-02-05 20:57:33425 // TODO(eroman): hack for http://crbug.com/15513
[email protected]970210c2010-02-19 20:27:02426 if (globals_->host_resolver->GetAsHostResolverImpl()) {
427 globals_->host_resolver.get()->GetAsHostResolverImpl()->Shutdown();
[email protected]e4d2dd822010-02-05 20:57:33428 }
[email protected]0ac83682010-01-22 17:46:27429
[email protected]d13c3272010-02-04 00:24:51430 delete globals_;
431 globals_ = NULL;
[email protected]0ac83682010-01-22 17:46:27432
[email protected]2a92cd92010-04-27 00:01:41433 BrowserProcessSubThread::CleanUp();
434}
435
436void IOThread::CleanUpAfterMessageLoopDestruction() {
[email protected]0ee7a3b2010-11-09 06:13:40437 // This will delete the |notification_service_|. Make sure it's done after
438 // anything else can reference it.
[email protected]9aa33e82010-04-15 00:15:39439 BrowserProcessSubThread::CleanUpAfterMessageLoopDestruction();
[email protected]4411da942010-10-25 15:06:02440
[email protected]6981d9632010-11-30 21:34:02441 // net::URLRequest instances must NOT outlive the IO thread.
[email protected]4411da942010-10-25 15:06:02442 //
443 // To allow for URLRequests to be deleted from
444 // MessageLoop::DestructionObserver this check has to happen after CleanUp
445 // (which runs before DestructionObservers).
[email protected]6981d9632010-11-30 21:34:02446 base::debug::LeakTracker<net::URLRequest>::CheckForLeaks();
[email protected]0ac83682010-01-22 17:46:27447}
448
[email protected]bcefe0f2010-11-10 16:19:10449// static
450void IOThread::RegisterPrefs(PrefService* local_state) {
451 local_state->RegisterStringPref(prefs::kAuthSchemes,
452 "basic,digest,ntlm,negotiate");
453 local_state->RegisterBooleanPref(prefs::kDisableAuthNegotiateCnameLookup,
454 false);
455 local_state->RegisterBooleanPref(prefs::kEnableAuthNegotiatePort, false);
456 local_state->RegisterStringPref(prefs::kAuthServerWhitelist, "");
457 local_state->RegisterStringPref(prefs::kAuthNegotiateDelegateWhitelist, "");
[email protected]ac7f3fdb2010-11-12 12:47:05458 local_state->RegisterStringPref(prefs::kGSSAPILibraryName, "");
[email protected]bcefe0f2010-11-10 16:19:10459}
460
[email protected]65d34382010-07-01 18:12:26461net::HttpAuthHandlerFactory* IOThread::CreateDefaultAuthHandlerFactory(
462 net::HostResolver* resolver) {
[email protected]9030a632010-11-19 20:12:09463 net::HttpAuthFilterWhitelist* auth_filter_default_credentials = NULL;
464 if (!auth_server_whitelist_.empty()) {
465 auth_filter_default_credentials =
466 new net::HttpAuthFilterWhitelist(auth_server_whitelist_);
467 }
468 net::HttpAuthFilterWhitelist* auth_filter_delegate = NULL;
469 if (!auth_delegate_whitelist_.empty()) {
470 auth_filter_delegate =
471 new net::HttpAuthFilterWhitelist(auth_delegate_whitelist_);
472 }
[email protected]b4955e7d2010-04-16 20:22:30473 globals_->url_security_manager.reset(
[email protected]d201b200e2010-08-27 17:35:02474 net::URLSecurityManager::Create(auth_filter_default_credentials,
475 auth_filter_delegate));
[email protected]b7304162010-08-23 17:42:29476 std::vector<std::string> supported_schemes;
[email protected]bcefe0f2010-11-10 16:19:10477 base::SplitString(auth_schemes_, ',', &supported_schemes);
[email protected]b7304162010-08-23 17:42:29478
479 return net::HttpAuthHandlerRegistryFactory::Create(
480 supported_schemes,
481 globals_->url_security_manager.get(),
482 resolver,
[email protected]ac7f3fdb2010-11-12 12:47:05483 gssapi_library_name_,
[email protected]bcefe0f2010-11-10 16:19:10484 negotiate_disable_cname_lookup_,
485 negotiate_enable_port_);
[email protected]eb3cac72010-02-26 21:07:45486}
487
[email protected]74be069e82010-06-25 00:12:49488void IOThread::InitNetworkPredictorOnIOThread(
[email protected]0ac83682010-01-22 17:46:27489 bool prefetching_enabled,
[email protected]74be069e82010-06-25 00:12:49490 base::TimeDelta max_dns_queue_delay,
[email protected]755a93352010-10-29 06:33:59491 size_t max_speculative_parallel_resolves,
[email protected]c5629c32010-06-23 01:22:43492 const chrome_common_net::UrlList& startup_urls,
[email protected]760d970a2010-05-18 00:39:18493 ListValue* referral_list,
494 bool preconnect_enabled) {
[email protected]f8b3ef82010-10-11 02:45:52495 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]74be069e82010-06-25 00:12:49496 CHECK(!predictor_);
[email protected]0ac83682010-01-22 17:46:27497
[email protected]74be069e82010-06-25 00:12:49498 chrome_browser_net::EnablePredictor(prefetching_enabled);
[email protected]0ac83682010-01-22 17:46:27499
[email protected]74be069e82010-06-25 00:12:49500 predictor_ = new chrome_browser_net::Predictor(
[email protected]73c45322010-10-01 23:57:54501 globals_->host_resolver.get(),
[email protected]74be069e82010-06-25 00:12:49502 max_dns_queue_delay,
[email protected]755a93352010-10-29 06:33:59503 max_speculative_parallel_resolves,
[email protected]760d970a2010-05-18 00:39:18504 preconnect_enabled);
[email protected]74be069e82010-06-25 00:12:49505 predictor_->AddRef();
[email protected]0ac83682010-01-22 17:46:27506
[email protected]f4ef861ba2010-07-28 22:37:23507 // Speculative_interceptor_ is used to predict subresource usage.
508 DCHECK(!speculative_interceptor_);
509 speculative_interceptor_ = new chrome_browser_net::ConnectInterceptor;
510
[email protected]bff1f512010-08-15 15:13:49511 FinalizePredictorInitialization(predictor_, startup_urls, referral_list);
[email protected]0ac83682010-01-22 17:46:27512}
513
514void IOThread::ChangedToOnTheRecordOnIOThread() {
[email protected]f8b3ef82010-10-11 02:45:52515 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]0ac83682010-01-22 17:46:27516
[email protected]74be069e82010-06-25 00:12:49517 if (predictor_) {
[email protected]0ac83682010-01-22 17:46:27518 // Destroy all evidence of our OTR session.
[email protected]df2840d2011-02-20 16:32:32519 // Note: OTR mode never saves InitialNavigationHistory data.
[email protected]74be069e82010-06-25 00:12:49520 predictor_->Predictor::DiscardAllResults();
[email protected]0ac83682010-01-22 17:46:27521 }
522
523 // Clear the host cache to avoid showing entries from the OTR session
524 // in about:net-internals.
[email protected]d6f37fc2011-02-13 23:58:41525 ClearHostCache();
526
527 // Clear all of the passively logged data.
528 // TODO(eroman): this is a bit heavy handed, really all we need to do is
529 // clear the data pertaining to off the record context.
530 net_log_->ClearAllPassivelyCapturedEvents();
531}
532
533void IOThread::ClearHostCache() {
534 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
535
[email protected]970210c2010-02-19 20:27:02536 if (globals_->host_resolver->GetAsHostResolverImpl()) {
537 net::HostCache* host_cache =
538 globals_->host_resolver.get()->GetAsHostResolverImpl()->cache();
[email protected]f2d8c4212010-02-02 00:56:35539 if (host_cache)
540 host_cache->clear();
541 }
[email protected]0ac83682010-01-22 17:46:27542}