blob: 7663c8a7418b60268085214e8950c1d9059049ff [file] [log] [blame]
[email protected]d24fc3a02012-02-11 02:08:341// Copyright (c) 2012 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]21ee224e2011-11-21 02:17:539#include "base/bind.h"
10#include "base/bind_helpers.h"
[email protected]aa84a7e2012-03-15 21:29:0611#include "base/command_line.h"
[email protected]c93123fa2012-04-19 02:49:4812#include "base/compiler_specific.h"
[email protected]58580352010-10-26 04:07:5013#include "base/debug/leak_tracker.h"
[email protected]0ac83682010-01-22 17:46:2714#include "base/logging.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]5bab49ec2012-05-04 21:13:1920#include "base/threading/worker_pool.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]5a38dfd2012-07-23 23:22:1023#include "chrome/browser/extensions/event_router_forwarder.h"
[email protected]9e743cd2010-03-16 07:03:5324#include "chrome/browser/net/chrome_net_log.h"
[email protected]c38831a12011-10-28 12:44:4925#include "chrome/browser/net/chrome_network_delegate.h"
[email protected]0ee7a3b2010-11-09 06:13:4026#include "chrome/browser/net/chrome_url_request_context.h"
[email protected]1889dc1b2010-10-14 22:03:1327#include "chrome/browser/net/connect_interceptor.h"
[email protected]7613faae2012-04-18 01:01:1928#include "chrome/browser/net/http_pipelining_compatibility_client.h"
[email protected]a9e0d1412012-08-20 22:13:0129#include "chrome/browser/net/load_time_stats.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]c38831a12011-10-28 12:44:4936#include "content/public/browser/browser_thread.h"
[email protected]5d1fa242011-10-18 23:35:3837#include "content/public/common/content_client.h"
[email protected]822581d2010-12-16 17:27:1538#include "net/base/cert_verifier.h"
[email protected]32cb7fb2012-03-22 22:41:1139#include "net/base/default_server_bound_cert_store.h"
[email protected]0ac83682010-01-22 17:46:2740#include "net/base/host_cache.h"
41#include "net/base/host_resolver.h"
[email protected]86933612010-10-16 23:10:3342#include "net/base/mapped_host_resolver.h"
[email protected]32eaa332010-02-08 22:15:5443#include "net/base/net_util.h"
[email protected]3b543ab2011-09-17 21:47:0044#include "net/base/sdch_manager.h"
[email protected]32cb7fb2012-03-22 22:41:1145#include "net/base/server_bound_cert_service.h"
[email protected]aa84a7e2012-03-15 21:29:0646#include "net/cookies/cookie_monster.h"
[email protected]933bc5c62011-04-12 19:08:0247#include "net/ftp/ftp_network_layer.h"
[email protected]eb3cac72010-02-26 21:07:4548#include "net/http/http_auth_filter.h"
[email protected]fa55e192010-02-15 14:25:5049#include "net/http/http_auth_handler_factory.h"
[email protected]2fb629202010-12-23 23:52:5750#include "net/http/http_network_layer.h"
[email protected]57cb0f72011-01-28 06:33:5851#include "net/http/http_network_session.h"
[email protected]17291a022011-10-10 07:32:5352#include "net/http/http_server_properties_impl.h"
[email protected]6104ea5d2011-04-27 21:37:1253#include "net/proxy/proxy_config_service.h"
[email protected]86933612010-10-16 23:10:3354#include "net/proxy/proxy_script_fetcher_impl.h"
[email protected]6104ea5d2011-04-27 21:37:1255#include "net/proxy/proxy_service.h"
[email protected]3dc1bc42012-06-19 08:20:5356#include "net/url_request/url_fetcher.h"
[email protected]a73a2802012-05-02 19:20:1557#include "net/url_request/url_request_throttler_manager.h"
[email protected]0ac83682010-01-22 17:46:2758
[email protected]77feb462011-05-16 23:37:2559#if defined(USE_NSS)
60#include "net/ocsp/nss_ocsp.h"
61#endif // defined(USE_NSS)
62
[email protected]6f96cbcb2011-11-04 02:26:0763#if defined(OS_CHROMEOS)
64#include "chrome/browser/chromeos/proxy_config_service_impl.h"
65#endif // defined(OS_CHROMEOS)
66
[email protected]631bb742011-11-02 11:29:3967using content::BrowserThread;
68
[email protected]075c0322012-02-14 00:56:4469class SafeBrowsingURLRequestContext;
70
[email protected]21ee224e2011-11-21 02:17:5371// The IOThread object must outlive any tasks posted to the IO thread before the
72// Quit task, so base::Bind() calls are not refcounted.
73
[email protected]0ac83682010-01-22 17:46:2774namespace {
75
[email protected]bd0875e2011-03-25 05:13:3576// Custom URLRequestContext used by requests which aren't associated with a
77// particular profile. We need to use a subclass of URLRequestContext in order
78// to provide the correct User-Agent.
79class URLRequestContextWithUserAgent : public net::URLRequestContext {
80 public:
81 virtual const std::string& GetUserAgent(
82 const GURL& url) const OVERRIDE {
[email protected]b75520232011-10-12 23:45:2583 return content::GetUserAgent(url);
[email protected]bd0875e2011-03-25 05:13:3584 }
[email protected]649d1c02012-04-27 02:56:2185
86 protected:
87 virtual ~URLRequestContextWithUserAgent() {}
[email protected]bd0875e2011-03-25 05:13:3588};
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)
[email protected]8c434cbc2012-03-14 14:25:0997 net::SetURLRequestContextForNSSHttpIO(this);
[email protected]77feb462011-05-16 23:37:2598#endif // defined(USE_NSS)
99 }
100
101 private:
102 virtual ~SystemURLRequestContext() {
103#if defined(USE_NSS)
[email protected]8c434cbc2012-03-14 14:25:09104 net::SetURLRequestContextForNSSHttpIO(NULL);
[email protected]77feb462011-05-16 23:37:25105#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 }
126 }
127
[email protected]06ef6d92011-05-19 04:24:58128 size_t retry_attempts = net::HostResolver::kDefaultRetryAttempts;
129
130 // Use the retry attempts override from the command-line, if any.
131 if (command_line.HasSwitch(switches::kHostResolverRetryAttempts)) {
132 std::string s =
133 command_line.GetSwitchValueASCII(switches::kHostResolverRetryAttempts);
134 // Parse the switch (it should be a non-negative integer).
135 int n;
136 if (base::StringToInt(s, &n) && n >= 0) {
137 retry_attempts = static_cast<size_t>(n);
138 } else {
139 LOG(ERROR) << "Invalid switch for host resolver retry attempts: " << s;
140 }
141 }
142
[email protected]d987cca2011-07-21 12:54:37143 net::HostResolver* global_host_resolver = NULL;
[email protected]b3601bc22012-02-21 21:23:20144 if (command_line.HasSwitch(switches::kEnableAsyncDns)) {
145 global_host_resolver =
146 net::CreateAsyncHostResolver(parallelism, retry_attempts, net_log);
[email protected]d987cca2011-07-21 12:54:37147 }
148
149 if (!global_host_resolver) {
150 global_host_resolver =
[email protected]06ef6d92011-05-19 04:24:58151 net::CreateSystemHostResolver(parallelism, retry_attempts, net_log);
[email protected]d987cca2011-07-21 12:54:37152 }
[email protected]9087aa32010-02-18 08:03:38153
[email protected]0f8f1b432010-03-16 19:06:03154 // Determine if we should disable IPv6 support.
[email protected]9087aa32010-02-18 08:03:38155 if (!command_line.HasSwitch(switches::kEnableIPv6)) {
[email protected]0f8f1b432010-03-16 19:06:03156 if (command_line.HasSwitch(switches::kDisableIPv6)) {
[email protected]46f6e202010-02-26 06:07:25157 global_host_resolver->SetDefaultAddressFamily(net::ADDRESS_FAMILY_IPV4);
[email protected]0f8f1b432010-03-16 19:06:03158 } else {
[email protected]a78f4272011-10-21 19:16:33159 global_host_resolver->ProbeIPv6Support();
[email protected]0f8f1b432010-03-16 19:06:03160 }
[email protected]9087aa32010-02-18 08:03:38161 }
162
[email protected]9087aa32010-02-18 08:03:38163 // If hostname remappings were specified on the command-line, layer these
164 // rules on top of the real host resolver. This allows forwarding all requests
165 // through a designated test server.
[email protected]0f8f1b432010-03-16 19:06:03166 if (!command_line.HasSwitch(switches::kHostResolverRules))
167 return global_host_resolver;
[email protected]0ac83682010-01-22 17:46:27168
[email protected]0f8f1b432010-03-16 19:06:03169 net::MappedHostResolver* remapped_resolver =
170 new net::MappedHostResolver(global_host_resolver);
171 remapped_resolver->SetRulesFromString(
172 command_line.GetSwitchValueASCII(switches::kHostResolverRules));
173 return remapped_resolver;
[email protected]0ac83682010-01-22 17:46:27174}
175
[email protected]ef2bf422012-05-11 03:27:09176// TODO(willchan): Remove proxy script fetcher context since it's not necessary
177// now that I got rid of refcounting URLRequestContexts.
[email protected]77feb462011-05-16 23:37:25178// See IOThread::Globals for details.
[email protected]ef2bf422012-05-11 03:27:09179net::URLRequestContext*
[email protected]2fb629202010-12-23 23:52:57180ConstructProxyScriptFetcherContext(IOThread::Globals* globals,
181 net::NetLog* net_log) {
[email protected]ef2bf422012-05-11 03:27:09182 net::URLRequestContext* context = new URLRequestContextWithUserAgent;
[email protected]2fb629202010-12-23 23:52:57183 context->set_net_log(net_log);
184 context->set_host_resolver(globals->host_resolver.get());
185 context->set_cert_verifier(globals->cert_verifier.get());
[email protected]a2a41972011-12-07 17:47:27186 context->set_transport_security_state(
187 globals->transport_security_state.get());
[email protected]2fb629202010-12-23 23:52:57188 context->set_http_auth_handler_factory(
189 globals->http_auth_handler_factory.get());
190 context->set_proxy_service(globals->proxy_script_fetcher_proxy_service.get());
191 context->set_http_transaction_factory(
[email protected]52617df2010-12-24 07:30:01192 globals->proxy_script_fetcher_http_transaction_factory.get());
[email protected]933bc5c62011-04-12 19:08:02193 context->set_ftp_transaction_factory(
194 globals->proxy_script_fetcher_ftp_transaction_factory.get());
[email protected]273e37d2011-08-11 01:49:12195 context->set_cookie_store(globals->system_cookie_store.get());
[email protected]9c4eff22012-03-20 22:42:29196 context->set_server_bound_cert_service(
197 globals->system_server_bound_cert_service.get());
[email protected]3ce02412011-03-01 12:01:15198 context->set_network_delegate(globals->system_network_delegate.get());
[email protected]db96a882011-10-09 02:01:54199 // TODO(rtenneti): We should probably use HttpServerPropertiesManager for the
200 // system URLRequestContext too. There's no reason this should be tied to a
201 // profile.
[email protected]2fb629202010-12-23 23:52:57202 return context;
203}
204
[email protected]ef2bf422012-05-11 03:27:09205net::URLRequestContext*
[email protected]db0e86dd2011-03-16 14:47:21206ConstructSystemRequestContext(IOThread::Globals* globals,
207 net::NetLog* net_log) {
[email protected]ef2bf422012-05-11 03:27:09208 net::URLRequestContext* context = new SystemURLRequestContext;
[email protected]db0e86dd2011-03-16 14:47:21209 context->set_net_log(net_log);
210 context->set_host_resolver(globals->host_resolver.get());
211 context->set_cert_verifier(globals->cert_verifier.get());
[email protected]a2a41972011-12-07 17:47:27212 context->set_transport_security_state(
213 globals->transport_security_state.get());
[email protected]db0e86dd2011-03-16 14:47:21214 context->set_http_auth_handler_factory(
215 globals->http_auth_handler_factory.get());
216 context->set_proxy_service(globals->system_proxy_service.get());
217 context->set_http_transaction_factory(
218 globals->system_http_transaction_factory.get());
[email protected]933bc5c62011-04-12 19:08:02219 context->set_ftp_transaction_factory(
220 globals->system_ftp_transaction_factory.get());
[email protected]273e37d2011-08-11 01:49:12221 context->set_cookie_store(globals->system_cookie_store.get());
[email protected]9c4eff22012-03-20 22:42:29222 context->set_server_bound_cert_service(
223 globals->system_server_bound_cert_service.get());
[email protected]a73a2802012-05-02 19:20:15224 context->set_throttler_manager(globals->throttler_manager.get());
[email protected]815c69cf2012-06-30 00:52:08225 context->set_network_delegate(globals->system_network_delegate.get());
[email protected]db0e86dd2011-03-16 14:47:21226 return context;
227}
228
[email protected]0ac83682010-01-22 17:46:27229} // namespace
230
[email protected]e0845d5f2012-05-29 00:11:41231class IOThread::LoggingNetworkChangeObserver
232 : public net::NetworkChangeNotifier::IPAddressObserver {
233 public:
234 // |net_log| must remain valid throughout our lifetime.
235 explicit LoggingNetworkChangeObserver(net::NetLog* net_log)
236 : net_log_(net_log) {
237 net::NetworkChangeNotifier::AddIPAddressObserver(this);
238 }
239
240 ~LoggingNetworkChangeObserver() {
241 net::NetworkChangeNotifier::RemoveIPAddressObserver(this);
242 }
243
244 virtual void OnIPAddressChanged() {
245 VLOG(1) << "Observed a change to the network IP addresses";
246
[email protected]2fa08912012-06-14 20:56:26247 net_log_->AddGlobalEntry(net::NetLog::TYPE_NETWORK_IP_ADDRESSES_CHANGED);
[email protected]e0845d5f2012-05-29 00:11:41248 }
249
250 private:
251 net::NetLog* net_log_;
252 DISALLOW_COPY_AND_ASSIGN(LoggingNetworkChangeObserver);
253};
254
[email protected]abe2c032011-03-31 18:49:34255class SystemURLRequestContextGetter : public net::URLRequestContextGetter {
[email protected]db0e86dd2011-03-16 14:47:21256 public:
257 explicit SystemURLRequestContextGetter(IOThread* io_thread);
[email protected]db0e86dd2011-03-16 14:47:21258
[email protected]abe2c032011-03-31 18:49:34259 // Implementation for net::UrlRequestContextGetter.
[email protected]4969b0122012-06-16 01:58:28260 virtual net::URLRequestContext* GetURLRequestContext() OVERRIDE;
261 virtual scoped_refptr<base::SingleThreadTaskRunner>
262 GetNetworkTaskRunner() const OVERRIDE;
[email protected]db0e86dd2011-03-16 14:47:21263
[email protected]13ed17f82012-04-06 02:27:18264 protected:
265 virtual ~SystemURLRequestContextGetter();
266
[email protected]db0e86dd2011-03-16 14:47:21267 private:
268 IOThread* const io_thread_; // Weak pointer, owned by BrowserProcess.
[email protected]4969b0122012-06-16 01:58:28269 scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_;
[email protected]db0e86dd2011-03-16 14:47:21270
271 base::debug::LeakTracker<SystemURLRequestContextGetter> leak_tracker_;
272};
273
274SystemURLRequestContextGetter::SystemURLRequestContextGetter(
275 IOThread* io_thread)
276 : io_thread_(io_thread),
[email protected]4969b0122012-06-16 01:58:28277 network_task_runner_(
[email protected]2e5b60a22011-11-28 15:56:41278 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)) {
[email protected]db0e86dd2011-03-16 14:47:21279}
280
281SystemURLRequestContextGetter::~SystemURLRequestContextGetter() {}
282
283net::URLRequestContext* SystemURLRequestContextGetter::GetURLRequestContext() {
284 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]ef2bf422012-05-11 03:27:09285 DCHECK(io_thread_->globals()->system_request_context.get());
[email protected]db0e86dd2011-03-16 14:47:21286
[email protected]ef2bf422012-05-11 03:27:09287 return io_thread_->globals()->system_request_context.get();
[email protected]db0e86dd2011-03-16 14:47:21288}
289
[email protected]4969b0122012-06-16 01:58:28290scoped_refptr<base::SingleThreadTaskRunner>
291SystemURLRequestContextGetter::GetNetworkTaskRunner() const {
292 return network_task_runner_;
[email protected]db0e86dd2011-03-16 14:47:21293}
294
[email protected]c93123fa2012-04-19 02:49:48295IOThread::Globals::
296SystemRequestContextLeakChecker::SystemRequestContextLeakChecker(
297 Globals* globals)
298 : globals_(globals) {
299 DCHECK(globals_);
[email protected]7613faae2012-04-18 01:01:19300}
[email protected]1889dc1b2010-10-14 22:03:13301
[email protected]c93123fa2012-04-19 02:49:48302IOThread::Globals::
303SystemRequestContextLeakChecker::~SystemRequestContextLeakChecker() {
304 if (globals_->system_request_context.get())
305 globals_->system_request_context->AssertNoURLRequests();
306}
307
308IOThread::Globals::Globals()
309 : ALLOW_THIS_IN_INITIALIZER_LIST(
310 system_request_context_leak_checker(this)) {}
311IOThread::Globals::~Globals() {}
312
[email protected]bcefe0f2010-11-10 16:19:10313// |local_state| is passed in explicitly in order to (1) reduce implicit
314// dependencies and (2) make IOThread more flexible for testing.
[email protected]3ce02412011-03-01 12:01:15315IOThread::IOThread(
316 PrefService* local_state,
317 ChromeNetLog* net_log,
[email protected]5a38dfd2012-07-23 23:22:10318 extensions::EventRouterForwarder* extension_event_router_forwarder)
[email protected]2e5b60a22011-11-28 15:56:41319 : net_log_(net_log),
[email protected]3ce02412011-03-01 12:01:15320 extension_event_router_forwarder_(extension_event_router_forwarder),
[email protected]d13c3272010-02-04 00:24:51321 globals_(NULL),
[email protected]4a109492011-09-24 21:00:12322 sdch_manager_(NULL),
[email protected]21ee224e2011-11-21 02:17:53323 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
[email protected]bcefe0f2010-11-10 16:19:10324 // We call RegisterPrefs() here (instead of inside browser_prefs.cc) to make
325 // sure that everything is initialized in the right order.
326 RegisterPrefs(local_state);
327 auth_schemes_ = local_state->GetString(prefs::kAuthSchemes);
328 negotiate_disable_cname_lookup_ = local_state->GetBoolean(
329 prefs::kDisableAuthNegotiateCnameLookup);
330 negotiate_enable_port_ = local_state->GetBoolean(
331 prefs::kEnableAuthNegotiatePort);
332 auth_server_whitelist_ = local_state->GetString(prefs::kAuthServerWhitelist);
333 auth_delegate_whitelist_ = local_state->GetString(
334 prefs::kAuthNegotiateDelegateWhitelist);
[email protected]ac7f3fdb2010-11-12 12:47:05335 gssapi_library_name_ = local_state->GetString(prefs::kGSSAPILibraryName);
[email protected]6f96cbcb2011-11-04 02:26:07336 pref_proxy_config_tracker_.reset(
337 ProxyServiceFactory::CreatePrefProxyConfigTracker(local_state));
[email protected]0a8db0d2011-04-13 15:15:40338 ChromeNetworkDelegate::InitializeReferrersEnabled(&system_enable_referrers_,
339 local_state);
[email protected]4d45a6de2011-05-13 05:20:18340 ssl_config_service_manager_.reset(
341 SSLConfigServiceManager::CreateDefaultManager(local_state));
[email protected]2e5b60a22011-11-28 15:56:41342
343 BrowserThread::SetDelegate(BrowserThread::IO, this);
[email protected]bcefe0f2010-11-10 16:19:10344}
[email protected]0ac83682010-01-22 17:46:27345
346IOThread::~IOThread() {
[email protected]2e5b60a22011-11-28 15:56:41347 // This isn't needed for production code, but in tests, IOThread may
348 // be multiply constructed.
349 BrowserThread::SetDelegate(BrowserThread::IO, NULL);
350
[email protected]6f96cbcb2011-11-04 02:26:07351 if (pref_proxy_config_tracker_.get())
[email protected]db0e86dd2011-03-16 14:47:21352 pref_proxy_config_tracker_->DetachFromPrefService();
[email protected]d13c3272010-02-04 00:24:51353 DCHECK(!globals_);
[email protected]0ac83682010-01-22 17:46:27354}
355
[email protected]d13c3272010-02-04 00:24:51356IOThread::Globals* IOThread::globals() {
[email protected]f8b3ef82010-10-11 02:45:52357 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]d13c3272010-02-04 00:24:51358 return globals_;
[email protected]0ac83682010-01-22 17:46:27359}
360
[email protected]b2fcd0e2010-12-01 15:19:40361ChromeNetLog* IOThread::net_log() {
362 return net_log_;
363}
364
[email protected]b09f76d62011-12-07 01:51:06365void IOThread::ChangedToOnTheRecord() {
366 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
367 BrowserThread::PostTask(
368 BrowserThread::IO,
369 FROM_HERE,
370 base::Bind(&IOThread::ChangedToOnTheRecordOnIOThread,
371 base::Unretained(this)));
372}
373
[email protected]abe2c032011-03-31 18:49:34374net::URLRequestContextGetter* IOThread::system_url_request_context_getter() {
[email protected]db0e86dd2011-03-16 14:47:21375 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
376 if (!system_url_request_context_getter_) {
[email protected]addb3242011-06-13 21:39:16377 InitSystemRequestContext();
[email protected]db0e86dd2011-03-16 14:47:21378 }
379 return system_url_request_context_getter_;
380}
381
[email protected]0ac83682010-01-22 17:46:27382void IOThread::Init() {
[email protected]2e5b60a22011-11-28 15:56:41383 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]70b92342010-10-12 05:54:06384
385#if defined(USE_NSS)
[email protected]8c434cbc2012-03-14 14:25:09386 net::SetMessageLoopForNSSHttpIO();
[email protected]ecd95ae2010-10-20 23:58:17387#endif // defined(USE_NSS)
[email protected]70b92342010-10-12 05:54:06388
[email protected]d13c3272010-02-04 00:24:51389 DCHECK(!globals_);
390 globals_ = new Globals;
391
[email protected]58bc7042010-07-07 18:04:14392 // Add an observer that will emit network change events to the ChromeNetLog.
393 // Assuming NetworkChangeNotifier dispatches in FIFO order, we should be
394 // logging the network change before other IO thread consumers respond to it.
395 network_change_observer_.reset(
[email protected]b2fcd0e2010-12-01 15:19:40396 new LoggingNetworkChangeObserver(net_log_));
[email protected]58bc7042010-07-07 18:04:14397
[email protected]cde8b3c2012-08-13 19:20:52398 // Setup the HistogramWatcher to run on the IO thread.
399 net::NetworkChangeNotifier::InitHistogramWatcher();
400
[email protected]3ce02412011-03-01 12:01:15401 globals_->extension_event_router_forwarder =
402 extension_event_router_forwarder_;
[email protected]a1d4ab072012-06-07 13:21:15403 ChromeNetworkDelegate* network_delegate = new ChromeNetworkDelegate(
[email protected]0a8db0d2011-04-13 15:15:40404 extension_event_router_forwarder_,
[email protected]c357acb42011-06-09 20:52:42405 NULL,
[email protected]673514522011-07-13 18:17:18406 NULL,
[email protected]6a5f77c32011-09-04 19:19:59407 NULL,
[email protected]9c8ae8c2012-03-09 13:13:35408 NULL,
[email protected]e9c41d22012-08-17 00:08:15409 NULL,
[email protected]5a07c192012-07-30 20:18:22410 &system_enable_referrers_,
411 NULL);
[email protected]a1d4ab072012-06-07 13:21:15412 if (CommandLine::ForCurrentProcess()->HasSwitch(
413 switches::kDisableExtensionsHttpThrottling)) {
414 network_delegate->NeverThrottleRequests();
415 }
416 globals_->system_network_delegate.reset(network_delegate);
[email protected]73c45322010-10-01 23:57:54417 globals_->host_resolver.reset(
[email protected]b2fcd0e2010-12-01 15:19:40418 CreateGlobalHostResolver(net_log_));
[email protected]9f59fac2012-03-21 23:18:11419 globals_->cert_verifier.reset(net::CertVerifier::CreateDefault());
[email protected]f43b89f32012-05-01 19:39:48420 globals_->transport_security_state.reset(new net::TransportSecurityState());
[email protected]4d45a6de2011-05-13 05:20:18421 globals_->ssl_config_service = GetSSLConfigService();
[email protected]65d34382010-07-01 18:12:26422 globals_->http_auth_handler_factory.reset(CreateDefaultAuthHandlerFactory(
[email protected]73c45322010-10-01 23:57:54423 globals_->host_resolver.get()));
[email protected]17291a022011-10-10 07:32:53424 globals_->http_server_properties.reset(new net::HttpServerPropertiesImpl);
[email protected]2fb629202010-12-23 23:52:57425 // For the ProxyScriptFetcher, we use a direct ProxyService.
[email protected]6104ea5d2011-04-27 21:37:12426 globals_->proxy_script_fetcher_proxy_service.reset(
427 net::ProxyService::CreateDirectWithNetLog(net_log_));
[email protected]273e37d2011-08-11 01:49:12428 // In-memory cookie store.
429 globals_->system_cookie_store = new net::CookieMonster(NULL, NULL);
[email protected]9c4eff22012-03-20 22:42:29430 // In-memory server bound cert store.
431 globals_->system_server_bound_cert_service.reset(
432 new net::ServerBoundCertService(
[email protected]5bab49ec2012-05-04 21:13:19433 new net::DefaultServerBoundCertStore(NULL),
434 base::WorkerPool::GetTaskRunner(true)));
[email protected]a9e0d1412012-08-20 22:13:01435 globals_->load_time_stats.reset(new chrome_browser_net::LoadTimeStats());
[email protected]9e1bdd32011-02-03 21:48:34436 net::HttpNetworkSession::Params session_params;
437 session_params.host_resolver = globals_->host_resolver.get();
438 session_params.cert_verifier = globals_->cert_verifier.get();
[email protected]9c4eff22012-03-20 22:42:29439 session_params.server_bound_cert_service =
440 globals_->system_server_bound_cert_service.get();
[email protected]a2a41972011-12-07 17:47:27441 session_params.transport_security_state =
442 globals_->transport_security_state.get();
[email protected]9e1bdd32011-02-03 21:48:34443 session_params.proxy_service =
444 globals_->proxy_script_fetcher_proxy_service.get();
445 session_params.http_auth_handler_factory =
446 globals_->http_auth_handler_factory.get();
[email protected]0651b812011-02-24 00:22:50447 session_params.network_delegate = globals_->system_network_delegate.get();
[email protected]db96a882011-10-09 02:01:54448 // TODO(rtenneti): We should probably use HttpServerPropertiesManager for the
449 // system URLRequestContext too. There's no reason this should be tied to a
450 // profile.
[email protected]17291a022011-10-10 07:32:53451 session_params.http_server_properties =
452 globals_->http_server_properties.get();
[email protected]9e1bdd32011-02-03 21:48:34453 session_params.net_log = net_log_;
454 session_params.ssl_config_service = globals_->ssl_config_service;
[email protected]57cb0f72011-01-28 06:33:58455 scoped_refptr<net::HttpNetworkSession> network_session(
[email protected]9e1bdd32011-02-03 21:48:34456 new net::HttpNetworkSession(session_params));
[email protected]57cb0f72011-01-28 06:33:58457 globals_->proxy_script_fetcher_http_transaction_factory.reset(
458 new net::HttpNetworkLayer(network_session));
[email protected]933bc5c62011-04-12 19:08:02459 globals_->proxy_script_fetcher_ftp_transaction_factory.reset(
460 new net::FtpNetworkLayer(globals_->host_resolver.get()));
[email protected]2fb629202010-12-23 23:52:57461
[email protected]a73a2802012-05-02 19:20:15462 globals_->throttler_manager.reset(new net::URLRequestThrottlerManager());
[email protected]a1d4ab072012-06-07 13:21:15463 globals_->throttler_manager->set_net_log(net_log_);
[email protected]a73a2802012-05-02 19:20:15464 // Always done in production, disabled only for unit tests.
465 globals_->throttler_manager->set_enable_thread_checks(true);
[email protected]a73a2802012-05-02 19:20:15466
[email protected]ef2bf422012-05-11 03:27:09467 globals_->proxy_script_fetcher_context.reset(
468 ConstructProxyScriptFetcherContext(globals_, net_log_));
[email protected]4a109492011-09-24 21:00:12469
470 sdch_manager_ = new net::SdchManager();
[email protected]2e5b60a22011-11-28 15:56:41471
472 // InitSystemRequestContext turns right around and posts a task back
473 // to the IO thread, so we can't let it run until we know the IO
474 // thread has started.
475 //
476 // Note that since we are at BrowserThread::Init time, the UI thread
477 // is blocked waiting for the thread to start. Therefore, posting
478 // this task to the main thread's message loop here is guaranteed to
479 // get it onto the message loop while the IOThread object still
480 // exists. However, the message might not be processed on the UI
481 // thread until after IOThread is gone, so use a weak pointer.
482 BrowserThread::PostTask(BrowserThread::UI,
483 FROM_HERE,
484 base::Bind(&IOThread::InitSystemRequestContext,
485 weak_factory_.GetWeakPtr()));
486
487 // We constructed the weak pointer on the IO thread but it will be
488 // used on the UI thread. Call this to avoid a thread checker
489 // error.
490 weak_factory_.DetachFromThread();
[email protected]0ac83682010-01-22 17:46:27491}
492
[email protected]2a92cd92010-04-27 00:01:41493void IOThread::CleanUp() {
[email protected]075c0322012-02-14 00:56:44494 base::debug::LeakTracker<SafeBrowsingURLRequestContext>::CheckForLeaks();
495
[email protected]4a109492011-09-24 21:00:12496 delete sdch_manager_;
497 sdch_manager_ = NULL;
498
[email protected]59a3b362010-10-21 21:52:41499#if defined(USE_NSS)
[email protected]8c434cbc2012-03-14 14:25:09500 net::ShutdownNSSHttpIO();
[email protected]59a3b362010-10-21 21:52:41501#endif // defined(USE_NSS)
502
[email protected]db0e86dd2011-03-16 14:47:21503 system_url_request_context_getter_ = NULL;
504
[email protected]af669932012-01-17 19:26:58505 // Release objects that the net::URLRequestContext could have been pointing
506 // to.
[email protected]0ee7a3b2010-11-09 06:13:40507
508 // This must be reset before the ChromeNetLog is destroyed.
509 network_change_observer_.reset();
510
[email protected]db0e86dd2011-03-16 14:47:21511 system_proxy_config_service_.reset();
512
[email protected]d13c3272010-02-04 00:24:51513 delete globals_;
514 globals_ = NULL;
[email protected]0ac83682010-01-22 17:46:27515
[email protected]db0e86dd2011-03-16 14:47:21516 base::debug::LeakTracker<SystemURLRequestContextGetter>::CheckForLeaks();
[email protected]0ac83682010-01-22 17:46:27517}
518
[email protected]bcefe0f2010-11-10 16:19:10519// static
520void IOThread::RegisterPrefs(PrefService* local_state) {
521 local_state->RegisterStringPref(prefs::kAuthSchemes,
522 "basic,digest,ntlm,negotiate");
523 local_state->RegisterBooleanPref(prefs::kDisableAuthNegotiateCnameLookup,
524 false);
525 local_state->RegisterBooleanPref(prefs::kEnableAuthNegotiatePort, false);
526 local_state->RegisterStringPref(prefs::kAuthServerWhitelist, "");
527 local_state->RegisterStringPref(prefs::kAuthNegotiateDelegateWhitelist, "");
[email protected]ac7f3fdb2010-11-12 12:47:05528 local_state->RegisterStringPref(prefs::kGSSAPILibraryName, "");
[email protected]0a8db0d2011-04-13 15:15:40529 local_state->RegisterBooleanPref(prefs::kEnableReferrers, true);
[email protected]bcefe0f2010-11-10 16:19:10530}
531
[email protected]65d34382010-07-01 18:12:26532net::HttpAuthHandlerFactory* IOThread::CreateDefaultAuthHandlerFactory(
533 net::HostResolver* resolver) {
[email protected]9030a632010-11-19 20:12:09534 net::HttpAuthFilterWhitelist* auth_filter_default_credentials = NULL;
535 if (!auth_server_whitelist_.empty()) {
536 auth_filter_default_credentials =
537 new net::HttpAuthFilterWhitelist(auth_server_whitelist_);
538 }
539 net::HttpAuthFilterWhitelist* auth_filter_delegate = NULL;
540 if (!auth_delegate_whitelist_.empty()) {
541 auth_filter_delegate =
542 new net::HttpAuthFilterWhitelist(auth_delegate_whitelist_);
543 }
[email protected]b4955e7d2010-04-16 20:22:30544 globals_->url_security_manager.reset(
[email protected]d201b200e2010-08-27 17:35:02545 net::URLSecurityManager::Create(auth_filter_default_credentials,
546 auth_filter_delegate));
[email protected]b7304162010-08-23 17:42:29547 std::vector<std::string> supported_schemes;
[email protected]bcefe0f2010-11-10 16:19:10548 base::SplitString(auth_schemes_, ',', &supported_schemes);
[email protected]b7304162010-08-23 17:42:29549
550 return net::HttpAuthHandlerRegistryFactory::Create(
551 supported_schemes,
552 globals_->url_security_manager.get(),
553 resolver,
[email protected]ac7f3fdb2010-11-12 12:47:05554 gssapi_library_name_,
[email protected]bcefe0f2010-11-10 16:19:10555 negotiate_disable_cname_lookup_,
556 negotiate_enable_port_);
[email protected]eb3cac72010-02-26 21:07:45557}
558
[email protected]d6f37fc2011-02-13 23:58:41559void IOThread::ClearHostCache() {
560 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
561
[email protected]489d1a82011-10-12 03:09:11562 net::HostCache* host_cache = globals_->host_resolver->GetHostCache();
563 if (host_cache)
564 host_cache->clear();
[email protected]0ac83682010-01-22 17:46:27565}
[email protected]db0e86dd2011-03-16 14:47:21566
[email protected]4d45a6de2011-05-13 05:20:18567net::SSLConfigService* IOThread::GetSSLConfigService() {
568 return ssl_config_service_manager_->Get();
569}
570
[email protected]b09f76d62011-12-07 01:51:06571void IOThread::ChangedToOnTheRecordOnIOThread() {
572 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
573
574 // Clear the host cache to avoid showing entries from the OTR session
575 // in about:net-internals.
576 ClearHostCache();
[email protected]b09f76d62011-12-07 01:51:06577}
578
[email protected]db0e86dd2011-03-16 14:47:21579void IOThread::InitSystemRequestContext() {
[email protected]addb3242011-06-13 21:39:16580 if (system_url_request_context_getter_)
581 return;
[email protected]63e26822011-07-16 19:07:35582 // If we're in unit_tests, IOThread may not be run.
[email protected]dd483702011-12-02 14:47:42583 if (!BrowserThread::IsMessageLoopValid(BrowserThread::IO))
[email protected]63e26822011-07-16 19:07:35584 return;
[email protected]71fdf772011-12-18 16:28:38585 bool wait_for_first_update = (pref_proxy_config_tracker_.get() != NULL);
[email protected]6f96cbcb2011-11-04 02:26:07586 ChromeProxyConfigService* proxy_config_service =
[email protected]71fdf772011-12-18 16:28:38587 ProxyServiceFactory::CreateProxyConfigService(wait_for_first_update);
[email protected]6f96cbcb2011-11-04 02:26:07588 system_proxy_config_service_.reset(proxy_config_service);
589 if (pref_proxy_config_tracker_.get()) {
590 pref_proxy_config_tracker_->SetChromeProxyConfigService(
591 proxy_config_service);
592 }
[email protected]addb3242011-06-13 21:39:16593 system_url_request_context_getter_ =
594 new SystemURLRequestContextGetter(this);
[email protected]2e5b60a22011-11-28 15:56:41595 // Safe to post an unretained this pointer, since IOThread is
596 // guaranteed to outlive the IO BrowserThread.
[email protected]dd483702011-12-02 14:47:42597 BrowserThread::PostTask(
598 BrowserThread::IO,
599 FROM_HERE,
600 base::Bind(&IOThread::InitSystemRequestContextOnIOThread,
601 base::Unretained(this)));
[email protected]addb3242011-06-13 21:39:16602}
603
604void IOThread::InitSystemRequestContextOnIOThread() {
[email protected]db0e86dd2011-03-16 14:47:21605 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]6104ea5d2011-04-27 21:37:12606 DCHECK(!globals_->system_proxy_service.get());
[email protected]db0e86dd2011-03-16 14:47:21607 DCHECK(system_proxy_config_service_.get());
608
609 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
[email protected]6104ea5d2011-04-27 21:37:12610 globals_->system_proxy_service.reset(
[email protected]db0e86dd2011-03-16 14:47:21611 ProxyServiceFactory::CreateProxyService(
612 net_log_,
[email protected]ef2bf422012-05-11 03:27:09613 globals_->proxy_script_fetcher_context.get(),
[email protected]db0e86dd2011-03-16 14:47:21614 system_proxy_config_service_.release(),
[email protected]6104ea5d2011-04-27 21:37:12615 command_line));
[email protected]db0e86dd2011-03-16 14:47:21616 net::HttpNetworkSession::Params system_params;
617 system_params.host_resolver = globals_->host_resolver.get();
618 system_params.cert_verifier = globals_->cert_verifier.get();
[email protected]9c4eff22012-03-20 22:42:29619 system_params.server_bound_cert_service =
620 globals_->system_server_bound_cert_service.get();
[email protected]a2a41972011-12-07 17:47:27621 system_params.transport_security_state =
622 globals_->transport_security_state.get();
[email protected]db0e86dd2011-03-16 14:47:21623 system_params.proxy_service = globals_->system_proxy_service.get();
624 system_params.ssl_config_service = globals_->ssl_config_service.get();
625 system_params.http_auth_handler_factory =
626 globals_->http_auth_handler_factory.get();
[email protected]17291a022011-10-10 07:32:53627 system_params.http_server_properties = globals_->http_server_properties.get();
[email protected]db0e86dd2011-03-16 14:47:21628 system_params.network_delegate = globals_->system_network_delegate.get();
629 system_params.net_log = net_log_;
630 globals_->system_http_transaction_factory.reset(
631 new net::HttpNetworkLayer(
632 new net::HttpNetworkSession(system_params)));
[email protected]933bc5c62011-04-12 19:08:02633 globals_->system_ftp_transaction_factory.reset(
634 new net::FtpNetworkLayer(globals_->host_resolver.get()));
[email protected]ef2bf422012-05-11 03:27:09635 globals_->system_request_context.reset(
636 ConstructSystemRequestContext(globals_, net_log_));
[email protected]d24fc3a02012-02-11 02:08:34637
638 sdch_manager_->set_sdch_fetcher(
639 new SdchDictionaryFetcher(system_url_request_context_getter_.get()));
[email protected]db0e86dd2011-03-16 14:47:21640}