| // 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_impl_io_data.h" |
| |
| #include <memory> |
| #include <set> |
| #include <string> |
| #include <utility> |
| |
| #include "base/bind.h" |
| #include "base/command_line.h" |
| #include "base/logging.h" |
| #include "base/macros.h" |
| #include "base/memory/ptr_util.h" |
| #include "base/metrics/field_trial.h" |
| #include "base/sequenced_task_runner.h" |
| #include "base/stl_util.h" |
| #include "base/strings/string_util.h" |
| #include "base/threading/sequenced_worker_pool.h" |
| #include "base/threading/worker_pool.h" |
| #include "build/build_config.h" |
| #include "chrome/browser/browser_process.h" |
| #include "chrome/browser/chrome_notification_types.h" |
| #include "chrome/browser/custom_handlers/protocol_handler_registry.h" |
| #include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h" |
| #include "chrome/browser/data_use_measurement/chrome_data_use_ascriber.h" |
| #include "chrome/browser/io_thread.h" |
| #include "chrome/browser/net/chrome_network_delegate.h" |
| #include "chrome/browser/net/http_server_properties_manager_factory.h" |
| #include "chrome/browser/net/predictor.h" |
| #include "chrome/browser/net/quota_policy_channel_id_store.h" |
| #include "chrome/browser/net/sdch_owner_pref_storage.h" |
| #include "chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_io_data.h" |
| #include "chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings.h" |
| #include "chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings_factory.h" |
| #include "chrome/browser/previews/previews_service.h" |
| #include "chrome/browser/previews/previews_service_factory.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/common/chrome_constants.h" |
| #include "chrome/common/chrome_switches.h" |
| #include "chrome/common/pref_names.h" |
| #include "chrome/common/url_constants.h" |
| #include "components/cookie_config/cookie_store_util.h" |
| #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h" |
| #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h" |
| #include "components/data_reduction_proxy/core/browser/data_store_impl.h" |
| #include "components/domain_reliability/monitor.h" |
| #include "components/net_log/chrome_net_log.h" |
| #include "components/prefs/json_pref_store.h" |
| #include "components/prefs/pref_filter.h" |
| #include "components/prefs/pref_member.h" |
| #include "components/prefs/pref_service.h" |
| #include "components/previews/core/previews_io_data.h" |
| #include "content/public/browser/browser_thread.h" |
| #include "content/public/browser/cookie_store_factory.h" |
| #include "content/public/browser/notification_service.h" |
| #include "content/public/browser/resource_context.h" |
| #include "content/public/browser/storage_partition.h" |
| #include "extensions/browser/extension_protocols.h" |
| #include "extensions/common/constants.h" |
| #include "extensions/features/features.h" |
| #include "net/base/cache_type.h" |
| #include "net/base/sdch_manager.h" |
| #include "net/cookies/cookie_store.h" |
| #include "net/http/http_cache.h" |
| #include "net/http/http_network_session.h" |
| #include "net/http/http_server_properties_manager.h" |
| #include "net/sdch/sdch_owner.h" |
| #include "net/ssl/channel_id_service.h" |
| #include "net/url_request/url_request_context_storage.h" |
| #include "net/url_request/url_request_intercepting_job_factory.h" |
| #include "net/url_request/url_request_job_factory_impl.h" |
| #include "storage/browser/quota/special_storage_policy.h" |
| |
| #if defined(OS_ANDROID) |
| #include "chrome/browser/android/offline_pages/offline_page_request_interceptor.h" |
| #endif // defined(OS_ANDROID) |
| |
| namespace { |
| |
| net::BackendType ChooseCacheBackendType() { |
| #if !defined(OS_ANDROID) |
| const base::CommandLine& command_line = |
| *base::CommandLine::ForCurrentProcess(); |
| if (command_line.HasSwitch(switches::kUseSimpleCacheBackend)) { |
| const std::string opt_value = |
| command_line.GetSwitchValueASCII(switches::kUseSimpleCacheBackend); |
| if (base::LowerCaseEqualsASCII(opt_value, "off")) |
| return net::CACHE_BACKEND_BLOCKFILE; |
| if (opt_value.empty() || base::LowerCaseEqualsASCII(opt_value, "on")) |
| return net::CACHE_BACKEND_SIMPLE; |
| } |
| const std::string experiment_name = |
| base::FieldTrialList::FindFullName("SimpleCacheTrial"); |
| if (base::StartsWith(experiment_name, "Disable", |
| base::CompareCase::INSENSITIVE_ASCII)) { |
| return net::CACHE_BACKEND_BLOCKFILE; |
| } |
| if (base::StartsWith(experiment_name, "ExperimentYes", |
| base::CompareCase::INSENSITIVE_ASCII)) { |
| return net::CACHE_BACKEND_SIMPLE; |
| } |
| #endif // #if !defined(OS_ANDROID) |
| |
| #if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) |
| return net::CACHE_BACKEND_SIMPLE; |
| #else |
| return net::CACHE_BACKEND_BLOCKFILE; |
| #endif |
| } |
| |
| } // namespace |
| |
| using content::BrowserThread; |
| |
| ProfileImplIOData::Handle::Handle(Profile* profile) |
| : io_data_(new ProfileImplIOData), |
| profile_(profile), |
| initialized_(false) { |
| DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| DCHECK(profile); |
| } |
| |
| ProfileImplIOData::Handle::~Handle() { |
| DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| if (io_data_->predictor_ != NULL) { |
| // io_data_->predictor_ might be NULL if Init() was never called |
| // (i.e. we shut down before ProfileImpl::DoFinalInit() got called). |
| io_data_->predictor_->ShutdownOnUIThread(); |
| } |
| |
| if (io_data_->http_server_properties_manager_) |
| io_data_->http_server_properties_manager_->ShutdownOnPrefThread(); |
| |
| // io_data_->data_reduction_proxy_io_data() might be NULL if Init() was |
| // never called. |
| if (io_data_->data_reduction_proxy_io_data()) |
| io_data_->data_reduction_proxy_io_data()->ShutdownOnUIThread(); |
| |
| io_data_->ShutdownOnUIThread(GetAllContextGetters()); |
| } |
| |
| void ProfileImplIOData::Handle::Init( |
| const base::FilePath& cookie_path, |
| const base::FilePath& channel_id_path, |
| const base::FilePath& cache_path, |
| int cache_max_size, |
| const base::FilePath& media_cache_path, |
| int media_cache_max_size, |
| const base::FilePath& extensions_cookie_path, |
| const base::FilePath& profile_path, |
| chrome_browser_net::Predictor* predictor, |
| content::CookieStoreConfig::SessionCookieMode session_cookie_mode, |
| storage::SpecialStoragePolicy* special_storage_policy, |
| std::unique_ptr<domain_reliability::DomainReliabilityMonitor> |
| domain_reliability_monitor) { |
| DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| DCHECK(!io_data_->lazy_params_); |
| DCHECK(predictor); |
| |
| LazyParams* lazy_params = new LazyParams(); |
| |
| lazy_params->cookie_path = cookie_path; |
| lazy_params->channel_id_path = channel_id_path; |
| lazy_params->cache_path = cache_path; |
| lazy_params->cache_max_size = cache_max_size; |
| lazy_params->media_cache_path = media_cache_path; |
| lazy_params->media_cache_max_size = media_cache_max_size; |
| lazy_params->extensions_cookie_path = extensions_cookie_path; |
| lazy_params->session_cookie_mode = session_cookie_mode; |
| lazy_params->special_storage_policy = special_storage_policy; |
| |
| PrefService* pref_service = profile_->GetPrefs(); |
| lazy_params->http_server_properties_manager.reset( |
| chrome_browser_net::HttpServerPropertiesManagerFactory::CreateManager( |
| pref_service)); |
| io_data_->http_server_properties_manager_ = |
| lazy_params->http_server_properties_manager.get(); |
| |
| io_data_->lazy_params_.reset(lazy_params); |
| |
| // Keep track of profile path and cache sizes separately so we can use them |
| // on demand when creating storage isolated URLRequestContextGetters. |
| io_data_->profile_path_ = profile_path; |
| io_data_->app_cache_max_size_ = cache_max_size; |
| io_data_->app_media_cache_max_size_ = media_cache_max_size; |
| |
| io_data_->predictor_.reset(predictor); |
| io_data_->domain_reliability_monitor_ = std::move(domain_reliability_monitor); |
| |
| io_data_->InitializeMetricsEnabledStateOnUIThread(); |
| if (io_data_->domain_reliability_monitor_) |
| io_data_->domain_reliability_monitor_->MoveToNetworkThread(); |
| |
| io_data_->previews_io_data_ = base::MakeUnique<previews::PreviewsIOData>( |
| BrowserThread::GetTaskRunnerForThread(BrowserThread::UI), |
| BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)); |
| PreviewsServiceFactory::GetForProfile(profile_)->Initialize( |
| io_data_->previews_io_data_.get(), |
| BrowserThread::GetTaskRunnerForThread(BrowserThread::IO), profile_path); |
| |
| io_data_->set_data_reduction_proxy_io_data( |
| CreateDataReductionProxyChromeIOData( |
| g_browser_process->io_thread()->net_log(), profile_->GetPrefs(), |
| BrowserThread::GetTaskRunnerForThread(BrowserThread::IO), |
| BrowserThread::GetTaskRunnerForThread(BrowserThread::UI))); |
| } |
| |
| content::ResourceContext* |
| ProfileImplIOData::Handle::GetResourceContext() const { |
| DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| LazyInitialize(); |
| return GetResourceContextNoInit(); |
| } |
| |
| content::ResourceContext* |
| ProfileImplIOData::Handle::GetResourceContextNoInit() const { |
| DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| // Don't call LazyInitialize here, since the resource context is created at |
| // the beginning of initalization and is used by some members while they're |
| // being initialized (i.e. AppCacheService). |
| return io_data_->GetResourceContext(); |
| } |
| |
| scoped_refptr<ChromeURLRequestContextGetter> |
| ProfileImplIOData::Handle::CreateMainRequestContextGetter( |
| content::ProtocolHandlerMap* protocol_handlers, |
| content::URLRequestInterceptorScopedVector request_interceptors, |
| IOThread* io_thread) const { |
| DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| LazyInitialize(); |
| DCHECK(!main_request_context_getter_.get()); |
| main_request_context_getter_ = ChromeURLRequestContextGetter::Create( |
| profile_, io_data_, protocol_handlers, std::move(request_interceptors)); |
| |
| base::SequencedWorkerPool* pool = BrowserThread::GetBlockingPool(); |
| scoped_refptr<base::SequencedTaskRunner> db_task_runner = |
| pool->GetSequencedTaskRunnerWithShutdownBehavior( |
| pool->GetSequenceToken(), |
| base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); |
| std::unique_ptr<data_reduction_proxy::DataStore> store( |
| new data_reduction_proxy::DataStoreImpl(io_data_->profile_path_)); |
| DataReductionProxyChromeSettingsFactory::GetForBrowserContext(profile_) |
| ->InitDataReductionProxySettings( |
| io_data_->data_reduction_proxy_io_data(), profile_->GetPrefs(), |
| main_request_context_getter_.get(), std::move(store), |
| BrowserThread::GetTaskRunnerForThread(BrowserThread::UI), |
| db_task_runner); |
| |
| io_data_->predictor_ |
| ->InitNetworkPredictor(profile_->GetPrefs(), |
| io_thread, |
| main_request_context_getter_.get(), |
| io_data_); |
| |
| content::NotificationService::current()->Notify( |
| chrome::NOTIFICATION_PROFILE_URL_REQUEST_CONTEXT_GETTER_INITIALIZED, |
| content::Source<Profile>(profile_), |
| content::NotificationService::NoDetails()); |
| return main_request_context_getter_; |
| } |
| |
| scoped_refptr<ChromeURLRequestContextGetter> |
| ProfileImplIOData::Handle::GetMediaRequestContextGetter() const { |
| DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| LazyInitialize(); |
| if (!media_request_context_getter_.get()) { |
| media_request_context_getter_ = |
| ChromeURLRequestContextGetter::CreateForMedia(profile_, io_data_); |
| } |
| return media_request_context_getter_; |
| } |
| |
| scoped_refptr<ChromeURLRequestContextGetter> |
| ProfileImplIOData::Handle::GetExtensionsRequestContextGetter() const { |
| DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| LazyInitialize(); |
| if (!extensions_request_context_getter_.get()) { |
| extensions_request_context_getter_ = |
| ChromeURLRequestContextGetter::CreateForExtensions(profile_, io_data_); |
| } |
| return extensions_request_context_getter_; |
| } |
| |
| scoped_refptr<ChromeURLRequestContextGetter> |
| ProfileImplIOData::Handle::CreateIsolatedAppRequestContextGetter( |
| const base::FilePath& partition_path, |
| bool in_memory, |
| content::ProtocolHandlerMap* protocol_handlers, |
| content::URLRequestInterceptorScopedVector request_interceptors) const { |
| DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| // Check that the partition_path is not the same as the base profile path. We |
| // expect isolated partition, which will never go to the default profile path. |
| CHECK(partition_path != profile_->GetPath()); |
| LazyInitialize(); |
| |
| // Keep a map of request context getters, one per requested storage partition. |
| StoragePartitionDescriptor descriptor(partition_path, in_memory); |
| ChromeURLRequestContextGetterMap::iterator iter = |
| app_request_context_getter_map_.find(descriptor); |
| if (iter != app_request_context_getter_map_.end()) |
| return iter->second; |
| |
| std::unique_ptr<ProtocolHandlerRegistry::JobInterceptorFactory> |
| protocol_handler_interceptor( |
| ProtocolHandlerRegistryFactory::GetForBrowserContext(profile_) |
| ->CreateJobInterceptorFactory()); |
| ChromeURLRequestContextGetter* context = |
| ChromeURLRequestContextGetter::CreateForIsolatedApp( |
| profile_, io_data_, descriptor, |
| std::move(protocol_handler_interceptor), protocol_handlers, |
| std::move(request_interceptors)); |
| app_request_context_getter_map_[descriptor] = context; |
| |
| return context; |
| } |
| |
| scoped_refptr<ChromeURLRequestContextGetter> |
| ProfileImplIOData::Handle::GetIsolatedMediaRequestContextGetter( |
| const base::FilePath& partition_path, |
| bool in_memory) const { |
| DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| // We must have a non-default path, or this will act like the default media |
| // context. |
| CHECK(partition_path != profile_->GetPath()); |
| LazyInitialize(); |
| |
| // Keep a map of request context getters, one per requested storage partition. |
| StoragePartitionDescriptor descriptor(partition_path, in_memory); |
| ChromeURLRequestContextGetterMap::iterator iter = |
| isolated_media_request_context_getter_map_.find(descriptor); |
| if (iter != isolated_media_request_context_getter_map_.end()) |
| return iter->second; |
| |
| // Get the app context as the starting point for the media context, so that |
| // it uses the app's cookie store. |
| ChromeURLRequestContextGetterMap::const_iterator app_iter = |
| app_request_context_getter_map_.find(descriptor); |
| DCHECK(app_iter != app_request_context_getter_map_.end()); |
| ChromeURLRequestContextGetter* app_context = app_iter->second.get(); |
| ChromeURLRequestContextGetter* context = |
| ChromeURLRequestContextGetter::CreateForIsolatedMedia( |
| profile_, app_context, io_data_, descriptor); |
| isolated_media_request_context_getter_map_[descriptor] = context; |
| |
| return context; |
| } |
| |
| DevToolsNetworkControllerHandle* |
| ProfileImplIOData::Handle::GetDevToolsNetworkControllerHandle() const { |
| DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| return io_data_->network_controller_handle(); |
| } |
| |
| void ProfileImplIOData::Handle::ClearNetworkingHistorySince( |
| base::Time time, |
| const base::Closure& completion) { |
| DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| LazyInitialize(); |
| |
| BrowserThread::PostTask( |
| BrowserThread::IO, FROM_HERE, |
| base::Bind( |
| &ProfileImplIOData::ClearNetworkingHistorySinceOnIOThread, |
| base::Unretained(io_data_), |
| time, |
| completion)); |
| } |
| |
| void ProfileImplIOData::Handle::LazyInitialize() const { |
| DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| if (initialized_) |
| return; |
| |
| // Set initialized_ to true at the beginning in case any of the objects |
| // below try to get the ResourceContext pointer. |
| initialized_ = true; |
| PrefService* pref_service = profile_->GetPrefs(); |
| io_data_->session_startup_pref()->Init( |
| prefs::kRestoreOnStartup, pref_service); |
| io_data_->session_startup_pref()->MoveToThread( |
| BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)); |
| io_data_->safe_browsing_enabled()->Init(prefs::kSafeBrowsingEnabled, |
| pref_service); |
| io_data_->safe_browsing_enabled()->MoveToThread( |
| BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)); |
| io_data_->InitializeOnUIThread(profile_); |
| } |
| |
| std::unique_ptr<ProfileIOData::ChromeURLRequestContextGetterVector> |
| ProfileImplIOData::Handle::GetAllContextGetters() { |
| ChromeURLRequestContextGetterMap::iterator iter; |
| std::unique_ptr<ChromeURLRequestContextGetterVector> context_getters( |
| new ChromeURLRequestContextGetterVector()); |
| |
| iter = isolated_media_request_context_getter_map_.begin(); |
| for (; iter != isolated_media_request_context_getter_map_.end(); ++iter) |
| context_getters->push_back(iter->second); |
| |
| iter = app_request_context_getter_map_.begin(); |
| for (; iter != app_request_context_getter_map_.end(); ++iter) |
| context_getters->push_back(iter->second); |
| |
| if (extensions_request_context_getter_.get()) |
| context_getters->push_back(extensions_request_context_getter_); |
| |
| if (media_request_context_getter_.get()) |
| context_getters->push_back(media_request_context_getter_); |
| |
| if (main_request_context_getter_.get()) |
| context_getters->push_back(main_request_context_getter_); |
| |
| return context_getters; |
| } |
| |
| ProfileImplIOData::LazyParams::LazyParams() |
| : cache_max_size(0), |
| media_cache_max_size(0), |
| session_cookie_mode( |
| content::CookieStoreConfig::EPHEMERAL_SESSION_COOKIES) {} |
| |
| ProfileImplIOData::LazyParams::~LazyParams() {} |
| |
| ProfileImplIOData::ProfileImplIOData() |
| : ProfileIOData(Profile::REGULAR_PROFILE), |
| http_server_properties_manager_(NULL), |
| app_cache_max_size_(0), |
| app_media_cache_max_size_(0) { |
| } |
| |
| ProfileImplIOData::~ProfileImplIOData() { |
| DestroyResourceContext(); |
| |
| if (media_request_context_) |
| media_request_context_->AssertNoURLRequests(); |
| } |
| |
| void ProfileImplIOData::InitializeInternal( |
| std::unique_ptr<ChromeNetworkDelegate> chrome_network_delegate, |
| ProfileParams* profile_params, |
| content::ProtocolHandlerMap* protocol_handlers, |
| content::URLRequestInterceptorScopedVector request_interceptors) const { |
| // Set up a persistent store for use by the network stack on the IO thread. |
| base::FilePath network_json_store_filepath( |
| profile_path_.Append(chrome::kNetworkPersistentStateFilename)); |
| network_json_store_ = new JsonPrefStore( |
| network_json_store_filepath, |
| JsonPrefStore::GetTaskRunnerForFile(network_json_store_filepath, |
| BrowserThread::GetBlockingPool()), |
| std::unique_ptr<PrefFilter>()); |
| network_json_store_->ReadPrefsAsync(nullptr); |
| |
| net::URLRequestContext* main_context = main_request_context(); |
| net::URLRequestContextStorage* main_context_storage = |
| main_request_context_storage(); |
| |
| IOThread* const io_thread = profile_params->io_thread; |
| IOThread::Globals* const io_thread_globals = io_thread->globals(); |
| |
| if (domain_reliability_monitor_) { |
| domain_reliability::DomainReliabilityMonitor* monitor = |
| domain_reliability_monitor_.get(); |
| monitor->InitURLRequestContext(main_context); |
| monitor->AddBakedInConfigs(); |
| monitor->SetDiscardUploads(!GetMetricsEnabledStateOnIOThread()); |
| chrome_network_delegate->set_domain_reliability_monitor(monitor); |
| } |
| |
| ApplyProfileParamsToContext(main_context); |
| |
| if (lazy_params_->http_server_properties_manager) { |
| lazy_params_->http_server_properties_manager->InitializeOnNetworkThread(); |
| main_context_storage->set_http_server_properties( |
| std::move(lazy_params_->http_server_properties_manager)); |
| } |
| |
| main_context->set_transport_security_state(transport_security_state()); |
| main_context->set_ct_policy_enforcer( |
| io_thread_globals->ct_policy_enforcer.get()); |
| |
| main_context->set_net_log(io_thread->net_log()); |
| |
| main_context_storage->set_network_delegate( |
| data_reduction_proxy_io_data()->CreateNetworkDelegate( |
| io_thread_globals->data_use_ascriber->CreateNetworkDelegate( |
| std::move(chrome_network_delegate), |
| io_thread->GetMetricsDataUseForwarder()), |
| true)); |
| |
| main_context->set_host_resolver( |
| io_thread_globals->host_resolver.get()); |
| |
| main_context->set_http_auth_handler_factory( |
| io_thread_globals->http_auth_handler_factory.get()); |
| |
| main_context->set_proxy_service(proxy_service()); |
| |
| // Set up cookie store. |
| DCHECK(!lazy_params_->cookie_path.empty()); |
| |
| content::CookieStoreConfig cookie_config( |
| lazy_params_->cookie_path, lazy_params_->session_cookie_mode, |
| lazy_params_->special_storage_policy.get(), |
| profile_params->cookie_monster_delegate.get()); |
| cookie_config.crypto_delegate = cookie_config::GetCookieCryptoDelegate(); |
| main_context_storage->set_cookie_store( |
| content::CreateCookieStore(cookie_config)); |
| |
| // Set up server bound cert service. |
| DCHECK(!lazy_params_->channel_id_path.empty()); |
| scoped_refptr<QuotaPolicyChannelIDStore> channel_id_db = |
| new QuotaPolicyChannelIDStore( |
| lazy_params_->channel_id_path, |
| BrowserThread::GetBlockingPool()->GetSequencedTaskRunner( |
| base::SequencedWorkerPool::GetSequenceToken()), |
| lazy_params_->special_storage_policy.get()); |
| main_context_storage->set_channel_id_service( |
| base::MakeUnique<net::ChannelIDService>( |
| new net::DefaultChannelIDStore(channel_id_db.get()), |
| base::WorkerPool::GetTaskRunner(true))); |
| |
| main_context->cookie_store()->SetChannelIDServiceID( |
| main_context->channel_id_service()->GetUniqueID()); |
| |
| std::unique_ptr<net::HttpCache::BackendFactory> main_backend( |
| new net::HttpCache::DefaultBackend( |
| net::DISK_CACHE, ChooseCacheBackendType(), lazy_params_->cache_path, |
| lazy_params_->cache_max_size, |
| BrowserThread::GetTaskRunnerForThread(BrowserThread::CACHE))); |
| main_context_storage->set_http_network_session( |
| CreateHttpNetworkSession(*profile_params)); |
| main_context_storage->set_http_transaction_factory(CreateMainHttpFactory( |
| main_context_storage->http_network_session(), std::move(main_backend))); |
| |
| std::unique_ptr<net::URLRequestJobFactoryImpl> main_job_factory( |
| new net::URLRequestJobFactoryImpl()); |
| InstallProtocolHandlers(main_job_factory.get(), protocol_handlers); |
| |
| // Install the Offline Page Interceptor. |
| #if defined(OS_ANDROID) |
| request_interceptors.push_back(std::unique_ptr<net::URLRequestInterceptor>( |
| new offline_pages::OfflinePageRequestInterceptor( |
| previews_io_data_.get()))); |
| #endif |
| |
| // The data reduction proxy interceptor should be as close to the network |
| // as possible. |
| request_interceptors.insert( |
| request_interceptors.begin(), |
| data_reduction_proxy_io_data()->CreateInterceptor().release()); |
| main_context_storage->set_job_factory(SetUpJobFactoryDefaults( |
| std::move(main_job_factory), std::move(request_interceptors), |
| std::move(profile_params->protocol_handler_interceptor), |
| main_context->network_delegate(), |
| io_thread_globals->host_resolver.get())); |
| main_context->set_network_quality_estimator( |
| io_thread_globals->network_quality_estimator.get()); |
| |
| #if BUILDFLAG(ENABLE_EXTENSIONS) |
| InitializeExtensionsRequestContext(profile_params); |
| #endif |
| |
| // Setup SDCH for this profile. |
| std::unique_ptr<net::SdchManager> sdch_manager(new net::SdchManager()); |
| sdch_policy_.reset(new net::SdchOwner(sdch_manager.get(), main_context)); |
| sdch_policy_->EnablePersistentStorage( |
| std::unique_ptr<net::SdchOwner::PrefStorage>( |
| new chrome_browser_net::SdchOwnerPrefStorage( |
| network_json_store_.get()))); |
| main_context_storage->set_sdch_manager(std::move(sdch_manager)); |
| |
| // Create a media request context based on the main context, but using a |
| // media cache. It shares the same job factory as the main context. |
| StoragePartitionDescriptor details(profile_path_, false); |
| media_request_context_.reset(InitializeMediaRequestContext(main_context, |
| details)); |
| |
| lazy_params_.reset(); |
| } |
| |
| void ProfileImplIOData:: |
| InitializeExtensionsRequestContext(ProfileParams* profile_params) const { |
| net::URLRequestContext* extensions_context = extensions_request_context(); |
| IOThread* const io_thread = profile_params->io_thread; |
| IOThread::Globals* const io_thread_globals = io_thread->globals(); |
| ApplyProfileParamsToContext(extensions_context); |
| |
| extensions_context->set_transport_security_state(transport_security_state()); |
| extensions_context->set_ct_policy_enforcer( |
| io_thread_globals->ct_policy_enforcer.get()); |
| |
| extensions_context->set_net_log(io_thread->net_log()); |
| |
| content::CookieStoreConfig cookie_config( |
| lazy_params_->extensions_cookie_path, |
| lazy_params_->session_cookie_mode, |
| NULL, NULL); |
| cookie_config.crypto_delegate = cookie_config::GetCookieCryptoDelegate(); |
| // Enable cookies for chrome-extension URLs. |
| cookie_config.cookieable_schemes.push_back(extensions::kExtensionScheme); |
| extensions_cookie_store_ = content::CreateCookieStore(cookie_config); |
| extensions_context->set_cookie_store(extensions_cookie_store_.get()); |
| |
| std::unique_ptr<net::URLRequestJobFactoryImpl> extensions_job_factory( |
| new net::URLRequestJobFactoryImpl()); |
| // TODO(shalev): The extensions_job_factory has a NULL NetworkDelegate. |
| // Without a network_delegate, this protocol handler will never |
| // handle file: requests, but as a side effect it makes |
| // job_factory::IsHandledProtocol return true, which prevents attempts to |
| // handle the protocol externally. We pass NULL in to |
| // SetUpJobFactory() to get this effect. |
| extensions_job_factory_ = SetUpJobFactoryDefaults( |
| std::move(extensions_job_factory), |
| content::URLRequestInterceptorScopedVector(), |
| std::unique_ptr<ProtocolHandlerRegistry::JobInterceptorFactory>(), NULL, |
| io_thread_globals->host_resolver.get()); |
| extensions_context->set_job_factory(extensions_job_factory_.get()); |
| } |
| |
| net::URLRequestContext* ProfileImplIOData::InitializeAppRequestContext( |
| net::URLRequestContext* main_context, |
| const StoragePartitionDescriptor& partition_descriptor, |
| std::unique_ptr<ProtocolHandlerRegistry::JobInterceptorFactory> |
| protocol_handler_interceptor, |
| content::ProtocolHandlerMap* protocol_handlers, |
| content::URLRequestInterceptorScopedVector request_interceptors) const { |
| // Copy most state from the main context. |
| AppRequestContext* context = new AppRequestContext(); |
| context->CopyFrom(main_context); |
| |
| base::FilePath cookie_path = partition_descriptor.path.Append( |
| chrome::kCookieFilename); |
| base::FilePath channel_id_path = |
| partition_descriptor.path.Append(chrome::kChannelIDFilename); |
| base::FilePath cache_path = |
| partition_descriptor.path.Append(chrome::kCacheDirname); |
| |
| // Use a separate HTTP disk cache for isolated apps. |
| std::unique_ptr<net::HttpCache::BackendFactory> app_backend; |
| if (partition_descriptor.in_memory) { |
| app_backend = net::HttpCache::DefaultBackend::InMemory(0); |
| } else { |
| app_backend.reset(new net::HttpCache::DefaultBackend( |
| net::DISK_CACHE, ChooseCacheBackendType(), cache_path, |
| app_cache_max_size_, |
| BrowserThread::GetTaskRunnerForThread(BrowserThread::CACHE))); |
| } |
| |
| std::unique_ptr<net::CookieStore> cookie_store; |
| scoped_refptr<net::SQLiteChannelIDStore> channel_id_db; |
| if (partition_descriptor.in_memory) { |
| cookie_store = content::CreateCookieStore(content::CookieStoreConfig()); |
| } else { |
| // Use an app-specific cookie store. |
| DCHECK(!cookie_path.empty()); |
| |
| // TODO(creis): We should have a cookie delegate for notifying the cookie |
| // extensions API, but we need to update it to understand isolated apps |
| // first. |
| content::CookieStoreConfig cookie_config( |
| cookie_path, content::CookieStoreConfig::EPHEMERAL_SESSION_COOKIES, |
| nullptr, nullptr); |
| cookie_config.crypto_delegate = cookie_config::GetCookieCryptoDelegate(); |
| cookie_store = content::CreateCookieStore(cookie_config); |
| channel_id_db = new net::SQLiteChannelIDStore( |
| channel_id_path, |
| BrowserThread::GetBlockingPool()->GetSequencedTaskRunner( |
| base::SequencedWorkerPool::GetSequenceToken())); |
| } |
| std::unique_ptr<net::ChannelIDService> channel_id_service( |
| new net::ChannelIDService( |
| new net::DefaultChannelIDStore(channel_id_db.get()), |
| base::WorkerPool::GetTaskRunner(true))); |
| cookie_store->SetChannelIDServiceID(channel_id_service->GetUniqueID()); |
| |
| // Build a new HttpNetworkSession that uses the new ChannelIDService. |
| // TODO(mmenke): It weird to combine state from |
| // main_request_context_storage() objects and the argumet to this method, |
| // |main_context|. Remove |main_context| as an argument, and just use |
| // main_context() instead. |
| net::HttpNetworkSession::Params network_params = |
| main_request_context_storage()->http_network_session()->params(); |
| network_params.channel_id_service = channel_id_service.get(); |
| std::unique_ptr<net::HttpNetworkSession> http_network_session( |
| new net::HttpNetworkSession(network_params)); |
| std::unique_ptr<net::HttpCache> app_http_cache = |
| CreateHttpFactory(http_network_session.get(), std::move(app_backend)); |
| |
| // Transfer ownership of the ChannelIDStore and the HttpNetworkSession to the |
| // AppRequestContext. |
| context->SetChannelIDService(std::move(channel_id_service)); |
| context->SetHttpNetworkSession(std::move(http_network_session)); |
| |
| // Transfer ownership of the cookies and cache to AppRequestContext. |
| context->SetCookieStore(std::move(cookie_store)); |
| context->SetHttpTransactionFactory(std::move(app_http_cache)); |
| |
| std::unique_ptr<net::URLRequestJobFactoryImpl> job_factory( |
| new net::URLRequestJobFactoryImpl()); |
| InstallProtocolHandlers(job_factory.get(), protocol_handlers); |
| // The data reduction proxy interceptor should be as close to the network |
| // as possible. |
| request_interceptors.insert( |
| request_interceptors.begin(), |
| data_reduction_proxy_io_data()->CreateInterceptor().release()); |
| |
| std::unique_ptr<net::URLRequestJobFactory> top_job_factory( |
| SetUpJobFactoryDefaults( |
| std::move(job_factory), std::move(request_interceptors), |
| std::move(protocol_handler_interceptor), context->network_delegate(), |
| context->host_resolver())); |
| context->SetJobFactory(std::move(top_job_factory)); |
| |
| return context; |
| } |
| |
| net::URLRequestContext* |
| ProfileImplIOData::InitializeMediaRequestContext( |
| net::URLRequestContext* original_context, |
| const StoragePartitionDescriptor& partition_descriptor) const { |
| // Copy most state from the original context. |
| MediaRequestContext* context = new MediaRequestContext(); |
| context->CopyFrom(original_context); |
| |
| // For in-memory context, return immediately after creating the new |
| // context before attaching a separate cache. It is important to return |
| // a new context rather than just reusing |original_context| because |
| // the caller expects to take ownership of the pointer. |
| if (partition_descriptor.in_memory) |
| return context; |
| |
| using content::StoragePartition; |
| base::FilePath cache_path; |
| int cache_max_size = app_media_cache_max_size_; |
| if (partition_descriptor.path == profile_path_) { |
| // lazy_params_ is only valid for the default media context creation. |
| cache_path = lazy_params_->media_cache_path; |
| cache_max_size = lazy_params_->media_cache_max_size; |
| } else { |
| cache_path = partition_descriptor.path.Append(chrome::kMediaCacheDirname); |
| } |
| |
| // Use a separate HTTP disk cache for isolated apps. |
| std::unique_ptr<net::HttpCache::BackendFactory> media_backend( |
| new net::HttpCache::DefaultBackend( |
| net::MEDIA_CACHE, ChooseCacheBackendType(), cache_path, |
| cache_max_size, |
| BrowserThread::GetTaskRunnerForThread(BrowserThread::CACHE))); |
| std::unique_ptr<net::HttpCache> media_http_cache = |
| CreateHttpFactory(main_request_context_storage()->http_network_session(), |
| std::move(media_backend)); |
| |
| // Transfer ownership of the cache to MediaRequestContext. |
| context->SetHttpTransactionFactory(std::move(media_http_cache)); |
| |
| // Note that we do not create a new URLRequestJobFactory because |
| // the media context should behave exactly like its parent context |
| // in all respects except for cache behavior on media subresources. |
| // The CopyFrom() step above means that our media context will use |
| // the same URLRequestJobFactory instance that our parent context does. |
| |
| return context; |
| } |
| |
| net::URLRequestContext* |
| ProfileImplIOData::AcquireMediaRequestContext() const { |
| DCHECK(media_request_context_); |
| return media_request_context_.get(); |
| } |
| |
| net::URLRequestContext* ProfileImplIOData::AcquireIsolatedAppRequestContext( |
| net::URLRequestContext* main_context, |
| const StoragePartitionDescriptor& partition_descriptor, |
| std::unique_ptr<ProtocolHandlerRegistry::JobInterceptorFactory> |
| protocol_handler_interceptor, |
| content::ProtocolHandlerMap* protocol_handlers, |
| content::URLRequestInterceptorScopedVector request_interceptors) const { |
| // We create per-app contexts on demand, unlike the others above. |
| net::URLRequestContext* app_request_context = InitializeAppRequestContext( |
| main_context, partition_descriptor, |
| std::move(protocol_handler_interceptor), protocol_handlers, |
| std::move(request_interceptors)); |
| DCHECK(app_request_context); |
| return app_request_context; |
| } |
| |
| net::URLRequestContext* |
| ProfileImplIOData::AcquireIsolatedMediaRequestContext( |
| net::URLRequestContext* app_context, |
| const StoragePartitionDescriptor& partition_descriptor) const { |
| // We create per-app media contexts on demand, unlike the others above. |
| net::URLRequestContext* media_request_context = |
| InitializeMediaRequestContext(app_context, partition_descriptor); |
| DCHECK(media_request_context); |
| return media_request_context; |
| } |
| |
| chrome_browser_net::Predictor* ProfileImplIOData::GetPredictor() { |
| return predictor_.get(); |
| } |
| |
| void ProfileImplIOData::ClearNetworkingHistorySinceOnIOThread( |
| base::Time time, |
| const base::Closure& completion) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| DCHECK(initialized()); |
| |
| DCHECK(transport_security_state()); |
| // Completes synchronously. |
| transport_security_state()->DeleteAllDynamicDataSince(time); |
| DCHECK(http_server_properties_manager_); |
| http_server_properties_manager_->Clear(completion); |
| } |