// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "chrome/browser/profiles/profile_io_data.h" #include #include "base/basictypes.h" #include "base/bind.h" #include "base/bind_helpers.h" #include "base/command_line.h" #include "base/compiler_specific.h" #include "base/logging.h" #include "base/stl_util.h" #include "base/string_number_conversions.h" #include "base/string_util.h" #include "base/stringprintf.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/net/about_protocol_handler.h" #include "chrome/browser/content_settings/cookie_settings.h" #include "chrome/browser/content_settings/host_content_settings_map.h" #include "chrome/browser/custom_handlers/protocol_handler_registry.h" #include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h" #include "chrome/browser/download/download_service.h" #include "chrome/browser/download/download_service_factory.h" #include "chrome/browser/extensions/extension_info_map.h" #include "chrome/browser/extensions/extension_protocols.h" #include "chrome/browser/extensions/extension_resource_protocols.h" #include "chrome/browser/extensions/extension_system.h" #include "chrome/browser/io_thread.h" #include "chrome/browser/net/chrome_cookie_notification_details.h" #include "chrome/browser/net/chrome_fraudulent_certificate_reporter.h" #include "chrome/browser/net/chrome_net_log.h" #include "chrome/browser/net/chrome_network_delegate.h" #include "chrome/browser/net/http_server_properties_manager.h" #include "chrome/browser/net/load_time_stats.h" #include "chrome/browser/net/proxy_service_factory.h" #include "chrome/browser/net/resource_prefetch_predictor_observer.h" #include "chrome/browser/net/transport_security_persister.h" #include "chrome/browser/notifications/desktop_notification_service_factory.h" #include "chrome/browser/policy/url_blacklist_manager.h" #include "chrome/browser/predictors/resource_prefetch_predictor.h" #include "chrome/browser/predictors/resource_prefetch_predictor_factory.h" #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/ui/webui/chrome_url_data_manager_backend.h" #include "chrome/common/chrome_notification_types.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/host_zoom_map.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/resource_context.h" #include "net/base/server_bound_cert_service.h" #include "net/cookies/canonical_cookie.h" #include "net/cookies/cookie_monster.h" #include "net/http/http_transaction_factory.h" #include "net/http/http_util.h" #include "net/proxy/proxy_config_service_fixed.h" #include "net/proxy/proxy_script_fetcher_impl.h" #include "net/proxy/proxy_service.h" #include "net/url_request/data_protocol_handler.h" #include "net/url_request/file_protocol_handler.h" #include "net/url_request/ftp_protocol_handler.h" #include "net/url_request/url_request.h" #if !defined(OS_ANDROID) #include "chrome/browser/managed_mode.h" #endif #if defined(OS_CHROMEOS) #include "chrome/browser/chromeos/gdata/drive_protocol_handler.h" #include "chrome/browser/chromeos/gview_request_interceptor.h" #include "chrome/browser/chromeos/proxy_config_service_impl.h" #include "chrome/browser/chromeos/settings/cros_settings.h" #include "chrome/browser/chromeos/settings/cros_settings_names.h" #endif // defined(OS_CHROMEOS) using content::BrowserContext; using content::BrowserThread; using content::ResourceContext; namespace { // ---------------------------------------------------------------------------- // CookieMonster::Delegate implementation // ---------------------------------------------------------------------------- class ChromeCookieMonsterDelegate : public net::CookieMonster::Delegate { public: explicit ChromeCookieMonsterDelegate( const base::Callback& profile_getter) : profile_getter_(profile_getter) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); } // net::CookieMonster::Delegate implementation. virtual void OnCookieChanged( const net::CanonicalCookie& cookie, bool removed, net::CookieMonster::Delegate::ChangeCause cause) { BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, base::Bind(&ChromeCookieMonsterDelegate::OnCookieChangedAsyncHelper, this, cookie, removed, cause)); } private: virtual ~ChromeCookieMonsterDelegate() {} void OnCookieChangedAsyncHelper( const net::CanonicalCookie& cookie, bool removed, net::CookieMonster::Delegate::ChangeCause cause) { Profile* profile = profile_getter_.Run(); if (profile) { ChromeCookieDetails cookie_details(&cookie, removed, cause); content::NotificationService::current()->Notify( chrome::NOTIFICATION_COOKIE_CHANGED, content::Source(profile), content::Details(&cookie_details)); } } const base::Callback profile_getter_; }; Profile* GetProfileOnUI(ProfileManager* profile_manager, Profile* profile) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(profile); if (profile_manager->IsValidProfile(profile)) return profile; return NULL; } } // namespace void ProfileIOData::InitializeOnUIThread(Profile* profile) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); PrefService* pref_service = profile->GetPrefs(); scoped_ptr params(new ProfileParams); params->path = profile->GetPath(); // Set up Accept-Language and Accept-Charset header values params->accept_language = net::HttpUtil::GenerateAcceptLanguageHeader( pref_service->GetString(prefs::kAcceptLanguages)); std::string default_charset = pref_service->GetString(prefs::kDefaultCharset); params->accept_charset = net::HttpUtil::GenerateAcceptCharsetHeader(default_charset); // At this point, we don't know the charset of the referring page // where a url request originates from. This is used to get a suggested // filename from Content-Disposition header made of raw 8bit characters. // Down the road, it can be overriden if it becomes known (for instance, // when download request is made through the context menu in a web page). // At the moment, it'll remain 'undeterministic' when a user // types a URL in the omnibar or click on a download link in a page. // For the latter, we need a change on the webkit-side. // We initialize it to the default charset here and a user will // have an *arguably* better default charset for interpreting a raw 8bit // C-D header field. It means the native OS codepage fallback in // net_util::GetSuggestedFilename is unlikely to be taken. params->referrer_charset = default_charset; params->io_thread = g_browser_process->io_thread(); params->cookie_settings = CookieSettings::Factory::GetForProfile(profile); params->ssl_config_service = profile->GetSSLConfigService(); base::Callback profile_getter = base::Bind(&GetProfileOnUI, g_browser_process->profile_manager(), profile); params->cookie_monster_delegate = new ChromeCookieMonsterDelegate(profile_getter); params->extension_info_map = extensions::ExtensionSystem::Get(profile)->info_map(); if (predictors::ResourcePrefetchPredictor* predictor = predictors::ResourcePrefetchPredictorFactory::GetForProfile( profile)) { resource_prefetch_predictor_observer_.reset( new chrome_browser_net::ResourcePrefetchPredictorObserver(predictor)); } #if defined(ENABLE_NOTIFICATIONS) params->notification_service = DesktopNotificationServiceFactory::GetForProfile(profile); #endif ProtocolHandlerRegistry* protocol_handler_registry = ProtocolHandlerRegistryFactory::GetForProfile(profile); DCHECK(protocol_handler_registry); // The profile instance is only available here in the InitializeOnUIThread // method, so we create the url interceptor here, then save it for // later delivery to the job factory in LazyInitialize. params->protocol_handler_interceptor.reset( protocol_handler_registry->CreateURLInterceptor()); ChromeProxyConfigService* proxy_config_service = ProxyServiceFactory::CreateProxyConfigService(true); params->proxy_config_service.reset(proxy_config_service); profile->GetProxyConfigTracker()->SetChromeProxyConfigService( proxy_config_service); params->profile = profile; profile_params_.reset(params.release()); ChromeNetworkDelegate::InitializePrefsOnUIThread( &enable_referrers_, &enable_do_not_track_, pref_service); #if defined(ENABLE_PRINTING) printing_enabled_.Init(prefs::kPrintingEnabled, pref_service, NULL); printing_enabled_.MoveToThread(BrowserThread::IO); #endif // The URLBlacklistManager has to be created on the UI thread to register // observers of |pref_service|, and it also has to clean up on // ShutdownOnUIThread to release these observers on the right thread. // Don't pass it in |profile_params_| to make sure it is correctly cleaned up, // in particular when this ProfileIOData isn't |initialized_| during deletion. #if defined(ENABLE_CONFIGURATION_POLICY) url_blacklist_manager_.reset(new policy::URLBlacklistManager(pref_service)); #endif initialized_on_UI_thread_ = true; // We need to make sure that content initializes its own data structures that // are associated with each ResourceContext because we might post this // object to the IO thread after this function. BrowserContext::EnsureResourceContextInitialized(profile); } ProfileIOData::MediaRequestContext::MediaRequestContext( chrome_browser_net::LoadTimeStats* load_time_stats) : ChromeURLRequestContext(ChromeURLRequestContext::CONTEXT_TYPE_MEDIA, load_time_stats) { } void ProfileIOData::MediaRequestContext::SetHttpTransactionFactory( scoped_ptr http_factory) { http_factory_ = http_factory.Pass(); set_http_transaction_factory(http_factory_.get()); } ProfileIOData::MediaRequestContext::~MediaRequestContext() {} ProfileIOData::AppRequestContext::AppRequestContext( chrome_browser_net::LoadTimeStats* load_time_stats) : ChromeURLRequestContext(ChromeURLRequestContext::CONTEXT_TYPE_APP, load_time_stats) { } void ProfileIOData::AppRequestContext::SetCookieStore( net::CookieStore* cookie_store) { cookie_store_ = cookie_store; set_cookie_store(cookie_store); } void ProfileIOData::AppRequestContext::SetHttpTransactionFactory( scoped_ptr http_factory) { http_factory_ = http_factory.Pass(); set_http_transaction_factory(http_factory_.get()); } void ProfileIOData::AppRequestContext::SetJobFactory( scoped_ptr job_factory) { job_factory_ = job_factory.Pass(); set_job_factory(job_factory_.get()); } ProfileIOData::AppRequestContext::~AppRequestContext() {} ProfileIOData::ProfileParams::ProfileParams() : io_thread(NULL), #if defined(ENABLE_NOTIFICATIONS) notification_service(NULL), #endif profile(NULL) { } ProfileIOData::ProfileParams::~ProfileParams() {} ProfileIOData::ProfileIOData(bool is_incognito) : initialized_(false), ALLOW_THIS_IN_INITIALIZER_LIST( resource_context_(new ResourceContext(this))), initialized_on_UI_thread_(false), is_incognito_(is_incognito) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); } ProfileIOData::~ProfileIOData() { if (BrowserThread::IsMessageLoopValid(BrowserThread::IO)) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); if (main_request_context_.get()) main_request_context_->AssertNoURLRequests(); if (extensions_request_context_.get()) extensions_request_context_->AssertNoURLRequests(); for (URLRequestContextMap::iterator it = app_request_context_map_.begin(); it != app_request_context_map_.end(); ++it) { it->second->AssertNoURLRequests(); delete it->second; } for (URLRequestContextMap::iterator it = isolated_media_request_context_map_.begin(); it != isolated_media_request_context_map_.end(); ++it) { it->second->AssertNoURLRequests(); delete it->second; } } // static ProfileIOData* ProfileIOData::FromResourceContext( content::ResourceContext* rc) { return (static_cast(rc))->io_data_; } // static bool ProfileIOData::IsHandledProtocol(const std::string& scheme) { DCHECK_EQ(scheme, StringToLowerASCII(scheme)); static const char* const kProtocolList[] = { chrome::kExtensionScheme, chrome::kChromeUIScheme, chrome::kChromeDevToolsScheme, #if defined(OS_CHROMEOS) chrome::kMetadataScheme, chrome::kDriveScheme, #endif // defined(OS_CHROMEOS) chrome::kBlobScheme, chrome::kFileSystemScheme, chrome::kExtensionResourceScheme, }; for (size_t i = 0; i < arraysize(kProtocolList); ++i) { if (scheme == kProtocolList[i]) return true; } return net::URLRequest::IsHandledProtocol(scheme); } bool ProfileIOData::IsHandledURL(const GURL& url) { if (!url.is_valid()) { // We handle error cases. return true; } return IsHandledProtocol(url.scheme()); } content::ResourceContext* ProfileIOData::GetResourceContext() const { return resource_context_.get(); } ChromeURLDataManagerBackend* ProfileIOData::GetChromeURLDataManagerBackend() const { LazyInitialize(); return chrome_url_data_manager_backend_.get(); } ChromeURLRequestContext* ProfileIOData::GetMainRequestContext() const { LazyInitialize(); return main_request_context_.get(); } ChromeURLRequestContext* ProfileIOData::GetMediaRequestContext() const { LazyInitialize(); ChromeURLRequestContext* context = AcquireMediaRequestContext(); DCHECK(context); return context; } ChromeURLRequestContext* ProfileIOData::GetExtensionsRequestContext() const { LazyInitialize(); return extensions_request_context_.get(); } ChromeURLRequestContext* ProfileIOData::GetIsolatedAppRequestContext( ChromeURLRequestContext* main_context, const std::string& app_id, scoped_ptr protocol_handler_interceptor) const { LazyInitialize(); ChromeURLRequestContext* context = NULL; if (ContainsKey(app_request_context_map_, app_id)) { context = app_request_context_map_[app_id]; } else { context = AcquireIsolatedAppRequestContext( main_context, app_id, protocol_handler_interceptor.Pass()); app_request_context_map_[app_id] = context; } DCHECK(context); return context; } ChromeURLRequestContext* ProfileIOData::GetIsolatedMediaRequestContext( ChromeURLRequestContext* app_context, const std::string& app_id) const { LazyInitialize(); ChromeURLRequestContext* context = NULL; if (ContainsKey(isolated_media_request_context_map_, app_id)) { context = isolated_media_request_context_map_[app_id]; } else { context = AcquireIsolatedMediaRequestContext(app_context, app_id); isolated_media_request_context_map_[app_id] = context; } DCHECK(context); return context; } ExtensionInfoMap* ProfileIOData::GetExtensionInfoMap() const { DCHECK(extension_info_map_) << "ExtensionSystem not initialized"; return extension_info_map_; } CookieSettings* ProfileIOData::GetCookieSettings() const { return cookie_settings_; } #if defined(ENABLE_NOTIFICATIONS) DesktopNotificationService* ProfileIOData::GetNotificationService() const { return notification_service_; } #endif void ProfileIOData::InitializeMetricsEnabledStateOnUIThread() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); #if defined(OS_CHROMEOS) // Just fetch the value from ChromeOS' settings while we're on the UI thread. // TODO(stevet): For now, this value is only set on profile initialization. // We will want to do something similar to the PrefMember method below in the // future to more accurately capture this state. chromeos::CrosSettings::Get()->GetBoolean(chromeos::kStatsReportingPref, &enable_metrics_); #else // Prep the PrefMember and send it to the IO thread, since this value will be // read from there. enable_metrics_.Init(prefs::kMetricsReportingEnabled, g_browser_process->local_state(), NULL); enable_metrics_.MoveToThread(BrowserThread::IO); #endif // defined(OS_CHROMEOS) } bool ProfileIOData::GetMetricsEnabledStateOnIOThread() const { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); #if defined(OS_CHROMEOS) return enable_metrics_; #else return enable_metrics_.GetValue(); #endif // defined(OS_CHROMEOS) } chrome_browser_net::HttpServerPropertiesManager* ProfileIOData::http_server_properties_manager() const { return http_server_properties_manager_.get(); } void ProfileIOData::set_http_server_properties_manager( chrome_browser_net::HttpServerPropertiesManager* manager) const { http_server_properties_manager_.reset(manager); } ProfileIOData::ResourceContext::ResourceContext(ProfileIOData* io_data) : io_data_(io_data), host_resolver_(NULL), request_context_(NULL) { DCHECK(io_data); } ProfileIOData::ResourceContext::~ResourceContext() {} void ProfileIOData::ResourceContext::EnsureInitialized() { io_data_->LazyInitialize(); } net::HostResolver* ProfileIOData::ResourceContext::GetHostResolver() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); EnsureInitialized(); return host_resolver_; } net::URLRequestContext* ProfileIOData::ResourceContext::GetRequestContext() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); EnsureInitialized(); return request_context_; } // static std::string ProfileIOData::GetSSLSessionCacheShard() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); // The SSL session cache is partitioned by setting a string. This returns a // unique string to partition the SSL session cache. Each time we create a // new profile, we'll get a fresh SSL session cache which is separate from // the other profiles. static unsigned ssl_session_cache_instance = 0; return StringPrintf("profile/%u", ssl_session_cache_instance++); } void ProfileIOData::LazyInitialize() const { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); if (initialized_) return; // TODO(jhawkins): Remove once crbug.com/102004 is fixed. CHECK(initialized_on_UI_thread_); // TODO(jhawkins): Return to DCHECK once crbug.com/102004 is fixed. CHECK(profile_params_.get()); IOThread* const io_thread = profile_params_->io_thread; IOThread::Globals* const io_thread_globals = io_thread->globals(); const CommandLine& command_line = *CommandLine::ForCurrentProcess(); load_time_stats_ = GetLoadTimeStats(io_thread_globals); // Create the common request contexts. main_request_context_.reset( new ChromeURLRequestContext(ChromeURLRequestContext::CONTEXT_TYPE_MAIN, load_time_stats_)); extensions_request_context_.reset( new ChromeURLRequestContext( ChromeURLRequestContext::CONTEXT_TYPE_EXTENSIONS, load_time_stats_)); chrome_url_data_manager_backend_.reset(new ChromeURLDataManagerBackend); network_delegate_.reset(new ChromeNetworkDelegate( io_thread_globals->extension_event_router_forwarder.get(), profile_params_->extension_info_map, url_blacklist_manager_.get(), #if !defined(OS_ANDROID) ManagedMode::GetURLFilter(), #else NULL, #endif profile_params_->profile, profile_params_->cookie_settings, &enable_referrers_, &enable_do_not_track_, load_time_stats_)); fraudulent_certificate_reporter_.reset( new chrome_browser_net::ChromeFraudulentCertificateReporter( main_request_context_.get())); proxy_service_.reset( ProxyServiceFactory::CreateProxyService( io_thread->net_log(), io_thread_globals->proxy_script_fetcher_context.get(), profile_params_->proxy_config_service.release(), command_line)); transport_security_state_.reset(new net::TransportSecurityState()); transport_security_persister_.reset( new TransportSecurityPersister(transport_security_state_.get(), profile_params_->path, is_incognito())); const std::string& serialized = command_line.GetSwitchValueASCII(switches::kHstsHosts); transport_security_persister_.get()->DeserializeFromCommandLine(serialized); // Take ownership over these parameters. cookie_settings_ = profile_params_->cookie_settings; #if defined(ENABLE_NOTIFICATIONS) notification_service_ = profile_params_->notification_service; #endif extension_info_map_ = profile_params_->extension_info_map; resource_context_->host_resolver_ = io_thread_globals->host_resolver.get(); resource_context_->request_context_ = main_request_context_.get(); if (profile_params_->resource_prefetch_predictor_observer_.get()) { resource_prefetch_predictor_observer_.reset( profile_params_->resource_prefetch_predictor_observer_.release()); } LazyInitializeInternal(profile_params_.get()); profile_params_.reset(); initialized_ = true; } void ProfileIOData::ApplyProfileParamsToContext( ChromeURLRequestContext* context) const { context->set_is_incognito(is_incognito()); context->set_accept_language(profile_params_->accept_language); context->set_accept_charset(profile_params_->accept_charset); context->set_referrer_charset(profile_params_->referrer_charset); context->set_ssl_config_service(profile_params_->ssl_config_service); } void ProfileIOData::SetUpJobFactoryDefaults( net::URLRequestJobFactory* job_factory, scoped_ptr protocol_handler_interceptor, net::NetworkDelegate* network_delegate, net::FtpTransactionFactory* ftp_transaction_factory, net::FtpAuthCache* ftp_auth_cache) const { // NOTE(willchan): Keep these protocol handlers in sync with // ProfileIOData::IsHandledProtocol(). bool set_protocol = job_factory->SetProtocolHandler( chrome::kFileScheme, new net::FileProtocolHandler()); DCHECK(set_protocol); set_protocol = job_factory->SetProtocolHandler( chrome::kChromeDevToolsScheme, CreateDevToolsProtocolHandler(chrome_url_data_manager_backend(), network_delegate)); DCHECK(set_protocol); if (protocol_handler_interceptor.get()) { job_factory->AddInterceptor(protocol_handler_interceptor.release()); } set_protocol = job_factory->SetProtocolHandler( chrome::kExtensionScheme, CreateExtensionProtocolHandler(is_incognito(), GetExtensionInfoMap())); DCHECK(set_protocol); set_protocol = job_factory->SetProtocolHandler( chrome::kExtensionResourceScheme, CreateExtensionResourceProtocolHandler()); DCHECK(set_protocol); set_protocol = job_factory->SetProtocolHandler( chrome::kChromeUIScheme, ChromeURLDataManagerBackend::CreateProtocolHandler( chrome_url_data_manager_backend_.get())); DCHECK(set_protocol); set_protocol = job_factory->SetProtocolHandler( chrome::kDataScheme, new net::DataProtocolHandler()); DCHECK(set_protocol); #if defined(OS_CHROMEOS) if (!is_incognito()) { set_protocol = job_factory->SetProtocolHandler( chrome::kDriveScheme, new gdata::DriveProtocolHandler()); DCHECK(set_protocol); } #if !defined(GOOGLE_CHROME_BUILD) // Install the GView request interceptor that will redirect requests // of compatible documents (PDF, etc) to the GView document viewer. const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess(); if (parsed_command_line.HasSwitch(switches::kEnableGView)) job_factory->AddInterceptor(new chromeos::GViewRequestInterceptor); #endif // !defined(GOOGLE_CHROME_BUILD) #endif // defined(OS_CHROMEOS) job_factory->SetProtocolHandler(chrome::kAboutScheme, new net::AboutProtocolHandler()); #if !defined(DISABLE_FTP_SUPPORT) DCHECK(ftp_transaction_factory); job_factory->SetProtocolHandler( chrome::kFtpScheme, new net::FtpProtocolHandler(ftp_transaction_factory, ftp_auth_cache)); #endif // !defined(DISABLE_FTP_SUPPORT) } void ProfileIOData::ShutdownOnUIThread() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); enable_referrers_.Destroy(); enable_do_not_track_.Destroy(); #if !defined(OS_CHROMEOS) enable_metrics_.Destroy(); #endif safe_browsing_enabled_.Destroy(); printing_enabled_.Destroy(); session_startup_pref_.Destroy(); #if defined(ENABLE_CONFIGURATION_POLICY) if (url_blacklist_manager_.get()) url_blacklist_manager_->ShutdownOnUIThread(); #endif bool posted = BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, this); if (!posted) delete this; } void ProfileIOData::set_server_bound_cert_service( net::ServerBoundCertService* server_bound_cert_service) const { server_bound_cert_service_.reset(server_bound_cert_service); } void ProfileIOData::DestroyResourceContext() { resource_context_.reset(); } void ProfileIOData::PopulateNetworkSessionParams( const ProfileParams* profile_params, net::HttpNetworkSession::Params* params) const { ChromeURLRequestContext* context = main_request_context(); IOThread* const io_thread = profile_params->io_thread; IOThread::Globals* const globals = io_thread->globals(); params->host_resolver = context->host_resolver(); params->cert_verifier = context->cert_verifier(); params->server_bound_cert_service = context->server_bound_cert_service(); params->transport_security_state = context->transport_security_state(); params->proxy_service = context->proxy_service(); params->ssl_session_cache_shard = GetSSLSessionCacheShard(); params->ssl_config_service = context->ssl_config_service(); params->http_auth_handler_factory = context->http_auth_handler_factory(); params->network_delegate = context->network_delegate(); params->http_server_properties = context->http_server_properties(); params->net_log = context->net_log(); params->host_mapping_rules = globals->host_mapping_rules.get(); params->ignore_certificate_errors = globals->ignore_certificate_errors; params->http_pipelining_enabled = globals->http_pipelining_enabled; params->testing_fixed_http_port = globals->testing_fixed_http_port; params->testing_fixed_https_port = globals->testing_fixed_https_port; const CommandLine& command_line = *CommandLine::ForCurrentProcess(); if (command_line.HasSwitch(switches::kTrustedSpdyProxy)) { params->trusted_spdy_proxy = command_line.GetSwitchValueASCII( switches::kTrustedSpdyProxy); } }