1 // Copyright (c) 2011 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" 6 7 #include <vector> 8 9 #include "base/command_line.h" 10 #include "base/debug/leak_tracker.h" 11 #include "base/logging.h" 12 #include "base/metrics/field_trial.h" 13 #include "base/stl_util-inl.h" 14 #include "base/string_number_conversions.h" 15 #include "base/string_split.h" 16 #include "base/string_util.h" 17 #include "base/threading/thread_restrictions.h" 18 #include "chrome/browser/browser_process.h" 19 #include "chrome/browser/extensions/extension_event_router_forwarder.h" 20 #include "chrome/browser/net/chrome_network_delegate.h" 21 #include "chrome/browser/net/chrome_net_log.h" 22 #include "chrome/browser/net/chrome_url_request_context.h" 23 #include "chrome/browser/net/connect_interceptor.h" 24 #include "chrome/browser/net/passive_log_collector.h" 25 #include "chrome/browser/net/predictor_api.h" 26 #include "chrome/browser/net/pref_proxy_config_service.h" 27 #include "chrome/browser/net/proxy_service_factory.h" 28 #include "chrome/browser/prefs/pref_service.h" 29 #include "chrome/common/chrome_switches.h" 30 #include "chrome/common/net/raw_host_resolver_proc.h" 31 #include "chrome/common/net/url_fetcher.h" 32 #include "chrome/common/pref_names.h" 33 #include "content/browser/browser_thread.h" 34 #include "content/browser/gpu_process_host.h" 35 #include "content/browser/in_process_webkit/indexed_db_key_utility_client.h" 36 #include "net/base/cert_verifier.h" 37 #include "net/base/cookie_monster.h" 38 #include "net/base/dnsrr_resolver.h" 39 #include "net/base/host_cache.h" 40 #include "net/base/host_resolver.h" 41 #include "net/base/host_resolver_impl.h" 42 #include "net/base/mapped_host_resolver.h" 43 #include "net/base/net_util.h" 44 #include "net/proxy/proxy_config_service.h" 45 #include "net/ftp/ftp_network_layer.h" 46 #include "net/http/http_auth_filter.h" 47 #include "net/http/http_auth_handler_factory.h" 48 #include "net/http/http_network_layer.h" 49 #include "net/http/http_network_session.h" 50 #if defined(USE_NSS) 51 #include "net/ocsp/nss_ocsp.h" 52 #endif // defined(USE_NSS) 53 #include "net/proxy/proxy_script_fetcher_impl.h" 54 #include "webkit/glue/webkit_glue.h" 55 56 namespace { 57 58 // Custom URLRequestContext used by requests which aren't associated with a 59 // particular profile. We need to use a subclass of URLRequestContext in order 60 // to provide the correct User-Agent. 61 class URLRequestContextWithUserAgent : public net::URLRequestContext { 62 public: 63 virtual const std::string& GetUserAgent( 64 const GURL& url) const OVERRIDE { 65 return webkit_glue::GetUserAgent(url); 66 } 67 }; 68 69 net::HostResolver* CreateGlobalHostResolver(net::NetLog* net_log) { 70 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 71 72 size_t parallelism = net::HostResolver::kDefaultParallelism; 73 74 // Use the concurrency override from the command-line, if any. 75 if (command_line.HasSwitch(switches::kHostResolverParallelism)) { 76 std::string s = 77 command_line.GetSwitchValueASCII(switches::kHostResolverParallelism); 78 79 // Parse the switch (it should be a positive integer formatted as decimal). 80 int n; 81 if (base::StringToInt(s, &n) && n > 0) { 82 parallelism = static_cast<size_t>(n); 83 } else { 84 LOG(ERROR) << "Invalid switch for host resolver parallelism: " << s; 85 } 86 } else { 87 // Set up a field trial to see what impact the total number of concurrent 88 // resolutions have on DNS resolutions. 89 base::FieldTrial::Probability kDivisor = 1000; 90 // For each option (i.e., non-default), we have a fixed probability. 91 base::FieldTrial::Probability kProbabilityPerGroup = 100; // 10%. 92 93 // After June 30, 2011 builds, it will always be in default group 94 // (parallel_default). 95 scoped_refptr<base::FieldTrial> trial( 96 new base::FieldTrial( 97 "DnsParallelism", kDivisor, "parallel_default", 2011, 6, 30)); 98 99 // List options with different counts. 100 // Firefox limits total to 8 in parallel, and default is currently 50. 101 int parallel_6 = trial->AppendGroup("parallel_6", kProbabilityPerGroup); 102 int parallel_7 = trial->AppendGroup("parallel_7", kProbabilityPerGroup); 103 int parallel_8 = trial->AppendGroup("parallel_8", kProbabilityPerGroup); 104 int parallel_9 = trial->AppendGroup("parallel_9", kProbabilityPerGroup); 105 int parallel_10 = trial->AppendGroup("parallel_10", kProbabilityPerGroup); 106 int parallel_14 = trial->AppendGroup("parallel_14", kProbabilityPerGroup); 107 int parallel_20 = trial->AppendGroup("parallel_20", kProbabilityPerGroup); 108 109 if (trial->group() == parallel_6) 110 parallelism = 6; 111 else if (trial->group() == parallel_7) 112 parallelism = 7; 113 else if (trial->group() == parallel_8) 114 parallelism = 8; 115 else if (trial->group() == parallel_9) 116 parallelism = 9; 117 else if (trial->group() == parallel_10) 118 parallelism = 10; 119 else if (trial->group() == parallel_14) 120 parallelism = 14; 121 else if (trial->group() == parallel_20) 122 parallelism = 20; 123 } 124 125 // Use the specified DNS server for doing raw resolutions if requested 126 // from the command-line. 127 scoped_refptr<net::HostResolverProc> resolver_proc; 128 if (command_line.HasSwitch(switches::kDnsServer)) { 129 std::string dns_ip_string = 130 command_line.GetSwitchValueASCII(switches::kDnsServer); 131 net::IPAddressNumber dns_ip_number; 132 if (net::ParseIPLiteralToNumber(dns_ip_string, &dns_ip_number)) { 133 resolver_proc = 134 new chrome_common_net::RawHostResolverProc(dns_ip_number, NULL); 135 } else { 136 LOG(ERROR) << "Invalid IP address specified for --dns-server: " 137 << dns_ip_string; 138 } 139 } 140 141 net::HostResolver* global_host_resolver = 142 net::CreateSystemHostResolver(parallelism, resolver_proc.get(), net_log); 143 144 // Determine if we should disable IPv6 support. 145 if (!command_line.HasSwitch(switches::kEnableIPv6)) { 146 if (command_line.HasSwitch(switches::kDisableIPv6)) { 147 global_host_resolver->SetDefaultAddressFamily(net::ADDRESS_FAMILY_IPV4); 148 } else { 149 net::HostResolverImpl* host_resolver_impl = 150 global_host_resolver->GetAsHostResolverImpl(); 151 if (host_resolver_impl != NULL) { 152 // Use probe to decide if support is warranted. 153 host_resolver_impl->ProbeIPv6Support(); 154 } 155 } 156 } 157 158 // If hostname remappings were specified on the command-line, layer these 159 // rules on top of the real host resolver. This allows forwarding all requests 160 // through a designated test server. 161 if (!command_line.HasSwitch(switches::kHostResolverRules)) 162 return global_host_resolver; 163 164 net::MappedHostResolver* remapped_resolver = 165 new net::MappedHostResolver(global_host_resolver); 166 remapped_resolver->SetRulesFromString( 167 command_line.GetSwitchValueASCII(switches::kHostResolverRules)); 168 return remapped_resolver; 169 } 170 171 class LoggingNetworkChangeObserver 172 : public net::NetworkChangeNotifier::IPAddressObserver { 173 public: 174 // |net_log| must remain valid throughout our lifetime. 175 explicit LoggingNetworkChangeObserver(net::NetLog* net_log) 176 : net_log_(net_log) { 177 net::NetworkChangeNotifier::AddIPAddressObserver(this); 178 } 179 180 ~LoggingNetworkChangeObserver() { 181 net::NetworkChangeNotifier::RemoveIPAddressObserver(this); 182 } 183 184 virtual void OnIPAddressChanged() { 185 VLOG(1) << "Observed a change to the network IP addresses"; 186 187 net_log_->AddEntry(net::NetLog::TYPE_NETWORK_IP_ADDRESSES_CHANGED, 188 base::TimeTicks::Now(), 189 net::NetLog::Source(), 190 net::NetLog::PHASE_NONE, 191 NULL); 192 } 193 194 private: 195 net::NetLog* net_log_; 196 DISALLOW_COPY_AND_ASSIGN(LoggingNetworkChangeObserver); 197 }; 198 199 scoped_refptr<net::URLRequestContext> 200 ConstructProxyScriptFetcherContext(IOThread::Globals* globals, 201 net::NetLog* net_log) { 202 scoped_refptr<net::URLRequestContext> context( 203 new URLRequestContextWithUserAgent); 204 context->set_net_log(net_log); 205 context->set_host_resolver(globals->host_resolver.get()); 206 context->set_cert_verifier(globals->cert_verifier.get()); 207 context->set_dnsrr_resolver(globals->dnsrr_resolver.get()); 208 context->set_http_auth_handler_factory( 209 globals->http_auth_handler_factory.get()); 210 context->set_proxy_service(globals->proxy_script_fetcher_proxy_service.get()); 211 context->set_http_transaction_factory( 212 globals->proxy_script_fetcher_http_transaction_factory.get()); 213 context->set_ftp_transaction_factory( 214 globals->proxy_script_fetcher_ftp_transaction_factory.get()); 215 // In-memory cookie store. 216 context->set_cookie_store(new net::CookieMonster(NULL, NULL)); 217 context->set_network_delegate(globals->system_network_delegate.get()); 218 return context; 219 } 220 221 scoped_refptr<net::URLRequestContext> 222 ConstructSystemRequestContext(IOThread::Globals* globals, 223 net::NetLog* net_log) { 224 scoped_refptr<net::URLRequestContext> context( 225 new URLRequestContextWithUserAgent); 226 context->set_net_log(net_log); 227 context->set_host_resolver(globals->host_resolver.get()); 228 context->set_cert_verifier(globals->cert_verifier.get()); 229 context->set_dnsrr_resolver(globals->dnsrr_resolver.get()); 230 context->set_http_auth_handler_factory( 231 globals->http_auth_handler_factory.get()); 232 context->set_proxy_service(globals->system_proxy_service.get()); 233 context->set_http_transaction_factory( 234 globals->system_http_transaction_factory.get()); 235 context->set_ftp_transaction_factory( 236 globals->system_ftp_transaction_factory.get()); 237 // In-memory cookie store. 238 context->set_cookie_store(new net::CookieMonster(NULL, NULL)); 239 return context; 240 } 241 242 } // namespace 243 244 class SystemURLRequestContextGetter : public net::URLRequestContextGetter { 245 public: 246 explicit SystemURLRequestContextGetter(IOThread* io_thread); 247 virtual ~SystemURLRequestContextGetter(); 248 249 // Implementation for net::UrlRequestContextGetter. 250 virtual net::URLRequestContext* GetURLRequestContext(); 251 virtual scoped_refptr<base::MessageLoopProxy> GetIOMessageLoopProxy() const; 252 253 private: 254 IOThread* const io_thread_; // Weak pointer, owned by BrowserProcess. 255 scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_; 256 257 base::debug::LeakTracker<SystemURLRequestContextGetter> leak_tracker_; 258 }; 259 260 SystemURLRequestContextGetter::SystemURLRequestContextGetter( 261 IOThread* io_thread) 262 : io_thread_(io_thread), 263 io_message_loop_proxy_(io_thread->message_loop_proxy()) { 264 } 265 266 SystemURLRequestContextGetter::~SystemURLRequestContextGetter() {} 267 268 net::URLRequestContext* SystemURLRequestContextGetter::GetURLRequestContext() { 269 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 270 271 if (!io_thread_->globals()->system_request_context) 272 io_thread_->InitSystemRequestContext(); 273 274 return io_thread_->globals()->system_request_context; 275 } 276 277 scoped_refptr<base::MessageLoopProxy> 278 SystemURLRequestContextGetter::GetIOMessageLoopProxy() const { 279 return io_message_loop_proxy_; 280 } 281 282 // The IOThread object must outlive any tasks posted to the IO thread before the 283 // Quit task. 284 DISABLE_RUNNABLE_METHOD_REFCOUNT(IOThread); 285 286 IOThread::Globals::Globals() {} 287 288 IOThread::Globals::~Globals() {} 289 290 // |local_state| is passed in explicitly in order to (1) reduce implicit 291 // dependencies and (2) make IOThread more flexible for testing. 292 IOThread::IOThread( 293 PrefService* local_state, 294 ChromeNetLog* net_log, 295 ExtensionEventRouterForwarder* extension_event_router_forwarder) 296 : BrowserProcessSubThread(BrowserThread::IO), 297 net_log_(net_log), 298 extension_event_router_forwarder_(extension_event_router_forwarder), 299 globals_(NULL), 300 speculative_interceptor_(NULL), 301 predictor_(NULL) { 302 // We call RegisterPrefs() here (instead of inside browser_prefs.cc) to make 303 // sure that everything is initialized in the right order. 304 RegisterPrefs(local_state); 305 auth_schemes_ = local_state->GetString(prefs::kAuthSchemes); 306 negotiate_disable_cname_lookup_ = local_state->GetBoolean( 307 prefs::kDisableAuthNegotiateCnameLookup); 308 negotiate_enable_port_ = local_state->GetBoolean( 309 prefs::kEnableAuthNegotiatePort); 310 auth_server_whitelist_ = local_state->GetString(prefs::kAuthServerWhitelist); 311 auth_delegate_whitelist_ = local_state->GetString( 312 prefs::kAuthNegotiateDelegateWhitelist); 313 gssapi_library_name_ = local_state->GetString(prefs::kGSSAPILibraryName); 314 pref_proxy_config_tracker_ = new PrefProxyConfigTracker(local_state); 315 ChromeNetworkDelegate::InitializeReferrersEnabled(&system_enable_referrers_, 316 local_state); 317 } 318 319 IOThread::~IOThread() { 320 if (pref_proxy_config_tracker_) 321 pref_proxy_config_tracker_->DetachFromPrefService(); 322 // We cannot rely on our base class to stop the thread since we want our 323 // CleanUp function to run. 324 Stop(); 325 DCHECK(!globals_); 326 } 327 328 IOThread::Globals* IOThread::globals() { 329 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 330 return globals_; 331 } 332 333 ChromeNetLog* IOThread::net_log() { 334 return net_log_; 335 } 336 337 void IOThread::InitNetworkPredictor( 338 bool prefetching_enabled, 339 base::TimeDelta max_dns_queue_delay, 340 size_t max_speculative_parallel_resolves, 341 const chrome_common_net::UrlList& startup_urls, 342 ListValue* referral_list, 343 bool preconnect_enabled) { 344 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 345 message_loop()->PostTask( 346 FROM_HERE, 347 NewRunnableMethod( 348 this, 349 &IOThread::InitNetworkPredictorOnIOThread, 350 prefetching_enabled, max_dns_queue_delay, 351 max_speculative_parallel_resolves, 352 startup_urls, referral_list, preconnect_enabled)); 353 } 354 355 void IOThread::RegisterURLRequestContextGetter( 356 ChromeURLRequestContextGetter* url_request_context_getter) { 357 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 358 std::list<ChromeURLRequestContextGetter*>::const_iterator it = 359 std::find(url_request_context_getters_.begin(), 360 url_request_context_getters_.end(), 361 url_request_context_getter); 362 DCHECK(it == url_request_context_getters_.end()); 363 url_request_context_getters_.push_back(url_request_context_getter); 364 } 365 366 void IOThread::UnregisterURLRequestContextGetter( 367 ChromeURLRequestContextGetter* url_request_context_getter) { 368 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 369 std::list<ChromeURLRequestContextGetter*>::iterator it = 370 std::find(url_request_context_getters_.begin(), 371 url_request_context_getters_.end(), 372 url_request_context_getter); 373 DCHECK(it != url_request_context_getters_.end()); 374 // This does not scale, but we shouldn't have many URLRequestContextGetters in 375 // the first place, so this should be fine. 376 url_request_context_getters_.erase(it); 377 } 378 379 void IOThread::ChangedToOnTheRecord() { 380 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 381 message_loop()->PostTask( 382 FROM_HERE, 383 NewRunnableMethod( 384 this, 385 &IOThread::ChangedToOnTheRecordOnIOThread)); 386 } 387 388 net::URLRequestContextGetter* IOThread::system_url_request_context_getter() { 389 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 390 if (!system_url_request_context_getter_) { 391 system_proxy_config_service_.reset( 392 ProxyServiceFactory::CreateProxyConfigService( 393 pref_proxy_config_tracker_)); 394 system_url_request_context_getter_ = 395 new SystemURLRequestContextGetter(this); 396 } 397 return system_url_request_context_getter_; 398 } 399 400 void IOThread::ClearNetworkingHistory() { 401 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 402 ClearHostCache(); 403 // Discard acrued data used to speculate in the future. 404 chrome_browser_net::DiscardInitialNavigationHistory(); 405 if (predictor_) 406 predictor_->DiscardAllResults(); 407 } 408 409 void IOThread::Init() { 410 // Though this thread is called the "IO" thread, it actually just routes 411 // messages around; it shouldn't be allowed to perform any blocking disk I/O. 412 base::ThreadRestrictions::SetIOAllowed(false); 413 414 BrowserProcessSubThread::Init(); 415 416 DCHECK_EQ(MessageLoop::TYPE_IO, message_loop()->type()); 417 418 #if defined(USE_NSS) 419 net::SetMessageLoopForOCSP(); 420 #endif // defined(USE_NSS) 421 422 DCHECK(!globals_); 423 globals_ = new Globals; 424 425 // Add an observer that will emit network change events to the ChromeNetLog. 426 // Assuming NetworkChangeNotifier dispatches in FIFO order, we should be 427 // logging the network change before other IO thread consumers respond to it. 428 network_change_observer_.reset( 429 new LoggingNetworkChangeObserver(net_log_)); 430 431 globals_->extension_event_router_forwarder = 432 extension_event_router_forwarder_; 433 globals_->system_network_delegate.reset(new ChromeNetworkDelegate( 434 extension_event_router_forwarder_, 435 Profile::kInvalidProfileId, 436 &system_enable_referrers_, 437 NULL)); 438 globals_->host_resolver.reset( 439 CreateGlobalHostResolver(net_log_)); 440 globals_->cert_verifier.reset(new net::CertVerifier); 441 globals_->dnsrr_resolver.reset(new net::DnsRRResolver); 442 // TODO(willchan): Use the real SSLConfigService. 443 globals_->ssl_config_service = 444 net::SSLConfigService::CreateSystemSSLConfigService(); 445 globals_->http_auth_handler_factory.reset(CreateDefaultAuthHandlerFactory( 446 globals_->host_resolver.get())); 447 // For the ProxyScriptFetcher, we use a direct ProxyService. 448 globals_->proxy_script_fetcher_proxy_service = 449 net::ProxyService::CreateDirectWithNetLog(net_log_); 450 net::HttpNetworkSession::Params session_params; 451 session_params.host_resolver = globals_->host_resolver.get(); 452 session_params.cert_verifier = globals_->cert_verifier.get(); 453 session_params.proxy_service = 454 globals_->proxy_script_fetcher_proxy_service.get(); 455 session_params.http_auth_handler_factory = 456 globals_->http_auth_handler_factory.get(); 457 session_params.network_delegate = globals_->system_network_delegate.get(); 458 session_params.net_log = net_log_; 459 session_params.ssl_config_service = globals_->ssl_config_service; 460 scoped_refptr<net::HttpNetworkSession> network_session( 461 new net::HttpNetworkSession(session_params)); 462 globals_->proxy_script_fetcher_http_transaction_factory.reset( 463 new net::HttpNetworkLayer(network_session)); 464 globals_->proxy_script_fetcher_ftp_transaction_factory.reset( 465 new net::FtpNetworkLayer(globals_->host_resolver.get())); 466 467 scoped_refptr<net::URLRequestContext> proxy_script_fetcher_context = 468 ConstructProxyScriptFetcherContext(globals_, net_log_); 469 globals_->proxy_script_fetcher_context = proxy_script_fetcher_context; 470 } 471 472 void IOThread::CleanUp() { 473 // Step 1: Kill all things that might be holding onto 474 // net::URLRequest/net::URLRequestContexts. 475 476 #if defined(USE_NSS) 477 net::ShutdownOCSP(); 478 #endif // defined(USE_NSS) 479 480 // Destroy all URLRequests started by URLFetchers. 481 URLFetcher::CancelAll(); 482 483 IndexedDBKeyUtilityClient::Shutdown(); 484 485 // If any child processes are still running, terminate them and 486 // and delete the BrowserChildProcessHost instances to release whatever 487 // IO thread only resources they are referencing. 488 BrowserChildProcessHost::TerminateAll(); 489 490 std::list<ChromeURLRequestContextGetter*> url_request_context_getters; 491 url_request_context_getters.swap(url_request_context_getters_); 492 for (std::list<ChromeURLRequestContextGetter*>::iterator it = 493 url_request_context_getters.begin(); 494 it != url_request_context_getters.end(); ++it) { 495 ChromeURLRequestContextGetter* getter = *it; 496 // Stop all pending certificate provenance check uploads 497 net::DnsCertProvenanceChecker* checker = 498 getter->GetURLRequestContext()->dns_cert_checker(); 499 if (checker) 500 checker->Shutdown(); 501 getter->ReleaseURLRequestContext(); 502 } 503 504 system_url_request_context_getter_ = NULL; 505 506 // Step 2: Release objects that the net::URLRequestContext could have been 507 // pointing to. 508 509 // This must be reset before the ChromeNetLog is destroyed. 510 network_change_observer_.reset(); 511 512 // Not initialized in Init(). May not be initialized. 513 if (predictor_) { 514 predictor_->Shutdown(); 515 516 // TODO(willchan): Stop reference counting Predictor. It's owned by 517 // IOThread now. 518 predictor_->Release(); 519 predictor_ = NULL; 520 chrome_browser_net::FreePredictorResources(); 521 } 522 523 // Deletion will unregister this interceptor. 524 delete speculative_interceptor_; 525 speculative_interceptor_ = NULL; 526 527 // TODO(eroman): hack for http://crbug.com/15513 528 if (globals_->host_resolver->GetAsHostResolverImpl()) { 529 globals_->host_resolver.get()->GetAsHostResolverImpl()->Shutdown(); 530 } 531 532 system_proxy_config_service_.reset(); 533 534 delete globals_; 535 globals_ = NULL; 536 537 // net::URLRequest instances must NOT outlive the IO thread. 538 base::debug::LeakTracker<net::URLRequest>::CheckForLeaks(); 539 540 base::debug::LeakTracker<SystemURLRequestContextGetter>::CheckForLeaks(); 541 542 // This will delete the |notification_service_|. Make sure it's done after 543 // anything else can reference it. 544 BrowserProcessSubThread::CleanUp(); 545 } 546 547 // static 548 void IOThread::RegisterPrefs(PrefService* local_state) { 549 local_state->RegisterStringPref(prefs::kAuthSchemes, 550 "basic,digest,ntlm,negotiate"); 551 local_state->RegisterBooleanPref(prefs::kDisableAuthNegotiateCnameLookup, 552 false); 553 local_state->RegisterBooleanPref(prefs::kEnableAuthNegotiatePort, false); 554 local_state->RegisterStringPref(prefs::kAuthServerWhitelist, ""); 555 local_state->RegisterStringPref(prefs::kAuthNegotiateDelegateWhitelist, ""); 556 local_state->RegisterStringPref(prefs::kGSSAPILibraryName, ""); 557 local_state->RegisterBooleanPref(prefs::kEnableReferrers, true); 558 } 559 560 net::HttpAuthHandlerFactory* IOThread::CreateDefaultAuthHandlerFactory( 561 net::HostResolver* resolver) { 562 net::HttpAuthFilterWhitelist* auth_filter_default_credentials = NULL; 563 if (!auth_server_whitelist_.empty()) { 564 auth_filter_default_credentials = 565 new net::HttpAuthFilterWhitelist(auth_server_whitelist_); 566 } 567 net::HttpAuthFilterWhitelist* auth_filter_delegate = NULL; 568 if (!auth_delegate_whitelist_.empty()) { 569 auth_filter_delegate = 570 new net::HttpAuthFilterWhitelist(auth_delegate_whitelist_); 571 } 572 globals_->url_security_manager.reset( 573 net::URLSecurityManager::Create(auth_filter_default_credentials, 574 auth_filter_delegate)); 575 std::vector<std::string> supported_schemes; 576 base::SplitString(auth_schemes_, ',', &supported_schemes); 577 578 return net::HttpAuthHandlerRegistryFactory::Create( 579 supported_schemes, 580 globals_->url_security_manager.get(), 581 resolver, 582 gssapi_library_name_, 583 negotiate_disable_cname_lookup_, 584 negotiate_enable_port_); 585 } 586 587 void IOThread::InitNetworkPredictorOnIOThread( 588 bool prefetching_enabled, 589 base::TimeDelta max_dns_queue_delay, 590 size_t max_speculative_parallel_resolves, 591 const chrome_common_net::UrlList& startup_urls, 592 ListValue* referral_list, 593 bool preconnect_enabled) { 594 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 595 CHECK(!predictor_); 596 597 chrome_browser_net::EnablePredictor(prefetching_enabled); 598 599 predictor_ = new chrome_browser_net::Predictor( 600 globals_->host_resolver.get(), 601 max_dns_queue_delay, 602 max_speculative_parallel_resolves, 603 preconnect_enabled); 604 predictor_->AddRef(); 605 606 // Speculative_interceptor_ is used to predict subresource usage. 607 DCHECK(!speculative_interceptor_); 608 speculative_interceptor_ = new chrome_browser_net::ConnectInterceptor; 609 610 FinalizePredictorInitialization(predictor_, startup_urls, referral_list); 611 } 612 613 void IOThread::ChangedToOnTheRecordOnIOThread() { 614 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 615 616 if (predictor_) { 617 // Destroy all evidence of our OTR session. 618 // Note: OTR mode never saves InitialNavigationHistory data. 619 predictor_->Predictor::DiscardAllResults(); 620 } 621 622 // Clear the host cache to avoid showing entries from the OTR session 623 // in about:net-internals. 624 ClearHostCache(); 625 626 // Clear all of the passively logged data. 627 // TODO(eroman): this is a bit heavy handed, really all we need to do is 628 // clear the data pertaining to incognito context. 629 net_log_->ClearAllPassivelyCapturedEvents(); 630 } 631 632 void IOThread::ClearHostCache() { 633 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 634 635 if (globals_->host_resolver->GetAsHostResolverImpl()) { 636 net::HostCache* host_cache = 637 globals_->host_resolver.get()->GetAsHostResolverImpl()->cache(); 638 if (host_cache) 639 host_cache->clear(); 640 } 641 } 642 643 void IOThread::InitSystemRequestContext() { 644 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 645 DCHECK(!globals_->system_proxy_service); 646 DCHECK(system_proxy_config_service_.get()); 647 648 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 649 globals_->system_proxy_service = 650 ProxyServiceFactory::CreateProxyService( 651 net_log_, 652 globals_->proxy_script_fetcher_context, 653 system_proxy_config_service_.release(), 654 command_line); 655 net::HttpNetworkSession::Params system_params; 656 system_params.host_resolver = globals_->host_resolver.get(); 657 system_params.cert_verifier = globals_->cert_verifier.get(); 658 system_params.dnsrr_resolver = globals_->dnsrr_resolver.get(); 659 system_params.dns_cert_checker = NULL; 660 system_params.ssl_host_info_factory = NULL; 661 system_params.proxy_service = globals_->system_proxy_service.get(); 662 system_params.ssl_config_service = globals_->ssl_config_service.get(); 663 system_params.http_auth_handler_factory = 664 globals_->http_auth_handler_factory.get(); 665 system_params.network_delegate = globals_->system_network_delegate.get(); 666 system_params.net_log = net_log_; 667 globals_->system_http_transaction_factory.reset( 668 new net::HttpNetworkLayer( 669 new net::HttpNetworkSession(system_params))); 670 globals_->system_ftp_transaction_factory.reset( 671 new net::FtpNetworkLayer(globals_->host_resolver.get())); 672 globals_->system_request_context = 673 ConstructSystemRequestContext(globals_, net_log_); 674 } 675