blob: c55cf8b069f7467f7d160771c0b1b352769c180e [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]026876f32012-08-22 23:53:4024#include "chrome/browser/net/async_dns_field_trial.h"
[email protected]ee4c30d2012-11-07 15:08:4325#include "chrome/browser/net/basic_http_user_agent_settings.h"
[email protected]9e743cd2010-03-16 07:03:5326#include "chrome/browser/net/chrome_net_log.h"
[email protected]c38831a12011-10-28 12:44:4927#include "chrome/browser/net/chrome_network_delegate.h"
[email protected]0ee7a3b2010-11-09 06:13:4028#include "chrome/browser/net/chrome_url_request_context.h"
[email protected]1889dc1b2010-10-14 22:03:1329#include "chrome/browser/net/connect_interceptor.h"
[email protected]4588b3d2012-11-14 00:37:3830#include "chrome/browser/net/dns_probe_service.h"
[email protected]7613faae2012-04-18 01:01:1931#include "chrome/browser/net/http_pipelining_compatibility_client.h"
[email protected]a9e0d1412012-08-20 22:13:0132#include "chrome/browser/net/load_time_stats.h"
[email protected]6f96cbcb2011-11-04 02:26:0733#include "chrome/browser/net/pref_proxy_config_tracker.h"
[email protected]db0e86dd2011-03-16 14:47:2134#include "chrome/browser/net/proxy_service_factory.h"
[email protected]3b543ab2011-09-17 21:47:0035#include "chrome/browser/net/sdch_dictionary_fetcher.h"
[email protected]ec44ee02012-09-28 21:31:5136#include "chrome/browser/net/spdyproxy/http_auth_handler_spdyproxy.h"
[email protected]77305422012-11-29 16:51:3937#include "chrome/browser/policy/policy_service.h"
[email protected]bcefe0f2010-11-10 16:19:1038#include "chrome/browser/prefs/pref_service.h"
[email protected]0ac83682010-01-22 17:46:2739#include "chrome/common/chrome_switches.h"
[email protected]bcefe0f2010-11-10 16:19:1040#include "chrome/common/pref_names.h"
[email protected]c38831a12011-10-28 12:44:4941#include "content/public/browser/browser_thread.h"
[email protected]822581d2010-12-16 17:27:1542#include "net/base/cert_verifier.h"
[email protected]32cb7fb2012-03-22 22:41:1143#include "net/base/default_server_bound_cert_store.h"
[email protected]0ac83682010-01-22 17:46:2744#include "net/base/host_cache.h"
[email protected]c2dad292012-09-07 21:27:3545#include "net/base/host_mapping_rules.h"
[email protected]0ac83682010-01-22 17:46:2746#include "net/base/host_resolver.h"
[email protected]86933612010-10-16 23:10:3347#include "net/base/mapped_host_resolver.h"
[email protected]32eaa332010-02-08 22:15:5448#include "net/base/net_util.h"
[email protected]3b543ab2011-09-17 21:47:0049#include "net/base/sdch_manager.h"
[email protected]32cb7fb2012-03-22 22:41:1150#include "net/base/server_bound_cert_service.h"
[email protected]aa84a7e2012-03-15 21:29:0651#include "net/cookies/cookie_monster.h"
[email protected]933bc5c62011-04-12 19:08:0252#include "net/ftp/ftp_network_layer.h"
[email protected]eb3cac72010-02-26 21:07:4553#include "net/http/http_auth_filter.h"
[email protected]fa55e192010-02-15 14:25:5054#include "net/http/http_auth_handler_factory.h"
[email protected]2fb629202010-12-23 23:52:5755#include "net/http/http_network_layer.h"
[email protected]17291a022011-10-10 07:32:5356#include "net/http/http_server_properties_impl.h"
[email protected]6104ea5d2011-04-27 21:37:1257#include "net/proxy/proxy_config_service.h"
[email protected]86933612010-10-16 23:10:3358#include "net/proxy/proxy_script_fetcher_impl.h"
[email protected]6104ea5d2011-04-27 21:37:1259#include "net/proxy/proxy_service.h"
[email protected]77305422012-11-29 16:51:3960#include "net/spdy/spdy_session.h"
[email protected]3dc1bc42012-06-19 08:20:5361#include "net/url_request/url_fetcher.h"
[email protected]a73a2802012-05-02 19:20:1562#include "net/url_request/url_request_throttler_manager.h"
[email protected]77305422012-11-29 16:51:3963#include "net/websockets/websocket_job.h"
64
65#if defined(ENABLE_CONFIGURATION_POLICY)
66#include "policy/policy_constants.h"
67#endif
[email protected]0ac83682010-01-22 17:46:2768
[email protected]a592c0432012-12-01 18:10:2969#if defined(USE_NSS) || defined(OS_IOS)
[email protected]77feb462011-05-16 23:37:2570#include "net/ocsp/nss_ocsp.h"
[email protected]a592c0432012-12-01 18:10:2971#endif
[email protected]77feb462011-05-16 23:37:2572
[email protected]6f96cbcb2011-11-04 02:26:0773#if defined(OS_CHROMEOS)
74#include "chrome/browser/chromeos/proxy_config_service_impl.h"
75#endif // defined(OS_CHROMEOS)
76
[email protected]631bb742011-11-02 11:29:3977using content::BrowserThread;
78
[email protected]075c0322012-02-14 00:56:4479class SafeBrowsingURLRequestContext;
80
[email protected]21ee224e2011-11-21 02:17:5381// The IOThread object must outlive any tasks posted to the IO thread before the
82// Quit task, so base::Bind() calls are not refcounted.
83
[email protected]0ac83682010-01-22 17:46:2784namespace {
85
[email protected]11f5e3a2012-09-27 00:30:1386#if defined(OS_MACOSX) && !defined(OS_IOS)
87void ObserveKeychainEvents() {
88 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
89 net::CertDatabase::GetInstance()->SetMessageLoopForKeychainEvents();
90}
91#endif
92
[email protected]ee4c30d2012-11-07 15:08:4393// Used for the "system" URLRequestContext.
94class SystemURLRequestContext : public net::URLRequestContext {
[email protected]77feb462011-05-16 23:37:2595 public:
96 SystemURLRequestContext() {
[email protected]a592c0432012-12-01 18:10:2997#if defined(USE_NSS) || defined(OS_IOS)
[email protected]8c434cbc2012-03-14 14:25:0998 net::SetURLRequestContextForNSSHttpIO(this);
[email protected]a592c0432012-12-01 18:10:2999#endif
[email protected]77feb462011-05-16 23:37:25100 }
101
102 private:
103 virtual ~SystemURLRequestContext() {
[email protected]a592c0432012-12-01 18:10:29104#if defined(USE_NSS) || defined(OS_IOS)
[email protected]8c434cbc2012-03-14 14:25:09105 net::SetURLRequestContextForNSSHttpIO(NULL);
[email protected]a592c0432012-12-01 18:10:29106#endif
[email protected]77feb462011-05-16 23:37:25107 }
108};
109
[email protected]c54a8912012-10-22 22:09:43110scoped_ptr<net::HostResolver> CreateGlobalHostResolver(net::NetLog* net_log) {
[email protected]0ac83682010-01-22 17:46:27111 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
[email protected]962b98212010-07-17 03:37:51112
[email protected]c54a8912012-10-22 22:09:43113 net::HostResolver::Options options;
[email protected]962b98212010-07-17 03:37:51114
115 // Use the concurrency override from the command-line, if any.
116 if (command_line.HasSwitch(switches::kHostResolverParallelism)) {
117 std::string s =
118 command_line.GetSwitchValueASCII(switches::kHostResolverParallelism);
119
120 // Parse the switch (it should be a positive integer formatted as decimal).
121 int n;
[email protected]e83326f2010-07-31 17:29:25122 if (base::StringToInt(s, &n) && n > 0) {
[email protected]c54a8912012-10-22 22:09:43123 options.max_concurrent_resolves = static_cast<size_t>(n);
[email protected]962b98212010-07-17 03:37:51124 } else {
125 LOG(ERROR) << "Invalid switch for host resolver parallelism: " << s;
126 }
127 }
128
[email protected]06ef6d92011-05-19 04:24:58129 // Use the retry attempts override from the command-line, if any.
130 if (command_line.HasSwitch(switches::kHostResolverRetryAttempts)) {
131 std::string s =
132 command_line.GetSwitchValueASCII(switches::kHostResolverRetryAttempts);
133 // Parse the switch (it should be a non-negative integer).
134 int n;
135 if (base::StringToInt(s, &n) && n >= 0) {
[email protected]c54a8912012-10-22 22:09:43136 options.max_retry_attempts = static_cast<size_t>(n);
[email protected]06ef6d92011-05-19 04:24:58137 } else {
138 LOG(ERROR) << "Invalid switch for host resolver retry attempts: " << s;
139 }
140 }
141
[email protected]c54a8912012-10-22 22:09:43142 scoped_ptr<net::HostResolver> global_host_resolver(
143 net::HostResolver::CreateSystemResolver(options, net_log));
[email protected]9087aa32010-02-18 08:03:38144
[email protected]0f8f1b432010-03-16 19:06:03145 // Determine if we should disable IPv6 support.
[email protected]9087aa32010-02-18 08:03:38146 if (!command_line.HasSwitch(switches::kEnableIPv6)) {
[email protected]0f8f1b432010-03-16 19:06:03147 if (command_line.HasSwitch(switches::kDisableIPv6)) {
[email protected]46f6e202010-02-26 06:07:25148 global_host_resolver->SetDefaultAddressFamily(net::ADDRESS_FAMILY_IPV4);
[email protected]0f8f1b432010-03-16 19:06:03149 } else {
[email protected]a78f4272011-10-21 19:16:33150 global_host_resolver->ProbeIPv6Support();
[email protected]0f8f1b432010-03-16 19:06:03151 }
[email protected]9087aa32010-02-18 08:03:38152 }
153
[email protected]9087aa32010-02-18 08:03:38154 // If hostname remappings were specified on the command-line, layer these
155 // rules on top of the real host resolver. This allows forwarding all requests
156 // through a designated test server.
[email protected]0f8f1b432010-03-16 19:06:03157 if (!command_line.HasSwitch(switches::kHostResolverRules))
[email protected]c54a8912012-10-22 22:09:43158 return global_host_resolver.PassAs<net::HostResolver>();
[email protected]0ac83682010-01-22 17:46:27159
[email protected]c54a8912012-10-22 22:09:43160 scoped_ptr<net::MappedHostResolver> remapped_resolver(
161 new net::MappedHostResolver(global_host_resolver.Pass()));
[email protected]0f8f1b432010-03-16 19:06:03162 remapped_resolver->SetRulesFromString(
163 command_line.GetSwitchValueASCII(switches::kHostResolverRules));
[email protected]c54a8912012-10-22 22:09:43164 return remapped_resolver.PassAs<net::HostResolver>();
[email protected]0ac83682010-01-22 17:46:27165}
166
[email protected]ef2bf422012-05-11 03:27:09167// TODO(willchan): Remove proxy script fetcher context since it's not necessary
168// now that I got rid of refcounting URLRequestContexts.
[email protected]77feb462011-05-16 23:37:25169// See IOThread::Globals for details.
[email protected]ef2bf422012-05-11 03:27:09170net::URLRequestContext*
[email protected]2fb629202010-12-23 23:52:57171ConstructProxyScriptFetcherContext(IOThread::Globals* globals,
172 net::NetLog* net_log) {
[email protected]ee4c30d2012-11-07 15:08:43173 net::URLRequestContext* context = new net::URLRequestContext;
[email protected]2fb629202010-12-23 23:52:57174 context->set_net_log(net_log);
175 context->set_host_resolver(globals->host_resolver.get());
176 context->set_cert_verifier(globals->cert_verifier.get());
[email protected]a2a41972011-12-07 17:47:27177 context->set_transport_security_state(
178 globals->transport_security_state.get());
[email protected]2fb629202010-12-23 23:52:57179 context->set_http_auth_handler_factory(
180 globals->http_auth_handler_factory.get());
181 context->set_proxy_service(globals->proxy_script_fetcher_proxy_service.get());
182 context->set_http_transaction_factory(
[email protected]52617df2010-12-24 07:30:01183 globals->proxy_script_fetcher_http_transaction_factory.get());
[email protected]933bc5c62011-04-12 19:08:02184 context->set_ftp_transaction_factory(
185 globals->proxy_script_fetcher_ftp_transaction_factory.get());
[email protected]273e37d2011-08-11 01:49:12186 context->set_cookie_store(globals->system_cookie_store.get());
[email protected]9c4eff22012-03-20 22:42:29187 context->set_server_bound_cert_service(
188 globals->system_server_bound_cert_service.get());
[email protected]3ce02412011-03-01 12:01:15189 context->set_network_delegate(globals->system_network_delegate.get());
[email protected]ee4c30d2012-11-07 15:08:43190 context->set_http_user_agent_settings(
191 globals->http_user_agent_settings.get());
[email protected]db96a882011-10-09 02:01:54192 // TODO(rtenneti): We should probably use HttpServerPropertiesManager for the
193 // system URLRequestContext too. There's no reason this should be tied to a
194 // profile.
[email protected]2fb629202010-12-23 23:52:57195 return context;
196}
197
[email protected]ef2bf422012-05-11 03:27:09198net::URLRequestContext*
[email protected]db0e86dd2011-03-16 14:47:21199ConstructSystemRequestContext(IOThread::Globals* globals,
200 net::NetLog* net_log) {
[email protected]ef2bf422012-05-11 03:27:09201 net::URLRequestContext* context = new SystemURLRequestContext;
[email protected]db0e86dd2011-03-16 14:47:21202 context->set_net_log(net_log);
203 context->set_host_resolver(globals->host_resolver.get());
204 context->set_cert_verifier(globals->cert_verifier.get());
[email protected]a2a41972011-12-07 17:47:27205 context->set_transport_security_state(
206 globals->transport_security_state.get());
[email protected]db0e86dd2011-03-16 14:47:21207 context->set_http_auth_handler_factory(
208 globals->http_auth_handler_factory.get());
209 context->set_proxy_service(globals->system_proxy_service.get());
210 context->set_http_transaction_factory(
211 globals->system_http_transaction_factory.get());
[email protected]933bc5c62011-04-12 19:08:02212 context->set_ftp_transaction_factory(
213 globals->system_ftp_transaction_factory.get());
[email protected]273e37d2011-08-11 01:49:12214 context->set_cookie_store(globals->system_cookie_store.get());
[email protected]9c4eff22012-03-20 22:42:29215 context->set_server_bound_cert_service(
216 globals->system_server_bound_cert_service.get());
[email protected]a73a2802012-05-02 19:20:15217 context->set_throttler_manager(globals->throttler_manager.get());
[email protected]815c69cf2012-06-30 00:52:08218 context->set_network_delegate(globals->system_network_delegate.get());
[email protected]ee4c30d2012-11-07 15:08:43219 context->set_http_user_agent_settings(
220 globals->http_user_agent_settings.get());
[email protected]db0e86dd2011-03-16 14:47:21221 return context;
222}
223
[email protected]f9cf5572012-12-04 15:52:09224int GetSwitchValueAsInt(const CommandLine& command_line,
225 const std::string& switch_name) {
226 int value;
227 if (!base::StringToInt(command_line.GetSwitchValueASCII(switch_name),
228 &value)) {
229 return 0;
230 }
231 return value;
[email protected]27c253802012-11-30 08:18:12232}
233
[email protected]0ac83682010-01-22 17:46:27234} // namespace
235
[email protected]e0845d5f2012-05-29 00:11:41236class IOThread::LoggingNetworkChangeObserver
[email protected]3d5aaad2012-10-27 12:31:28237 : public net::NetworkChangeNotifier::IPAddressObserver,
[email protected]03848872012-12-08 02:46:41238 public net::NetworkChangeNotifier::ConnectionTypeObserver,
239 public net::NetworkChangeNotifier::NetworkChangeObserver {
[email protected]e0845d5f2012-05-29 00:11:41240 public:
241 // |net_log| must remain valid throughout our lifetime.
242 explicit LoggingNetworkChangeObserver(net::NetLog* net_log)
243 : net_log_(net_log) {
244 net::NetworkChangeNotifier::AddIPAddressObserver(this);
[email protected]3d5aaad2012-10-27 12:31:28245 net::NetworkChangeNotifier::AddConnectionTypeObserver(this);
[email protected]03848872012-12-08 02:46:41246 net::NetworkChangeNotifier::AddNetworkChangeObserver(this);
[email protected]e0845d5f2012-05-29 00:11:41247 }
248
249 ~LoggingNetworkChangeObserver() {
250 net::NetworkChangeNotifier::RemoveIPAddressObserver(this);
[email protected]3d5aaad2012-10-27 12:31:28251 net::NetworkChangeNotifier::RemoveConnectionTypeObserver(this);
[email protected]03848872012-12-08 02:46:41252 net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this);
[email protected]e0845d5f2012-05-29 00:11:41253 }
254
[email protected]03848872012-12-08 02:46:41255 // NetworkChangeNotifier::IPAddressObserver implementation.
[email protected]3d5aaad2012-10-27 12:31:28256 virtual void OnIPAddressChanged() OVERRIDE {
[email protected]e0845d5f2012-05-29 00:11:41257 VLOG(1) << "Observed a change to the network IP addresses";
258
[email protected]2fa08912012-06-14 20:56:26259 net_log_->AddGlobalEntry(net::NetLog::TYPE_NETWORK_IP_ADDRESSES_CHANGED);
[email protected]e0845d5f2012-05-29 00:11:41260 }
261
[email protected]03848872012-12-08 02:46:41262 // NetworkChangeNotifier::ConnectionTypeObserver implementation.
[email protected]3d5aaad2012-10-27 12:31:28263 virtual void OnConnectionTypeChanged(
264 net::NetworkChangeNotifier::ConnectionType type) OVERRIDE {
265 std::string type_as_string =
266 net::NetworkChangeNotifier::ConnectionTypeToString(type);
267
268 VLOG(1) << "Observed a change to network connectivity state "
269 << type_as_string;
270
271 net_log_->AddGlobalEntry(
272 net::NetLog::TYPE_NETWORK_CONNECTIVITY_CHANGED,
273 net::NetLog::StringCallback("new_connection_type", &type_as_string));
274 }
275
[email protected]03848872012-12-08 02:46:41276 // NetworkChangeNotifier::NetworkChangeObserver implementation.
277 virtual void OnNetworkChanged(
278 net::NetworkChangeNotifier::ConnectionType type) OVERRIDE {
279 std::string type_as_string =
280 net::NetworkChangeNotifier::ConnectionTypeToString(type);
281
282 VLOG(1) << "Observed a network change to state " << type_as_string;
283
284 net_log_->AddGlobalEntry(
285 net::NetLog::TYPE_NETWORK_CHANGED,
286 net::NetLog::StringCallback("new_connection_type", &type_as_string));
287 }
288
[email protected]e0845d5f2012-05-29 00:11:41289 private:
290 net::NetLog* net_log_;
291 DISALLOW_COPY_AND_ASSIGN(LoggingNetworkChangeObserver);
292};
293
[email protected]abe2c032011-03-31 18:49:34294class SystemURLRequestContextGetter : public net::URLRequestContextGetter {
[email protected]db0e86dd2011-03-16 14:47:21295 public:
296 explicit SystemURLRequestContextGetter(IOThread* io_thread);
[email protected]db0e86dd2011-03-16 14:47:21297
[email protected]abe2c032011-03-31 18:49:34298 // Implementation for net::UrlRequestContextGetter.
[email protected]4969b0122012-06-16 01:58:28299 virtual net::URLRequestContext* GetURLRequestContext() OVERRIDE;
300 virtual scoped_refptr<base::SingleThreadTaskRunner>
301 GetNetworkTaskRunner() const OVERRIDE;
[email protected]db0e86dd2011-03-16 14:47:21302
[email protected]13ed17f82012-04-06 02:27:18303 protected:
304 virtual ~SystemURLRequestContextGetter();
305
[email protected]db0e86dd2011-03-16 14:47:21306 private:
307 IOThread* const io_thread_; // Weak pointer, owned by BrowserProcess.
[email protected]4969b0122012-06-16 01:58:28308 scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_;
[email protected]db0e86dd2011-03-16 14:47:21309
310 base::debug::LeakTracker<SystemURLRequestContextGetter> leak_tracker_;
311};
312
313SystemURLRequestContextGetter::SystemURLRequestContextGetter(
314 IOThread* io_thread)
315 : io_thread_(io_thread),
[email protected]4969b0122012-06-16 01:58:28316 network_task_runner_(
[email protected]2e5b60a22011-11-28 15:56:41317 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)) {
[email protected]db0e86dd2011-03-16 14:47:21318}
319
320SystemURLRequestContextGetter::~SystemURLRequestContextGetter() {}
321
322net::URLRequestContext* SystemURLRequestContextGetter::GetURLRequestContext() {
323 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]ef2bf422012-05-11 03:27:09324 DCHECK(io_thread_->globals()->system_request_context.get());
[email protected]db0e86dd2011-03-16 14:47:21325
[email protected]ef2bf422012-05-11 03:27:09326 return io_thread_->globals()->system_request_context.get();
[email protected]db0e86dd2011-03-16 14:47:21327}
328
[email protected]4969b0122012-06-16 01:58:28329scoped_refptr<base::SingleThreadTaskRunner>
330SystemURLRequestContextGetter::GetNetworkTaskRunner() const {
331 return network_task_runner_;
[email protected]db0e86dd2011-03-16 14:47:21332}
333
[email protected]c93123fa2012-04-19 02:49:48334IOThread::Globals::
335SystemRequestContextLeakChecker::SystemRequestContextLeakChecker(
336 Globals* globals)
337 : globals_(globals) {
338 DCHECK(globals_);
[email protected]7613faae2012-04-18 01:01:19339}
[email protected]1889dc1b2010-10-14 22:03:13340
[email protected]c93123fa2012-04-19 02:49:48341IOThread::Globals::
342SystemRequestContextLeakChecker::~SystemRequestContextLeakChecker() {
343 if (globals_->system_request_context.get())
344 globals_->system_request_context->AssertNoURLRequests();
345}
346
347IOThread::Globals::Globals()
348 : ALLOW_THIS_IN_INITIALIZER_LIST(
[email protected]c2dad292012-09-07 21:27:35349 system_request_context_leak_checker(this)),
350 ignore_certificate_errors(false),
351 http_pipelining_enabled(false),
352 testing_fixed_http_port(0),
353 testing_fixed_https_port(0) {}
354
[email protected]c93123fa2012-04-19 02:49:48355IOThread::Globals::~Globals() {}
356
[email protected]bcefe0f2010-11-10 16:19:10357// |local_state| is passed in explicitly in order to (1) reduce implicit
358// dependencies and (2) make IOThread more flexible for testing.
[email protected]3ce02412011-03-01 12:01:15359IOThread::IOThread(
[email protected]5b199522012-12-22 17:24:44360 PrefServiceSimple* local_state,
[email protected]77305422012-11-29 16:51:39361 policy::PolicyService* policy_service,
[email protected]3ce02412011-03-01 12:01:15362 ChromeNetLog* net_log,
[email protected]5a38dfd2012-07-23 23:22:10363 extensions::EventRouterForwarder* extension_event_router_forwarder)
[email protected]2e5b60a22011-11-28 15:56:41364 : net_log_(net_log),
[email protected]3ce02412011-03-01 12:01:15365 extension_event_router_forwarder_(extension_event_router_forwarder),
[email protected]d13c3272010-02-04 00:24:51366 globals_(NULL),
[email protected]4a109492011-09-24 21:00:12367 sdch_manager_(NULL),
[email protected]77305422012-11-29 16:51:39368 is_spdy_disabled_by_policy_(false),
[email protected]21ee224e2011-11-21 02:17:53369 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
[email protected]bcefe0f2010-11-10 16:19:10370 // We call RegisterPrefs() here (instead of inside browser_prefs.cc) to make
371 // sure that everything is initialized in the right order.
[email protected]5b199522012-12-22 17:24:44372 //
373 // TODO(joi): See if we can fix so it does get registered from
374 // browser_prefs::RegisterLocalState.
[email protected]bcefe0f2010-11-10 16:19:10375 RegisterPrefs(local_state);
376 auth_schemes_ = local_state->GetString(prefs::kAuthSchemes);
377 negotiate_disable_cname_lookup_ = local_state->GetBoolean(
378 prefs::kDisableAuthNegotiateCnameLookup);
379 negotiate_enable_port_ = local_state->GetBoolean(
380 prefs::kEnableAuthNegotiatePort);
381 auth_server_whitelist_ = local_state->GetString(prefs::kAuthServerWhitelist);
382 auth_delegate_whitelist_ = local_state->GetString(
383 prefs::kAuthNegotiateDelegateWhitelist);
[email protected]ac7f3fdb2010-11-12 12:47:05384 gssapi_library_name_ = local_state->GetString(prefs::kGSSAPILibraryName);
[email protected]6f96cbcb2011-11-04 02:26:07385 pref_proxy_config_tracker_.reset(
386 ProxyServiceFactory::CreatePrefProxyConfigTracker(local_state));
[email protected]9d8cfb682012-09-13 16:48:04387 ChromeNetworkDelegate::InitializePrefsOnUIThread(
388 &system_enable_referrers_,
389 NULL,
[email protected]d1208ba32012-11-08 11:10:33390 NULL,
[email protected]9d8cfb682012-09-13 16:48:04391 local_state);
[email protected]4d45a6de2011-05-13 05:20:18392 ssl_config_service_manager_.reset(
[email protected]e6426c1b2012-09-12 21:51:41393 SSLConfigServiceManager::CreateDefaultManager(local_state, NULL));
[email protected]2e5b60a22011-11-28 15:56:41394
[email protected]fa4b6c32012-11-26 23:02:39395 dns_client_enabled_.Init(prefs::kBuiltInDnsClientEnabled,
396 local_state,
397 base::Bind(&IOThread::UpdateDnsClientEnabled,
398 base::Unretained(this)));
399 dns_client_enabled_.MoveToThread(
400 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO));
401
[email protected]77305422012-11-29 16:51:39402#if defined(ENABLE_CONFIGURATION_POLICY)
403 is_spdy_disabled_by_policy_ = policy_service->GetPolicies(
404 policy::POLICY_DOMAIN_CHROME,
405 std::string()).Get(policy::key::kDisableSpdy) != NULL;
406#endif // ENABLE_CONFIGURATION_POLICY
407
[email protected]2e5b60a22011-11-28 15:56:41408 BrowserThread::SetDelegate(BrowserThread::IO, this);
[email protected]bcefe0f2010-11-10 16:19:10409}
[email protected]0ac83682010-01-22 17:46:27410
411IOThread::~IOThread() {
[email protected]2e5b60a22011-11-28 15:56:41412 // This isn't needed for production code, but in tests, IOThread may
413 // be multiply constructed.
414 BrowserThread::SetDelegate(BrowserThread::IO, NULL);
415
[email protected]d461ed22013-01-18 03:18:56416 pref_proxy_config_tracker_->DetachFromPrefService();
[email protected]d13c3272010-02-04 00:24:51417 DCHECK(!globals_);
[email protected]0ac83682010-01-22 17:46:27418}
419
[email protected]d13c3272010-02-04 00:24:51420IOThread::Globals* IOThread::globals() {
[email protected]f8b3ef82010-10-11 02:45:52421 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]d13c3272010-02-04 00:24:51422 return globals_;
[email protected]0ac83682010-01-22 17:46:27423}
424
[email protected]b2fcd0e2010-12-01 15:19:40425ChromeNetLog* IOThread::net_log() {
426 return net_log_;
427}
428
[email protected]b09f76d62011-12-07 01:51:06429void IOThread::ChangedToOnTheRecord() {
430 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
431 BrowserThread::PostTask(
432 BrowserThread::IO,
433 FROM_HERE,
434 base::Bind(&IOThread::ChangedToOnTheRecordOnIOThread,
435 base::Unretained(this)));
436}
437
[email protected]abe2c032011-03-31 18:49:34438net::URLRequestContextGetter* IOThread::system_url_request_context_getter() {
[email protected]db0e86dd2011-03-16 14:47:21439 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
440 if (!system_url_request_context_getter_) {
[email protected]addb3242011-06-13 21:39:16441 InitSystemRequestContext();
[email protected]db0e86dd2011-03-16 14:47:21442 }
443 return system_url_request_context_getter_;
444}
445
[email protected]0ac83682010-01-22 17:46:27446void IOThread::Init() {
[email protected]2e5b60a22011-11-28 15:56:41447 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]70b92342010-10-12 05:54:06448
[email protected]a592c0432012-12-01 18:10:29449#if defined(USE_NSS) || defined(OS_IOS)
[email protected]8c434cbc2012-03-14 14:25:09450 net::SetMessageLoopForNSSHttpIO();
[email protected]a592c0432012-12-01 18:10:29451#endif
[email protected]70b92342010-10-12 05:54:06452
[email protected]c2dad292012-09-07 21:27:35453 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
454
[email protected]d13c3272010-02-04 00:24:51455 DCHECK(!globals_);
456 globals_ = new Globals;
457
[email protected]58bc7042010-07-07 18:04:14458 // Add an observer that will emit network change events to the ChromeNetLog.
459 // Assuming NetworkChangeNotifier dispatches in FIFO order, we should be
460 // logging the network change before other IO thread consumers respond to it.
461 network_change_observer_.reset(
[email protected]b2fcd0e2010-12-01 15:19:40462 new LoggingNetworkChangeObserver(net_log_));
[email protected]58bc7042010-07-07 18:04:14463
[email protected]cde8b3c2012-08-13 19:20:52464 // Setup the HistogramWatcher to run on the IO thread.
465 net::NetworkChangeNotifier::InitHistogramWatcher();
466
[email protected]3ce02412011-03-01 12:01:15467 globals_->extension_event_router_forwarder =
468 extension_event_router_forwarder_;
[email protected]a09159a2012-11-29 12:51:48469 ChromeNetworkDelegate* network_delegate =
470 new ChromeNetworkDelegate(extension_event_router_forwarder_,
471 &system_enable_referrers_);
[email protected]c2dad292012-09-07 21:27:35472 if (command_line.HasSwitch(switches::kDisableExtensionsHttpThrottling))
[email protected]a1d4ab072012-06-07 13:21:15473 network_delegate->NeverThrottleRequests();
[email protected]a1d4ab072012-06-07 13:21:15474 globals_->system_network_delegate.reset(network_delegate);
[email protected]c54a8912012-10-22 22:09:43475 globals_->host_resolver = CreateGlobalHostResolver(net_log_);
[email protected]fa4b6c32012-11-26 23:02:39476 UpdateDnsClientEnabled();
[email protected]9f59fac2012-03-21 23:18:11477 globals_->cert_verifier.reset(net::CertVerifier::CreateDefault());
[email protected]f43b89f32012-05-01 19:39:48478 globals_->transport_security_state.reset(new net::TransportSecurityState());
[email protected]4d45a6de2011-05-13 05:20:18479 globals_->ssl_config_service = GetSSLConfigService();
[email protected]ec44ee02012-09-28 21:31:51480 if (command_line.HasSwitch(switches::kSpdyProxyOrigin)) {
481 spdyproxy_origin_ =
482 command_line.GetSwitchValueASCII(switches::kSpdyProxyOrigin);
483 }
[email protected]65d34382010-07-01 18:12:26484 globals_->http_auth_handler_factory.reset(CreateDefaultAuthHandlerFactory(
[email protected]73c45322010-10-01 23:57:54485 globals_->host_resolver.get()));
[email protected]17291a022011-10-10 07:32:53486 globals_->http_server_properties.reset(new net::HttpServerPropertiesImpl);
[email protected]2fb629202010-12-23 23:52:57487 // For the ProxyScriptFetcher, we use a direct ProxyService.
[email protected]6104ea5d2011-04-27 21:37:12488 globals_->proxy_script_fetcher_proxy_service.reset(
489 net::ProxyService::CreateDirectWithNetLog(net_log_));
[email protected]273e37d2011-08-11 01:49:12490 // In-memory cookie store.
491 globals_->system_cookie_store = new net::CookieMonster(NULL, NULL);
[email protected]9c4eff22012-03-20 22:42:29492 // In-memory server bound cert store.
493 globals_->system_server_bound_cert_service.reset(
494 new net::ServerBoundCertService(
[email protected]5bab49ec2012-05-04 21:13:19495 new net::DefaultServerBoundCertStore(NULL),
496 base::WorkerPool::GetTaskRunner(true)));
[email protected]4588b3d2012-11-14 00:37:38497 globals_->dns_probe_service.reset(new chrome_browser_net::DnsProbeService());
[email protected]a9e0d1412012-08-20 22:13:01498 globals_->load_time_stats.reset(new chrome_browser_net::LoadTimeStats());
[email protected]c2dad292012-09-07 21:27:35499 globals_->host_mapping_rules.reset(new net::HostMappingRules());
[email protected]ee4c30d2012-11-07 15:08:43500 globals_->http_user_agent_settings.reset(
501 new BasicHttpUserAgentSettings(EmptyString(), EmptyString()));
[email protected]c2dad292012-09-07 21:27:35502 if (command_line.HasSwitch(switches::kHostRules)) {
503 globals_->host_mapping_rules->SetRulesFromString(
504 command_line.GetSwitchValueASCII(switches::kHostRules));
505 }
506 if (command_line.HasSwitch(switches::kIgnoreCertificateErrors))
507 globals_->ignore_certificate_errors = true;
508 if (command_line.HasSwitch(switches::kEnableHttpPipelining))
509 globals_->http_pipelining_enabled = true;
510 if (command_line.HasSwitch(switches::kTestingFixedHttpPort)) {
[email protected]f9cf5572012-12-04 15:52:09511 globals_->testing_fixed_http_port =
512 GetSwitchValueAsInt(command_line, switches::kTestingFixedHttpPort);
[email protected]c2dad292012-09-07 21:27:35513 }
514 if (command_line.HasSwitch(switches::kTestingFixedHttpsPort)) {
[email protected]f9cf5572012-12-04 15:52:09515 globals_->testing_fixed_https_port =
516 GetSwitchValueAsInt(command_line, switches::kTestingFixedHttpsPort);
[email protected]c2dad292012-09-07 21:27:35517 }
[email protected]f1e97e92012-12-16 04:53:25518 if (command_line.HasSwitch(switches::kOriginPortToForceQuicOn)) {
519 globals_->origin_port_to_force_quic_on.set(
520 GetSwitchValueAsInt(command_line,
521 switches::kOriginPortToForceQuicOn));
522 }
[email protected]c2dad292012-09-07 21:27:35523
[email protected]f9cf5572012-12-04 15:52:09524 InitializeNetworkOptions(command_line);
525
[email protected]9e1bdd32011-02-03 21:48:34526 net::HttpNetworkSession::Params session_params;
[email protected]f9cf5572012-12-04 15:52:09527 InitializeNetworkSessionParams(&session_params);
[email protected]27c253802012-11-30 08:18:12528 session_params.net_log = net_log_;
[email protected]9e1bdd32011-02-03 21:48:34529 session_params.proxy_service =
530 globals_->proxy_script_fetcher_proxy_service.get();
[email protected]c2dad292012-09-07 21:27:35531
[email protected]57cb0f72011-01-28 06:33:58532 scoped_refptr<net::HttpNetworkSession> network_session(
[email protected]9e1bdd32011-02-03 21:48:34533 new net::HttpNetworkSession(session_params));
[email protected]57cb0f72011-01-28 06:33:58534 globals_->proxy_script_fetcher_http_transaction_factory.reset(
535 new net::HttpNetworkLayer(network_session));
[email protected]933bc5c62011-04-12 19:08:02536 globals_->proxy_script_fetcher_ftp_transaction_factory.reset(
537 new net::FtpNetworkLayer(globals_->host_resolver.get()));
[email protected]2fb629202010-12-23 23:52:57538
[email protected]a73a2802012-05-02 19:20:15539 globals_->throttler_manager.reset(new net::URLRequestThrottlerManager());
[email protected]a1d4ab072012-06-07 13:21:15540 globals_->throttler_manager->set_net_log(net_log_);
[email protected]a73a2802012-05-02 19:20:15541 // Always done in production, disabled only for unit tests.
542 globals_->throttler_manager->set_enable_thread_checks(true);
[email protected]a73a2802012-05-02 19:20:15543
[email protected]ef2bf422012-05-11 03:27:09544 globals_->proxy_script_fetcher_context.reset(
545 ConstructProxyScriptFetcherContext(globals_, net_log_));
[email protected]4a109492011-09-24 21:00:12546
547 sdch_manager_ = new net::SdchManager();
[email protected]2e5b60a22011-11-28 15:56:41548
[email protected]11f5e3a2012-09-27 00:30:13549#if defined(OS_MACOSX) && !defined(OS_IOS)
550 // Start observing Keychain events. This needs to be done on the UI thread,
551 // as Keychain services requires a CFRunLoop.
552 BrowserThread::PostTask(BrowserThread::UI,
553 FROM_HERE,
554 base::Bind(&ObserveKeychainEvents));
555#endif
556
[email protected]2e5b60a22011-11-28 15:56:41557 // InitSystemRequestContext turns right around and posts a task back
558 // to the IO thread, so we can't let it run until we know the IO
559 // thread has started.
560 //
561 // Note that since we are at BrowserThread::Init time, the UI thread
562 // is blocked waiting for the thread to start. Therefore, posting
563 // this task to the main thread's message loop here is guaranteed to
564 // get it onto the message loop while the IOThread object still
565 // exists. However, the message might not be processed on the UI
566 // thread until after IOThread is gone, so use a weak pointer.
567 BrowserThread::PostTask(BrowserThread::UI,
568 FROM_HERE,
569 base::Bind(&IOThread::InitSystemRequestContext,
570 weak_factory_.GetWeakPtr()));
571
572 // We constructed the weak pointer on the IO thread but it will be
573 // used on the UI thread. Call this to avoid a thread checker
574 // error.
575 weak_factory_.DetachFromThread();
[email protected]0ac83682010-01-22 17:46:27576}
577
[email protected]2a92cd92010-04-27 00:01:41578void IOThread::CleanUp() {
[email protected]075c0322012-02-14 00:56:44579 base::debug::LeakTracker<SafeBrowsingURLRequestContext>::CheckForLeaks();
580
[email protected]4a109492011-09-24 21:00:12581 delete sdch_manager_;
582 sdch_manager_ = NULL;
583
[email protected]a592c0432012-12-01 18:10:29584#if defined(USE_NSS) || defined(OS_IOS)
[email protected]8c434cbc2012-03-14 14:25:09585 net::ShutdownNSSHttpIO();
[email protected]a592c0432012-12-01 18:10:29586#endif
[email protected]59a3b362010-10-21 21:52:41587
[email protected]db0e86dd2011-03-16 14:47:21588 system_url_request_context_getter_ = NULL;
589
[email protected]af669932012-01-17 19:26:58590 // Release objects that the net::URLRequestContext could have been pointing
591 // to.
[email protected]0ee7a3b2010-11-09 06:13:40592
593 // This must be reset before the ChromeNetLog is destroyed.
594 network_change_observer_.reset();
595
[email protected]db0e86dd2011-03-16 14:47:21596 system_proxy_config_service_.reset();
597
[email protected]d13c3272010-02-04 00:24:51598 delete globals_;
599 globals_ = NULL;
[email protected]0ac83682010-01-22 17:46:27600
[email protected]db0e86dd2011-03-16 14:47:21601 base::debug::LeakTracker<SystemURLRequestContextGetter>::CheckForLeaks();
[email protected]0ac83682010-01-22 17:46:27602}
603
[email protected]f9cf5572012-12-04 15:52:09604void IOThread::InitializeNetworkOptions(const CommandLine& command_line) {
605 if (command_line.HasSwitch(switches::kEnableFileCookies)) {
[email protected]77305422012-11-29 16:51:39606 // Enable cookie storage for file:// URLs. Must do this before the first
607 // Profile (and therefore the first CookieMonster) is created.
608 net::CookieMonster::EnableFileScheme();
609 }
610
611 // If "spdy.disabled" preference is controlled via policy, then skip use-spdy
612 // command line flags.
613 if (is_spdy_disabled_by_policy_)
614 return;
615
[email protected]f9cf5572012-12-04 15:52:09616 if (command_line.HasSwitch(switches::kEnableIPPooling))
617 globals_->enable_spdy_ip_pooling.set(true);
[email protected]77305422012-11-29 16:51:39618
[email protected]f9cf5572012-12-04 15:52:09619 if (command_line.HasSwitch(switches::kDisableIPPooling))
620 globals_->enable_spdy_ip_pooling.set(false);
[email protected]77305422012-11-29 16:51:39621
[email protected]f9cf5572012-12-04 15:52:09622 if (command_line.HasSwitch(switches::kEnableSpdyCredentialFrames))
623 globals_->enable_spdy_credential_frames.set(true);
[email protected]77305422012-11-29 16:51:39624
[email protected]f9cf5572012-12-04 15:52:09625 if (command_line.HasSwitch(switches::kEnableWebSocketOverSpdy)) {
[email protected]77305422012-11-29 16:51:39626 // Enable WebSocket over SPDY.
627 net::WebSocketJob::set_websocket_over_spdy_enabled(true);
628 }
[email protected]f9cf5572012-12-04 15:52:09629 if (command_line.HasSwitch(switches::kMaxSpdySessionsPerDomain)) {
630 globals_->max_spdy_sessions_per_domain.set(
631 GetSwitchValueAsInt(command_line, switches::kMaxSpdySessionsPerDomain));
632 }
633 if (command_line.HasSwitch(switches::kMaxSpdyConcurrentStreams)) {
634 globals_->max_spdy_concurrent_streams_limit.set(
635 GetSwitchValueAsInt(command_line, switches::kMaxSpdyConcurrentStreams));
636 }
[email protected]77305422012-11-29 16:51:39637
638 bool used_spdy_switch = false;
[email protected]f9cf5572012-12-04 15:52:09639 if (command_line.HasSwitch(switches::kUseSpdy)) {
[email protected]77305422012-11-29 16:51:39640 std::string spdy_mode =
[email protected]f9cf5572012-12-04 15:52:09641 command_line.GetSwitchValueASCII(switches::kUseSpdy);
[email protected]443a30ed2012-11-30 02:56:46642 EnableSpdy(spdy_mode);
[email protected]77305422012-11-29 16:51:39643 used_spdy_switch = true;
644 }
[email protected]f9cf5572012-12-04 15:52:09645 if (command_line.HasSwitch(switches::kEnableSpdy3)) {
[email protected]77305422012-11-29 16:51:39646 net::HttpStreamFactory::EnableNpnSpdy3();
647 used_spdy_switch = true;
[email protected]f9cf5572012-12-04 15:52:09648 } else if (command_line.HasSwitch(switches::kEnableNpn)) {
[email protected]77305422012-11-29 16:51:39649 net::HttpStreamFactory::EnableNpnSpdy();
650 used_spdy_switch = true;
[email protected]f9cf5572012-12-04 15:52:09651 } else if (command_line.HasSwitch(switches::kEnableNpnHttpOnly)) {
[email protected]77305422012-11-29 16:51:39652 net::HttpStreamFactory::EnableNpnHttpOnly();
653 used_spdy_switch = true;
654 }
655 if (!used_spdy_switch) {
656 net::HttpStreamFactory::EnableNpnSpdy3();
657 }
658}
659
[email protected]443a30ed2012-11-30 02:56:46660void IOThread::EnableSpdy(const std::string& mode) {
661 static const char kOff[] = "off";
662 static const char kSSL[] = "ssl";
663 static const char kDisableSSL[] = "no-ssl";
664 static const char kDisablePing[] = "no-ping";
665 static const char kExclude[] = "exclude"; // Hosts to exclude
666 static const char kDisableCompression[] = "no-compress";
667 static const char kDisableAltProtocols[] = "no-alt-protocols";
668 static const char kForceAltProtocols[] = "force-alt-protocols";
669 static const char kSingleDomain[] = "single-domain";
670
671 static const char kInitialMaxConcurrentStreams[] = "init-max-streams";
672
673 std::vector<std::string> spdy_options;
674 base::SplitString(mode, ',', &spdy_options);
675
676 for (std::vector<std::string>::iterator it = spdy_options.begin();
677 it != spdy_options.end(); ++it) {
678 const std::string& element = *it;
679 std::vector<std::string> name_value;
680 base::SplitString(element, '=', &name_value);
681 const std::string& option = name_value.size() > 0 ? name_value[0] : "";
682 const std::string value = name_value.size() > 1 ? name_value[1] : "";
683
684 if (option == kOff) {
685 net::HttpStreamFactory::set_spdy_enabled(false);
686 } else if (option == kDisableSSL) {
[email protected]f9cf5572012-12-04 15:52:09687 globals_->spdy_default_protocol.set(net::kProtoSPDY2);
[email protected]443a30ed2012-11-30 02:56:46688 net::HttpStreamFactory::set_force_spdy_over_ssl(false);
689 net::HttpStreamFactory::set_force_spdy_always(true);
690 } else if (option == kSSL) {
[email protected]f9cf5572012-12-04 15:52:09691 globals_->spdy_default_protocol.set(net::kProtoSPDY2);
[email protected]443a30ed2012-11-30 02:56:46692 net::HttpStreamFactory::set_force_spdy_over_ssl(true);
693 net::HttpStreamFactory::set_force_spdy_always(true);
694 } else if (option == kDisablePing) {
[email protected]f9cf5572012-12-04 15:52:09695 globals_->enable_spdy_ping_based_connection_checking.set(false);
[email protected]443a30ed2012-11-30 02:56:46696 } else if (option == kExclude) {
697 net::HttpStreamFactory::add_forced_spdy_exclusion(value);
698 } else if (option == kDisableCompression) {
[email protected]f9cf5572012-12-04 15:52:09699 globals_->enable_spdy_compression.set(false);
[email protected]443a30ed2012-11-30 02:56:46700 } else if (option == kDisableAltProtocols) {
701 net::HttpStreamFactory::set_use_alternate_protocols(false);
702 } else if (option == kForceAltProtocols) {
703 net::PortAlternateProtocolPair pair;
704 pair.port = 443;
705 pair.protocol = net::NPN_SPDY_2;
706 net::HttpServerPropertiesImpl::ForceAlternateProtocol(pair);
707 } else if (option == kSingleDomain) {
708 DLOG(INFO) << "FORCING SINGLE DOMAIN";
[email protected]f9cf5572012-12-04 15:52:09709 globals_->force_spdy_single_domain.set(true);
[email protected]443a30ed2012-11-30 02:56:46710 } else if (option == kInitialMaxConcurrentStreams) {
711 int streams;
[email protected]f9cf5572012-12-04 15:52:09712 if (base::StringToInt(value, &streams))
713 globals_->initial_max_spdy_concurrent_streams.set(streams);
[email protected]443a30ed2012-11-30 02:56:46714 } else if (option.empty() && it == spdy_options.begin()) {
715 continue;
716 } else {
717 LOG(DFATAL) << "Unrecognized spdy option: " << option;
718 }
719 }
720}
721
[email protected]bcefe0f2010-11-10 16:19:10722// static
[email protected]5b199522012-12-22 17:24:44723void IOThread::RegisterPrefs(PrefServiceSimple* local_state) {
[email protected]bcefe0f2010-11-10 16:19:10724 local_state->RegisterStringPref(prefs::kAuthSchemes,
[email protected]ec44ee02012-09-28 21:31:51725 "basic,digest,ntlm,negotiate,"
726 "spdyproxy");
[email protected]bcefe0f2010-11-10 16:19:10727 local_state->RegisterBooleanPref(prefs::kDisableAuthNegotiateCnameLookup,
728 false);
729 local_state->RegisterBooleanPref(prefs::kEnableAuthNegotiatePort, false);
730 local_state->RegisterStringPref(prefs::kAuthServerWhitelist, "");
731 local_state->RegisterStringPref(prefs::kAuthNegotiateDelegateWhitelist, "");
[email protected]ac7f3fdb2010-11-12 12:47:05732 local_state->RegisterStringPref(prefs::kGSSAPILibraryName, "");
[email protected]ec44ee02012-09-28 21:31:51733 local_state->RegisterStringPref(prefs::kSpdyProxyOrigin, "");
[email protected]0a8db0d2011-04-13 15:15:40734 local_state->RegisterBooleanPref(prefs::kEnableReferrers, true);
[email protected]7a299a92012-10-24 23:54:50735 local_state->RegisterInt64Pref(prefs::kHttpReceivedContentLength, 0);
736 local_state->RegisterInt64Pref(prefs::kHttpOriginalContentLength, 0);
[email protected]fa4b6c32012-11-26 23:02:39737 local_state->RegisterBooleanPref(
738 prefs::kBuiltInDnsClientEnabled,
739 chrome_browser_net::ConfigureAsyncDnsFieldTrial());
[email protected]bcefe0f2010-11-10 16:19:10740}
741
[email protected]65d34382010-07-01 18:12:26742net::HttpAuthHandlerFactory* IOThread::CreateDefaultAuthHandlerFactory(
743 net::HostResolver* resolver) {
[email protected]9030a632010-11-19 20:12:09744 net::HttpAuthFilterWhitelist* auth_filter_default_credentials = NULL;
745 if (!auth_server_whitelist_.empty()) {
746 auth_filter_default_credentials =
747 new net::HttpAuthFilterWhitelist(auth_server_whitelist_);
748 }
749 net::HttpAuthFilterWhitelist* auth_filter_delegate = NULL;
750 if (!auth_delegate_whitelist_.empty()) {
751 auth_filter_delegate =
752 new net::HttpAuthFilterWhitelist(auth_delegate_whitelist_);
753 }
[email protected]b4955e7d2010-04-16 20:22:30754 globals_->url_security_manager.reset(
[email protected]d201b200e2010-08-27 17:35:02755 net::URLSecurityManager::Create(auth_filter_default_credentials,
756 auth_filter_delegate));
[email protected]b7304162010-08-23 17:42:29757 std::vector<std::string> supported_schemes;
[email protected]bcefe0f2010-11-10 16:19:10758 base::SplitString(auth_schemes_, ',', &supported_schemes);
[email protected]b7304162010-08-23 17:42:29759
[email protected]ec44ee02012-09-28 21:31:51760 scoped_ptr<net::HttpAuthHandlerRegistryFactory> registry_factory(
761 net::HttpAuthHandlerRegistryFactory::Create(
762 supported_schemes, globals_->url_security_manager.get(),
763 resolver, gssapi_library_name_, negotiate_disable_cname_lookup_,
764 negotiate_enable_port_));
765
766 if (!spdyproxy_origin_.empty()) {
767 GURL origin_url(spdyproxy_origin_);
768 if (origin_url.is_valid()) {
769 registry_factory->RegisterSchemeFactory(
770 "spdyproxy",
771 new spdyproxy::HttpAuthHandlerSpdyProxy::Factory(origin_url));
772 } else {
773 LOG(WARNING) << "Skipping creation of SpdyProxy auth handler since "
774 << "authorized origin is invalid: "
775 << spdyproxy_origin_;
776 }
777 }
778
779 return registry_factory.release();
[email protected]eb3cac72010-02-26 21:07:45780}
781
[email protected]d6f37fc2011-02-13 23:58:41782void IOThread::ClearHostCache() {
783 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
784
[email protected]489d1a82011-10-12 03:09:11785 net::HostCache* host_cache = globals_->host_resolver->GetHostCache();
786 if (host_cache)
787 host_cache->clear();
[email protected]0ac83682010-01-22 17:46:27788}
[email protected]db0e86dd2011-03-16 14:47:21789
[email protected]f9cf5572012-12-04 15:52:09790void IOThread::InitializeNetworkSessionParams(
791 net::HttpNetworkSession::Params* params) {
792 params->host_resolver = globals_->host_resolver.get();
793 params->cert_verifier = globals_->cert_verifier.get();
794 params->server_bound_cert_service =
795 globals_->system_server_bound_cert_service.get();
796 params->transport_security_state = globals_->transport_security_state.get();
797 params->ssl_config_service = globals_->ssl_config_service.get();
798 params->http_auth_handler_factory = globals_->http_auth_handler_factory.get();
799 params->http_server_properties = globals_->http_server_properties.get();
800 params->network_delegate = globals_->system_network_delegate.get();
801 params->host_mapping_rules = globals_->host_mapping_rules.get();
802 params->ignore_certificate_errors = globals_->ignore_certificate_errors;
803 params->http_pipelining_enabled = globals_->http_pipelining_enabled;
804 params->testing_fixed_http_port = globals_->testing_fixed_http_port;
805 params->testing_fixed_https_port = globals_->testing_fixed_https_port;
806
807 globals_->max_spdy_sessions_per_domain.CopyToIfSet(
808 &params->max_spdy_sessions_per_domain);
809 globals_->initial_max_spdy_concurrent_streams.CopyToIfSet(
810 &params->spdy_initial_max_concurrent_streams);
811 globals_->max_spdy_concurrent_streams_limit.CopyToIfSet(
812 &params->spdy_max_concurrent_streams_limit);
813 globals_->force_spdy_single_domain.CopyToIfSet(
814 &params->force_spdy_single_domain);
815 globals_->enable_spdy_ip_pooling.CopyToIfSet(
816 &params->enable_spdy_ip_pooling);
817 globals_->enable_spdy_credential_frames.CopyToIfSet(
818 &params->enable_spdy_credential_frames);
819 globals_->enable_spdy_compression.CopyToIfSet(
820 &params->enable_spdy_compression);
821 globals_->enable_spdy_ping_based_connection_checking.CopyToIfSet(
822 &params->enable_spdy_ping_based_connection_checking);
823 globals_->spdy_default_protocol.CopyToIfSet(
824 &params->spdy_default_protocol);
[email protected]f1e97e92012-12-16 04:53:25825 globals_->origin_port_to_force_quic_on.CopyToIfSet(
826 &params->origin_port_to_force_quic_on);
[email protected]f9cf5572012-12-04 15:52:09827}
828
[email protected]4d45a6de2011-05-13 05:20:18829net::SSLConfigService* IOThread::GetSSLConfigService() {
830 return ssl_config_service_manager_->Get();
831}
832
[email protected]b09f76d62011-12-07 01:51:06833void IOThread::ChangedToOnTheRecordOnIOThread() {
834 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
835
836 // Clear the host cache to avoid showing entries from the OTR session
837 // in about:net-internals.
838 ClearHostCache();
[email protected]b09f76d62011-12-07 01:51:06839}
840
[email protected]db0e86dd2011-03-16 14:47:21841void IOThread::InitSystemRequestContext() {
[email protected]addb3242011-06-13 21:39:16842 if (system_url_request_context_getter_)
843 return;
[email protected]63e26822011-07-16 19:07:35844 // If we're in unit_tests, IOThread may not be run.
[email protected]dd483702011-12-02 14:47:42845 if (!BrowserThread::IsMessageLoopValid(BrowserThread::IO))
[email protected]63e26822011-07-16 19:07:35846 return;
[email protected]6f96cbcb2011-11-04 02:26:07847 ChromeProxyConfigService* proxy_config_service =
[email protected]d461ed22013-01-18 03:18:56848 ProxyServiceFactory::CreateProxyConfigService();
[email protected]6f96cbcb2011-11-04 02:26:07849 system_proxy_config_service_.reset(proxy_config_service);
[email protected]d461ed22013-01-18 03:18:56850 pref_proxy_config_tracker_->SetChromeProxyConfigService(proxy_config_service);
[email protected]addb3242011-06-13 21:39:16851 system_url_request_context_getter_ =
852 new SystemURLRequestContextGetter(this);
[email protected]2e5b60a22011-11-28 15:56:41853 // Safe to post an unretained this pointer, since IOThread is
854 // guaranteed to outlive the IO BrowserThread.
[email protected]dd483702011-12-02 14:47:42855 BrowserThread::PostTask(
856 BrowserThread::IO,
857 FROM_HERE,
858 base::Bind(&IOThread::InitSystemRequestContextOnIOThread,
859 base::Unretained(this)));
[email protected]addb3242011-06-13 21:39:16860}
861
862void IOThread::InitSystemRequestContextOnIOThread() {
[email protected]db0e86dd2011-03-16 14:47:21863 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]6104ea5d2011-04-27 21:37:12864 DCHECK(!globals_->system_proxy_service.get());
[email protected]db0e86dd2011-03-16 14:47:21865 DCHECK(system_proxy_config_service_.get());
866
867 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
[email protected]6104ea5d2011-04-27 21:37:12868 globals_->system_proxy_service.reset(
[email protected]db0e86dd2011-03-16 14:47:21869 ProxyServiceFactory::CreateProxyService(
870 net_log_,
[email protected]ef2bf422012-05-11 03:27:09871 globals_->proxy_script_fetcher_context.get(),
[email protected]db0e86dd2011-03-16 14:47:21872 system_proxy_config_service_.release(),
[email protected]6104ea5d2011-04-27 21:37:12873 command_line));
[email protected]c2dad292012-09-07 21:27:35874
[email protected]db0e86dd2011-03-16 14:47:21875 net::HttpNetworkSession::Params system_params;
[email protected]f9cf5572012-12-04 15:52:09876 InitializeNetworkSessionParams(&system_params);
[email protected]db0e86dd2011-03-16 14:47:21877 system_params.net_log = net_log_;
[email protected]27c253802012-11-30 08:18:12878 system_params.proxy_service = globals_->system_proxy_service.get();
[email protected]c2dad292012-09-07 21:27:35879
[email protected]db0e86dd2011-03-16 14:47:21880 globals_->system_http_transaction_factory.reset(
881 new net::HttpNetworkLayer(
882 new net::HttpNetworkSession(system_params)));
[email protected]933bc5c62011-04-12 19:08:02883 globals_->system_ftp_transaction_factory.reset(
884 new net::FtpNetworkLayer(globals_->host_resolver.get()));
[email protected]ef2bf422012-05-11 03:27:09885 globals_->system_request_context.reset(
886 ConstructSystemRequestContext(globals_, net_log_));
[email protected]d24fc3a02012-02-11 02:08:34887
888 sdch_manager_->set_sdch_fetcher(
889 new SdchDictionaryFetcher(system_url_request_context_getter_.get()));
[email protected]db0e86dd2011-03-16 14:47:21890}
[email protected]fa4b6c32012-11-26 23:02:39891
892void IOThread::UpdateDnsClientEnabled() {
893 globals()->host_resolver->SetDnsClientEnabled(*dns_client_enabled_);
894}