blob: 9b7f7180319fcdbd0db228f4f18347a05c2d3cc5 [file] [log] [blame]
[email protected]0ac83682010-01-22 17:46:271// Copyright (c) 2010 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
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]ba74b0d22010-10-23 05:19:2017#include "base/thread_restrictions.h"
[email protected]0ac83682010-01-22 17:46:2718#include "chrome/browser/browser_process.h"
[email protected]e36717272010-10-12 12:07:1319#include "chrome/browser/browser_thread.h"
[email protected]1082b1d2010-03-30 00:31:2220#include "chrome/browser/gpu_process_host.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]2db580532010-10-08 14:32:3731#include "net/base/dnsrr_resolver.h"
[email protected]0ac83682010-01-22 17:46:2732#include "net/base/host_cache.h"
33#include "net/base/host_resolver.h"
[email protected]f2d8c4212010-02-02 00:56:3534#include "net/base/host_resolver_impl.h"
[email protected]86933612010-10-16 23:10:3335#include "net/base/mapped_host_resolver.h"
[email protected]32eaa332010-02-08 22:15:5436#include "net/base/net_util.h"
[email protected]eb3cac72010-02-26 21:07:4537#include "net/http/http_auth_filter.h"
[email protected]fa55e192010-02-15 14:25:5038#include "net/http/http_auth_handler_factory.h"
[email protected]70b92342010-10-12 05:54:0639#if defined(USE_NSS)
40#include "net/ocsp/nss_ocsp.h"
41#endif // defined(USE_NSS)
[email protected]86933612010-10-16 23:10:3342#include "net/proxy/proxy_script_fetcher_impl.h"
[email protected]0ac83682010-01-22 17:46:2743
44namespace {
45
[email protected]ee094b82010-08-24 15:55:5146net::HostResolver* CreateGlobalHostResolver(net::NetLog* net_log) {
[email protected]0ac83682010-01-22 17:46:2747 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
[email protected]962b98212010-07-17 03:37:5148
49 size_t parallelism = net::HostResolver::kDefaultParallelism;
50
51 // Use the concurrency override from the command-line, if any.
52 if (command_line.HasSwitch(switches::kHostResolverParallelism)) {
53 std::string s =
54 command_line.GetSwitchValueASCII(switches::kHostResolverParallelism);
55
56 // Parse the switch (it should be a positive integer formatted as decimal).
57 int n;
[email protected]e83326f2010-07-31 17:29:2558 if (base::StringToInt(s, &n) && n > 0) {
[email protected]962b98212010-07-17 03:37:5159 parallelism = static_cast<size_t>(n);
60 } else {
61 LOG(ERROR) << "Invalid switch for host resolver parallelism: " << s;
62 }
[email protected]ecd95ae2010-10-20 23:58:1763 } else {
64 // Set up a field trial to see what impact the total number of concurrent
65 // resolutions have on DNS resolutions.
66 base::FieldTrial::Probability kDivisor = 1000;
67 // For each option (i.e., non-default), we have a fixed probability.
68 base::FieldTrial::Probability kProbabilityPerGroup = 100; // 10%.
69
[email protected]ad8e04a2010-11-01 04:16:2770 scoped_refptr<base::FieldTrial> trial(
71 new base::FieldTrial("DnsParallelism", kDivisor));
[email protected]ecd95ae2010-10-20 23:58:1772
73 // List options with different counts.
74 // Firefox limits total to 8 in parallel, and default is currently 50.
75 int parallel_6 = trial->AppendGroup("parallel_6", kProbabilityPerGroup);
[email protected]755a93352010-10-29 06:33:5976 int parallel_7 = trial->AppendGroup("parallel_7", kProbabilityPerGroup);
[email protected]ecd95ae2010-10-20 23:58:1777 int parallel_8 = trial->AppendGroup("parallel_8", kProbabilityPerGroup);
[email protected]755a93352010-10-29 06:33:5978 int parallel_9 = trial->AppendGroup("parallel_9", kProbabilityPerGroup);
[email protected]ecd95ae2010-10-20 23:58:1779 int parallel_10 = trial->AppendGroup("parallel_10", kProbabilityPerGroup);
80 int parallel_14 = trial->AppendGroup("parallel_14", kProbabilityPerGroup);
81 int parallel_20 = trial->AppendGroup("parallel_20", kProbabilityPerGroup);
82
83 trial->AppendGroup("parallel_default",
84 base::FieldTrial::kAllRemainingProbability);
85
86 if (trial->group() == parallel_6)
87 parallelism = 6;
[email protected]755a93352010-10-29 06:33:5988 else if (trial->group() == parallel_7)
89 parallelism = 7;
[email protected]ecd95ae2010-10-20 23:58:1790 else if (trial->group() == parallel_8)
91 parallelism = 8;
[email protected]755a93352010-10-29 06:33:5992 else if (trial->group() == parallel_9)
93 parallelism = 9;
[email protected]ecd95ae2010-10-20 23:58:1794 else if (trial->group() == parallel_10)
95 parallelism = 10;
96 else if (trial->group() == parallel_14)
97 parallelism = 14;
98 else if (trial->group() == parallel_20)
99 parallelism = 20;
[email protected]962b98212010-07-17 03:37:51100 }
101
[email protected]2258c1c92010-10-28 17:51:19102 // Use the specified DNS server for doing raw resolutions if requested
103 // from the command-line.
104 scoped_refptr<net::HostResolverProc> resolver_proc;
105 if (command_line.HasSwitch(switches::kDnsServer)) {
106 std::string dns_ip_string =
107 command_line.GetSwitchValueASCII(switches::kDnsServer);
108 net::IPAddressNumber dns_ip_number;
109 if (net::ParseIPLiteralToNumber(dns_ip_string, &dns_ip_number)) {
110 resolver_proc =
111 new chrome_common_net::RawHostResolverProc(dns_ip_number, NULL);
112 } else {
113 LOG(ERROR) << "Invalid IP address specified for --dns-server: "
114 << dns_ip_string;
115 }
116 }
117
[email protected]962b98212010-07-17 03:37:51118 net::HostResolver* global_host_resolver =
[email protected]2258c1c92010-10-28 17:51:19119 net::CreateSystemHostResolver(parallelism, resolver_proc.get(), net_log);
[email protected]9087aa32010-02-18 08:03:38120
[email protected]0f8f1b432010-03-16 19:06:03121 // Determine if we should disable IPv6 support.
[email protected]9087aa32010-02-18 08:03:38122 if (!command_line.HasSwitch(switches::kEnableIPv6)) {
[email protected]0f8f1b432010-03-16 19:06:03123 if (command_line.HasSwitch(switches::kDisableIPv6)) {
[email protected]46f6e202010-02-26 06:07:25124 global_host_resolver->SetDefaultAddressFamily(net::ADDRESS_FAMILY_IPV4);
[email protected]0f8f1b432010-03-16 19:06:03125 } else {
126 net::HostResolverImpl* host_resolver_impl =
127 global_host_resolver->GetAsHostResolverImpl();
128 if (host_resolver_impl != NULL) {
[email protected]780f8492010-09-16 04:12:15129 // Use probe to decide if support is warranted.
130 host_resolver_impl->ProbeIPv6Support();
[email protected]0f8f1b432010-03-16 19:06:03131 }
132 }
[email protected]9087aa32010-02-18 08:03:38133 }
134
[email protected]9087aa32010-02-18 08:03:38135 // If hostname remappings were specified on the command-line, layer these
136 // rules on top of the real host resolver. This allows forwarding all requests
137 // through a designated test server.
[email protected]0f8f1b432010-03-16 19:06:03138 if (!command_line.HasSwitch(switches::kHostResolverRules))
139 return global_host_resolver;
[email protected]0ac83682010-01-22 17:46:27140
[email protected]0f8f1b432010-03-16 19:06:03141 net::MappedHostResolver* remapped_resolver =
142 new net::MappedHostResolver(global_host_resolver);
143 remapped_resolver->SetRulesFromString(
144 command_line.GetSwitchValueASCII(switches::kHostResolverRules));
145 return remapped_resolver;
[email protected]0ac83682010-01-22 17:46:27146}
147
[email protected]58bc7042010-07-07 18:04:14148class LoggingNetworkChangeObserver
149 : public net::NetworkChangeNotifier::Observer {
150 public:
151 // |net_log| must remain valid throughout our lifetime.
152 explicit LoggingNetworkChangeObserver(net::NetLog* net_log)
153 : net_log_(net_log) {
154 net::NetworkChangeNotifier::AddObserver(this);
155 }
156
157 ~LoggingNetworkChangeObserver() {
158 net::NetworkChangeNotifier::RemoveObserver(this);
159 }
160
161 virtual void OnIPAddressChanged() {
[email protected]8e96e502010-10-21 20:57:12162 VLOG(1) << "Observed a change to the network IP addresses";
[email protected]58bc7042010-07-07 18:04:14163
[email protected]d3aaf3f2010-09-02 20:45:55164 net_log_->AddEntry(net::NetLog::TYPE_NETWORK_IP_ADDRESSES_CHANGED,
[email protected]58bc7042010-07-07 18:04:14165 base::TimeTicks::Now(),
[email protected]d2cbfbe2010-08-12 17:38:16166 net::NetLog::Source(),
[email protected]58bc7042010-07-07 18:04:14167 net::NetLog::PHASE_NONE,
168 NULL);
169 }
170
171 private:
172 net::NetLog* net_log_;
173 DISALLOW_COPY_AND_ASSIGN(LoggingNetworkChangeObserver);
174};
175
[email protected]0ac83682010-01-22 17:46:27176} // namespace
177
[email protected]86933612010-10-16 23:10:33178// This is a wrapper class around ProxyScriptFetcherImpl that will
179// keep track of live instances.
180class IOThread::ManagedProxyScriptFetcher
181 : public net::ProxyScriptFetcherImpl {
182 public:
183 ManagedProxyScriptFetcher(URLRequestContext* context,
184 IOThread* io_thread)
185 : net::ProxyScriptFetcherImpl(context),
186 io_thread_(io_thread) {
187 DCHECK(!ContainsKey(*fetchers(), this));
188 fetchers()->insert(this);
189 }
190
191 virtual ~ManagedProxyScriptFetcher() {
192 DCHECK(ContainsKey(*fetchers(), this));
193 fetchers()->erase(this);
194 }
195
196 private:
197 ProxyScriptFetchers* fetchers() {
198 return &io_thread_->fetchers_;
199 }
200
201 IOThread* io_thread_;
202
203 DISALLOW_COPY_AND_ASSIGN(ManagedProxyScriptFetcher);
204};
205
[email protected]0ac83682010-01-22 17:46:27206// The IOThread object must outlive any tasks posted to the IO thread before the
207// Quit task.
[email protected]c56428f22010-06-16 02:17:23208DISABLE_RUNNABLE_METHOD_REFCOUNT(IOThread);
[email protected]0ac83682010-01-22 17:46:27209
[email protected]1889dc1b2010-10-14 22:03:13210IOThread::Globals::Globals() {}
211
212IOThread::Globals::~Globals() {}
213
[email protected]bcefe0f2010-11-10 16:19:10214// |local_state| is passed in explicitly in order to (1) reduce implicit
215// dependencies and (2) make IOThread more flexible for testing.
216IOThread::IOThread(PrefService* local_state)
[email protected]f8b3ef82010-10-11 02:45:52217 : BrowserProcessSubThread(BrowserThread::IO),
[email protected]d13c3272010-02-04 00:24:51218 globals_(NULL),
[email protected]c5629c32010-06-23 01:22:43219 speculative_interceptor_(NULL),
[email protected]bcefe0f2010-11-10 16:19:10220 predictor_(NULL) {
221 // We call RegisterPrefs() here (instead of inside browser_prefs.cc) to make
222 // sure that everything is initialized in the right order.
223 RegisterPrefs(local_state);
224 auth_schemes_ = local_state->GetString(prefs::kAuthSchemes);
225 negotiate_disable_cname_lookup_ = local_state->GetBoolean(
226 prefs::kDisableAuthNegotiateCnameLookup);
227 negotiate_enable_port_ = local_state->GetBoolean(
228 prefs::kEnableAuthNegotiatePort);
229 auth_server_whitelist_ = local_state->GetString(prefs::kAuthServerWhitelist);
230 auth_delegate_whitelist_ = local_state->GetString(
231 prefs::kAuthNegotiateDelegateWhitelist);
232}
[email protected]0ac83682010-01-22 17:46:27233
234IOThread::~IOThread() {
235 // We cannot rely on our base class to stop the thread since we want our
236 // CleanUp function to run.
237 Stop();
[email protected]d13c3272010-02-04 00:24:51238 DCHECK(!globals_);
[email protected]0ac83682010-01-22 17:46:27239}
240
[email protected]d13c3272010-02-04 00:24:51241IOThread::Globals* IOThread::globals() {
[email protected]f8b3ef82010-10-11 02:45:52242 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]d13c3272010-02-04 00:24:51243 return globals_;
[email protected]0ac83682010-01-22 17:46:27244}
245
[email protected]74be069e82010-06-25 00:12:49246void IOThread::InitNetworkPredictor(
[email protected]0ac83682010-01-22 17:46:27247 bool prefetching_enabled,
[email protected]74be069e82010-06-25 00:12:49248 base::TimeDelta max_dns_queue_delay,
[email protected]755a93352010-10-29 06:33:59249 size_t max_speculative_parallel_resolves,
[email protected]c5629c32010-06-23 01:22:43250 const chrome_common_net::UrlList& startup_urls,
[email protected]760d970a2010-05-18 00:39:18251 ListValue* referral_list,
252 bool preconnect_enabled) {
[email protected]f8b3ef82010-10-11 02:45:52253 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
[email protected]0ac83682010-01-22 17:46:27254 message_loop()->PostTask(
255 FROM_HERE,
256 NewRunnableMethod(
257 this,
[email protected]74be069e82010-06-25 00:12:49258 &IOThread::InitNetworkPredictorOnIOThread,
[email protected]755a93352010-10-29 06:33:59259 prefetching_enabled, max_dns_queue_delay,
260 max_speculative_parallel_resolves,
[email protected]c5629c32010-06-23 01:22:43261 startup_urls, referral_list, preconnect_enabled));
[email protected]0ac83682010-01-22 17:46:27262}
263
[email protected]0ee7a3b2010-11-09 06:13:40264void IOThread::RegisterURLRequestContextGetter(
265 ChromeURLRequestContextGetter* url_request_context_getter) {
266 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
267 std::list<ChromeURLRequestContextGetter*>::const_iterator it =
268 std::find(url_request_context_getters_.begin(),
269 url_request_context_getters_.end(),
270 url_request_context_getter);
271 DCHECK(it == url_request_context_getters_.end());
272 url_request_context_getters_.push_back(url_request_context_getter);
273}
274
275void IOThread::UnregisterURLRequestContextGetter(
276 ChromeURLRequestContextGetter* url_request_context_getter) {
277 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
278 std::list<ChromeURLRequestContextGetter*>::iterator it =
279 std::find(url_request_context_getters_.begin(),
280 url_request_context_getters_.end(),
281 url_request_context_getter);
282 DCHECK(it != url_request_context_getters_.end());
283 // This does not scale, but we shouldn't have many URLRequestContextGetters in
284 // the first place, so this should be fine.
285 url_request_context_getters_.erase(it);
286}
287
[email protected]0ac83682010-01-22 17:46:27288void IOThread::ChangedToOnTheRecord() {
[email protected]f8b3ef82010-10-11 02:45:52289 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
[email protected]0ac83682010-01-22 17:46:27290 message_loop()->PostTask(
291 FROM_HERE,
292 NewRunnableMethod(
293 this,
294 &IOThread::ChangedToOnTheRecordOnIOThread));
295}
296
[email protected]86933612010-10-16 23:10:33297net::ProxyScriptFetcher* IOThread::CreateAndRegisterProxyScriptFetcher(
298 URLRequestContext* url_request_context) {
299 return new ManagedProxyScriptFetcher(url_request_context, this);
300}
301
[email protected]0ac83682010-01-22 17:46:27302void IOThread::Init() {
[email protected]45446a52010-11-04 17:41:00303#if !defined(OS_CHROMEOS)
[email protected]ba74b0d22010-10-23 05:19:20304 // TODO(evan): test and enable this on all platforms.
305 // Though this thread is called the "IO" thread, it actually just routes
306 // messages around; it shouldn't be allowed to perform any blocking disk I/O.
307 base::ThreadRestrictions::SetIOAllowed(false);
308#endif
309
[email protected]0ac83682010-01-22 17:46:27310 BrowserProcessSubThread::Init();
311
[email protected]70b92342010-10-12 05:54:06312 DCHECK_EQ(MessageLoop::TYPE_IO, message_loop()->type());
313
314#if defined(USE_NSS)
315 net::SetMessageLoopForOCSP();
[email protected]ecd95ae2010-10-20 23:58:17316#endif // defined(USE_NSS)
[email protected]70b92342010-10-12 05:54:06317
[email protected]d13c3272010-02-04 00:24:51318 DCHECK(!globals_);
319 globals_ = new Globals;
320
[email protected]aa92ba22010-06-21 23:17:24321 globals_->net_log.reset(new ChromeNetLog());
[email protected]58bc7042010-07-07 18:04:14322
323 // Add an observer that will emit network change events to the ChromeNetLog.
324 // Assuming NetworkChangeNotifier dispatches in FIFO order, we should be
325 // logging the network change before other IO thread consumers respond to it.
326 network_change_observer_.reset(
327 new LoggingNetworkChangeObserver(globals_->net_log.get()));
328
[email protected]73c45322010-10-01 23:57:54329 globals_->host_resolver.reset(
330 CreateGlobalHostResolver(globals_->net_log.get()));
[email protected]2db580532010-10-08 14:32:37331 globals_->dnsrr_resolver.reset(new net::DnsRRResolver);
[email protected]65d34382010-07-01 18:12:26332 globals_->http_auth_handler_factory.reset(CreateDefaultAuthHandlerFactory(
[email protected]73c45322010-10-01 23:57:54333 globals_->host_resolver.get()));
[email protected]0ac83682010-01-22 17:46:27334}
335
[email protected]2a92cd92010-04-27 00:01:41336void IOThread::CleanUp() {
[email protected]0ee7a3b2010-11-09 06:13:40337 // Step 1: Kill all things that might be holding onto
338 // URLRequest/URLRequestContexts.
339
[email protected]59a3b362010-10-21 21:52:41340#if defined(USE_NSS)
341 net::ShutdownOCSP();
342#endif // defined(USE_NSS)
343
[email protected]0b1ad312010-10-22 01:01:38344 // Destroy all URLRequests started by URLFetchers.
345 URLFetcher::CancelAll();
346
[email protected]0ee7a3b2010-11-09 06:13:40347 // Break any cycles between the ProxyScriptFetcher and URLRequestContext.
348 for (ProxyScriptFetchers::const_iterator it = fetchers_.begin();
349 it != fetchers_.end(); ++it) {
350 (*it)->Cancel();
351 }
[email protected]58bc7042010-07-07 18:04:14352
[email protected]325a71f2010-05-21 23:05:27353 // If any child processes are still running, terminate them and
[email protected]d27893f62010-07-03 05:47:42354 // and delete the BrowserChildProcessHost instances to release whatever
[email protected]325a71f2010-05-21 23:05:27355 // IO thread only resources they are referencing.
[email protected]d27893f62010-07-03 05:47:42356 BrowserChildProcessHost::TerminateAll();
[email protected]325a71f2010-05-21 23:05:27357
[email protected]0ee7a3b2010-11-09 06:13:40358 std::list<ChromeURLRequestContextGetter*> url_request_context_getters;
359 url_request_context_getters.swap(url_request_context_getters_);
360 for (std::list<ChromeURLRequestContextGetter*>::iterator it =
361 url_request_context_getters.begin();
362 it != url_request_context_getters.end(); ++it) {
363 ChromeURLRequestContextGetter* getter = *it;
364 getter->ReleaseURLRequestContext();
365 }
366
367 // Step 2: Release objects that the URLRequestContext could have been pointing
368 // to.
369
370 // This must be reset before the ChromeNetLog is destroyed.
371 network_change_observer_.reset();
372
[email protected]0ac83682010-01-22 17:46:27373 // Not initialized in Init(). May not be initialized.
[email protected]74be069e82010-06-25 00:12:49374 if (predictor_) {
375 predictor_->Shutdown();
[email protected]0ac83682010-01-22 17:46:27376
[email protected]74be069e82010-06-25 00:12:49377 // TODO(willchan): Stop reference counting Predictor. It's owned by
[email protected]0ac83682010-01-22 17:46:27378 // IOThread now.
[email protected]74be069e82010-06-25 00:12:49379 predictor_->Release();
380 predictor_ = NULL;
381 chrome_browser_net::FreePredictorResources();
[email protected]0ac83682010-01-22 17:46:27382 }
383
[email protected]c5629c32010-06-23 01:22:43384 // Deletion will unregister this interceptor.
385 delete speculative_interceptor_;
386 speculative_interceptor_ = NULL;
387
[email protected]e4d2dd822010-02-05 20:57:33388 // TODO(eroman): hack for http://crbug.com/15513
[email protected]970210c2010-02-19 20:27:02389 if (globals_->host_resolver->GetAsHostResolverImpl()) {
390 globals_->host_resolver.get()->GetAsHostResolverImpl()->Shutdown();
[email protected]e4d2dd822010-02-05 20:57:33391 }
[email protected]0ac83682010-01-22 17:46:27392
[email protected]2a92cd92010-04-27 00:01:41393 // We will delete the NetLog as part of CleanUpAfterMessageLoopDestruction()
394 // in case any of the message loop destruction observers try to access it.
395 deferred_net_log_to_delete_.reset(globals_->net_log.release());
396
[email protected]d13c3272010-02-04 00:24:51397 delete globals_;
398 globals_ = NULL;
[email protected]0ac83682010-01-22 17:46:27399
[email protected]2a92cd92010-04-27 00:01:41400 BrowserProcessSubThread::CleanUp();
401}
402
403void IOThread::CleanUpAfterMessageLoopDestruction() {
404 // TODO(eroman): get rid of this special case for 39723. If we could instead
[email protected]0ee7a3b2010-11-09 06:13:40405 // have a method that runs after the message loop destruction observers have
[email protected]2a92cd92010-04-27 00:01:41406 // run, but before the message loop itself is destroyed, we could safely
407 // combine the two cleanups.
408 deferred_net_log_to_delete_.reset();
[email protected]0ee7a3b2010-11-09 06:13:40409
410 // This will delete the |notification_service_|. Make sure it's done after
411 // anything else can reference it.
[email protected]9aa33e82010-04-15 00:15:39412 BrowserProcessSubThread::CleanUpAfterMessageLoopDestruction();
[email protected]4411da942010-10-25 15:06:02413
414 // URLRequest instances must NOT outlive the IO thread.
415 //
416 // To allow for URLRequests to be deleted from
417 // MessageLoop::DestructionObserver this check has to happen after CleanUp
418 // (which runs before DestructionObservers).
[email protected]58580352010-10-26 04:07:50419 base::debug::LeakTracker<URLRequest>::CheckForLeaks();
[email protected]0ac83682010-01-22 17:46:27420}
421
[email protected]bcefe0f2010-11-10 16:19:10422// static
423void IOThread::RegisterPrefs(PrefService* local_state) {
424 local_state->RegisterStringPref(prefs::kAuthSchemes,
425 "basic,digest,ntlm,negotiate");
426 local_state->RegisterBooleanPref(prefs::kDisableAuthNegotiateCnameLookup,
427 false);
428 local_state->RegisterBooleanPref(prefs::kEnableAuthNegotiatePort, false);
429 local_state->RegisterStringPref(prefs::kAuthServerWhitelist, "");
430 local_state->RegisterStringPref(prefs::kAuthNegotiateDelegateWhitelist, "");
431}
432
[email protected]65d34382010-07-01 18:12:26433net::HttpAuthHandlerFactory* IOThread::CreateDefaultAuthHandlerFactory(
434 net::HostResolver* resolver) {
[email protected]eb3cac72010-02-26 21:07:45435
[email protected]bcefe0f2010-11-10 16:19:10436 net::HttpAuthFilterWhitelist* auth_filter_default_credentials =
437 new net::HttpAuthFilterWhitelist(auth_server_whitelist_);
438 net::HttpAuthFilterWhitelist* auth_filter_delegate =
439 new net::HttpAuthFilterWhitelist(auth_delegate_whitelist_);
[email protected]b4955e7d2010-04-16 20:22:30440 globals_->url_security_manager.reset(
[email protected]d201b200e2010-08-27 17:35:02441 net::URLSecurityManager::Create(auth_filter_default_credentials,
442 auth_filter_delegate));
[email protected]b7304162010-08-23 17:42:29443 std::vector<std::string> supported_schemes;
[email protected]bcefe0f2010-11-10 16:19:10444 base::SplitString(auth_schemes_, ',', &supported_schemes);
[email protected]b7304162010-08-23 17:42:29445
446 return net::HttpAuthHandlerRegistryFactory::Create(
447 supported_schemes,
448 globals_->url_security_manager.get(),
449 resolver,
[email protected]bcefe0f2010-11-10 16:19:10450 negotiate_disable_cname_lookup_,
451 negotiate_enable_port_);
[email protected]eb3cac72010-02-26 21:07:45452}
453
[email protected]74be069e82010-06-25 00:12:49454void IOThread::InitNetworkPredictorOnIOThread(
[email protected]0ac83682010-01-22 17:46:27455 bool prefetching_enabled,
[email protected]74be069e82010-06-25 00:12:49456 base::TimeDelta max_dns_queue_delay,
[email protected]755a93352010-10-29 06:33:59457 size_t max_speculative_parallel_resolves,
[email protected]c5629c32010-06-23 01:22:43458 const chrome_common_net::UrlList& startup_urls,
[email protected]760d970a2010-05-18 00:39:18459 ListValue* referral_list,
460 bool preconnect_enabled) {
[email protected]f8b3ef82010-10-11 02:45:52461 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]74be069e82010-06-25 00:12:49462 CHECK(!predictor_);
[email protected]0ac83682010-01-22 17:46:27463
[email protected]74be069e82010-06-25 00:12:49464 chrome_browser_net::EnablePredictor(prefetching_enabled);
[email protected]0ac83682010-01-22 17:46:27465
[email protected]74be069e82010-06-25 00:12:49466 predictor_ = new chrome_browser_net::Predictor(
[email protected]73c45322010-10-01 23:57:54467 globals_->host_resolver.get(),
[email protected]74be069e82010-06-25 00:12:49468 max_dns_queue_delay,
[email protected]755a93352010-10-29 06:33:59469 max_speculative_parallel_resolves,
[email protected]760d970a2010-05-18 00:39:18470 preconnect_enabled);
[email protected]74be069e82010-06-25 00:12:49471 predictor_->AddRef();
[email protected]0ac83682010-01-22 17:46:27472
[email protected]f4ef861ba2010-07-28 22:37:23473 // Speculative_interceptor_ is used to predict subresource usage.
474 DCHECK(!speculative_interceptor_);
475 speculative_interceptor_ = new chrome_browser_net::ConnectInterceptor;
476
[email protected]bff1f512010-08-15 15:13:49477 FinalizePredictorInitialization(predictor_, startup_urls, referral_list);
[email protected]0ac83682010-01-22 17:46:27478}
479
480void IOThread::ChangedToOnTheRecordOnIOThread() {
[email protected]f8b3ef82010-10-11 02:45:52481 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]0ac83682010-01-22 17:46:27482
[email protected]74be069e82010-06-25 00:12:49483 if (predictor_) {
[email protected]0ac83682010-01-22 17:46:27484 // Destroy all evidence of our OTR session.
[email protected]74be069e82010-06-25 00:12:49485 predictor_->Predictor::DiscardAllResults();
[email protected]0ac83682010-01-22 17:46:27486 }
487
488 // Clear the host cache to avoid showing entries from the OTR session
489 // in about:net-internals.
[email protected]970210c2010-02-19 20:27:02490 if (globals_->host_resolver->GetAsHostResolverImpl()) {
491 net::HostCache* host_cache =
492 globals_->host_resolver.get()->GetAsHostResolverImpl()->cache();
[email protected]f2d8c4212010-02-02 00:56:35493 if (host_cache)
494 host_cache->clear();
495 }
[email protected]9e743cd2010-03-16 07:03:53496 // Clear all of the passively logged data.
497 // TODO(eroman): this is a bit heavy handed, really all we need to do is
498 // clear the data pertaining to off the record context.
499 globals_->net_log->passive_collector()->Clear();
[email protected]0ac83682010-01-22 17:46:27500}