1 // Copyright (c) 2012 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.
5 #include "chrome/browser/profiles/profile_impl_io_data.h"
8 #include "base/command_line.h"
9 #include "base/logging.h"
10 #include "base/metrics/field_trial.h"
11 #include "base/prefs/pref_member.h"
12 #include "base/prefs/pref_service.h"
13 #include "base/sequenced_task_runner.h"
14 #include "base/stl_util.h"
15 #include "base/strings/string_util.h"
16 #include "base/threading/sequenced_worker_pool.h"
17 #include "base/threading/worker_pool.h"
18 #include "chrome/browser/chrome_notification_types.h"
19 #include "chrome/browser/chromeos/profiles/profile_helper.h"
20 #include "chrome/browser/custom_handlers/protocol_handler_registry.h"
21 #include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h"
22 #include "chrome/browser/io_thread.h"
23 #include "chrome/browser/net/chrome_net_log.h"
24 #include "chrome/browser/net/chrome_network_delegate.h"
25 #include "chrome/browser/net/connect_interceptor.h"
26 #include "chrome/browser/net/cookie_store_util.h"
27 #include "chrome/browser/net/http_server_properties_manager.h"
28 #include "chrome/browser/net/predictor.h"
29 #include "chrome/browser/net/sqlite_server_bound_cert_store.h"
30 #include "chrome/browser/profiles/profile.h"
31 #include "chrome/common/chrome_constants.h"
32 #include "chrome/common/chrome_switches.h"
33 #include "chrome/common/pref_names.h"
34 #include "chrome/common/url_constants.h"
35 #include "components/domain_reliability/monitor.h"
36 #include "content/public/browser/browser_thread.h"
37 #include "content/public/browser/cookie_store_factory.h"
38 #include "content/public/browser/notification_service.h"
39 #include "content/public/browser/resource_context.h"
40 #include "content/public/browser/storage_partition.h"
41 #include "extensions/browser/extension_protocols.h"
42 #include "extensions/common/constants.h"
43 #include "net/base/cache_type.h"
44 #include "net/ftp/ftp_network_layer.h"
45 #include "net/http/http_cache.h"
46 #include "net/ssl/server_bound_cert_service.h"
47 #include "net/url_request/url_request_job_factory_impl.h"
48 #include "webkit/browser/quota/special_storage_policy.h"
50 #if defined(OS_ANDROID) || defined(OS_IOS)
51 #if defined(SPDY_PROXY_AUTH_VALUE)
52 #include "components/data_reduction_proxy/browser/data_reduction_proxy_settings.h"
58 // Identifies Chrome as the source of Domain Reliability uploads it sends.
59 const char* kDomainReliabilityUploadReporterString
= "chrome";
61 net::BackendType
ChooseCacheBackendType() {
62 #if defined(OS_ANDROID)
63 return net::CACHE_BACKEND_SIMPLE
;
65 const CommandLine
& command_line
= *CommandLine::ForCurrentProcess();
66 if (command_line
.HasSwitch(switches::kUseSimpleCacheBackend
)) {
67 const std::string opt_value
=
68 command_line
.GetSwitchValueASCII(switches::kUseSimpleCacheBackend
);
69 if (LowerCaseEqualsASCII(opt_value
, "off"))
70 return net::CACHE_BACKEND_BLOCKFILE
;
71 if (opt_value
== "" || LowerCaseEqualsASCII(opt_value
, "on"))
72 return net::CACHE_BACKEND_SIMPLE
;
74 const std::string experiment_name
=
75 base::FieldTrialList::FindFullName("SimpleCacheTrial");
76 if (experiment_name
== "ExperimentYes" ||
77 experiment_name
== "ExperimentYes2") {
78 return net::CACHE_BACKEND_SIMPLE
;
80 return net::CACHE_BACKEND_BLOCKFILE
;
84 bool IsDomainReliabilityMonitoringEnabled() {
85 CommandLine
* command_line
= CommandLine::ForCurrentProcess();
86 if (command_line
->HasSwitch(switches::kDisableDomainReliability
))
88 if (command_line
->HasSwitch(switches::kEnableDomainReliability
))
90 return base::FieldTrialList::FindFullName("DomRel-Enable") == "enable";
95 using content::BrowserThread
;
97 ProfileImplIOData::Handle::Handle(Profile
* profile
)
98 : io_data_(new ProfileImplIOData
),
100 initialized_(false) {
101 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
105 ProfileImplIOData::Handle::~Handle() {
106 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
107 if (io_data_
->predictor_
!= NULL
) {
108 // io_data_->predictor_ might be NULL if Init() was never called
109 // (i.e. we shut down before ProfileImpl::DoFinalInit() got called).
110 bool save_prefs
= true;
111 #if defined(OS_CHROMEOS)
112 save_prefs
= !chromeos::ProfileHelper::IsSigninProfile(profile_
);
115 io_data_
->predictor_
->SaveStateForNextStartupAndTrim(
116 profile_
->GetPrefs());
118 io_data_
->predictor_
->ShutdownOnUIThread();
121 if (io_data_
->http_server_properties_manager_
)
122 io_data_
->http_server_properties_manager_
->ShutdownOnUIThread();
123 io_data_
->ShutdownOnUIThread();
126 void ProfileImplIOData::Handle::Init(
127 const base::FilePath
& cookie_path
,
128 const base::FilePath
& server_bound_cert_path
,
129 const base::FilePath
& cache_path
,
131 const base::FilePath
& media_cache_path
,
132 int media_cache_max_size
,
133 const base::FilePath
& extensions_cookie_path
,
134 const base::FilePath
& profile_path
,
135 const base::FilePath
& infinite_cache_path
,
136 chrome_browser_net::Predictor
* predictor
,
137 content::CookieStoreConfig::SessionCookieMode session_cookie_mode
,
138 quota::SpecialStoragePolicy
* special_storage_policy
) {
139 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
140 DCHECK(!io_data_
->lazy_params_
);
143 LazyParams
* lazy_params
= new LazyParams();
145 lazy_params
->cookie_path
= cookie_path
;
146 lazy_params
->server_bound_cert_path
= server_bound_cert_path
;
147 lazy_params
->cache_path
= cache_path
;
148 lazy_params
->cache_max_size
= cache_max_size
;
149 lazy_params
->media_cache_path
= media_cache_path
;
150 lazy_params
->media_cache_max_size
= media_cache_max_size
;
151 lazy_params
->extensions_cookie_path
= extensions_cookie_path
;
152 lazy_params
->infinite_cache_path
= infinite_cache_path
;
153 lazy_params
->session_cookie_mode
= session_cookie_mode
;
154 lazy_params
->special_storage_policy
= special_storage_policy
;
156 io_data_
->lazy_params_
.reset(lazy_params
);
158 // Keep track of profile path and cache sizes separately so we can use them
159 // on demand when creating storage isolated URLRequestContextGetters.
160 io_data_
->profile_path_
= profile_path
;
161 io_data_
->app_cache_max_size_
= cache_max_size
;
162 io_data_
->app_media_cache_max_size_
= media_cache_max_size
;
164 io_data_
->predictor_
.reset(predictor
);
166 io_data_
->InitializeMetricsEnabledStateOnUIThread();
169 content::ResourceContext
*
170 ProfileImplIOData::Handle::GetResourceContext() const {
171 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
173 return GetResourceContextNoInit();
176 content::ResourceContext
*
177 ProfileImplIOData::Handle::GetResourceContextNoInit() const {
178 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
179 // Don't call LazyInitialize here, since the resource context is created at
180 // the beginning of initalization and is used by some members while they're
181 // being initialized (i.e. AppCacheService).
182 return io_data_
->GetResourceContext();
185 scoped_refptr
<ChromeURLRequestContextGetter
>
186 ProfileImplIOData::Handle::CreateMainRequestContextGetter(
187 content::ProtocolHandlerMap
* protocol_handlers
,
188 content::URLRequestInterceptorScopedVector request_interceptors
,
189 PrefService
* local_state
,
190 IOThread
* io_thread
) const {
191 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
193 DCHECK(!main_request_context_getter_
.get());
194 main_request_context_getter_
= ChromeURLRequestContextGetter::Create(
195 profile_
, io_data_
, protocol_handlers
, request_interceptors
.Pass());
198 ->InitNetworkPredictor(profile_
->GetPrefs(),
201 main_request_context_getter_
.get());
203 content::NotificationService::current()->Notify(
204 chrome::NOTIFICATION_PROFILE_URL_REQUEST_CONTEXT_GETTER_INITIALIZED
,
205 content::Source
<Profile
>(profile_
),
206 content::NotificationService::NoDetails());
207 return main_request_context_getter_
;
210 scoped_refptr
<ChromeURLRequestContextGetter
>
211 ProfileImplIOData::Handle::GetMediaRequestContextGetter() const {
212 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
214 if (!media_request_context_getter_
.get()) {
215 media_request_context_getter_
=
216 ChromeURLRequestContextGetter::CreateForMedia(profile_
, io_data_
);
218 return media_request_context_getter_
;
221 scoped_refptr
<ChromeURLRequestContextGetter
>
222 ProfileImplIOData::Handle::GetExtensionsRequestContextGetter() const {
223 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
225 if (!extensions_request_context_getter_
.get()) {
226 extensions_request_context_getter_
=
227 ChromeURLRequestContextGetter::CreateForExtensions(profile_
, io_data_
);
229 return extensions_request_context_getter_
;
232 scoped_refptr
<ChromeURLRequestContextGetter
>
233 ProfileImplIOData::Handle::CreateIsolatedAppRequestContextGetter(
234 const base::FilePath
& partition_path
,
236 content::ProtocolHandlerMap
* protocol_handlers
,
237 content::URLRequestInterceptorScopedVector request_interceptors
) const {
238 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
239 // Check that the partition_path is not the same as the base profile path. We
240 // expect isolated partition, which will never go to the default profile path.
241 CHECK(partition_path
!= profile_
->GetPath());
244 // Keep a map of request context getters, one per requested storage partition.
245 StoragePartitionDescriptor
descriptor(partition_path
, in_memory
);
246 ChromeURLRequestContextGetterMap::iterator iter
=
247 app_request_context_getter_map_
.find(descriptor
);
248 if (iter
!= app_request_context_getter_map_
.end())
251 scoped_ptr
<ProtocolHandlerRegistry::JobInterceptorFactory
>
252 protocol_handler_interceptor(
253 ProtocolHandlerRegistryFactory::GetForProfile(profile_
)->
254 CreateJobInterceptorFactory());
255 ChromeURLRequestContextGetter
* context
=
256 ChromeURLRequestContextGetter::CreateForIsolatedApp(
260 protocol_handler_interceptor
.Pass(),
262 request_interceptors
.Pass());
263 app_request_context_getter_map_
[descriptor
] = context
;
268 scoped_refptr
<ChromeURLRequestContextGetter
>
269 ProfileImplIOData::Handle::GetIsolatedMediaRequestContextGetter(
270 const base::FilePath
& partition_path
,
271 bool in_memory
) const {
272 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
273 // We must have a non-default path, or this will act like the default media
275 CHECK(partition_path
!= profile_
->GetPath());
278 // Keep a map of request context getters, one per requested storage partition.
279 StoragePartitionDescriptor
descriptor(partition_path
, in_memory
);
280 ChromeURLRequestContextGetterMap::iterator iter
=
281 isolated_media_request_context_getter_map_
.find(descriptor
);
282 if (iter
!= isolated_media_request_context_getter_map_
.end())
285 // Get the app context as the starting point for the media context, so that
286 // it uses the app's cookie store.
287 ChromeURLRequestContextGetterMap::const_iterator app_iter
=
288 app_request_context_getter_map_
.find(descriptor
);
289 DCHECK(app_iter
!= app_request_context_getter_map_
.end());
290 ChromeURLRequestContextGetter
* app_context
= app_iter
->second
.get();
291 ChromeURLRequestContextGetter
* context
=
292 ChromeURLRequestContextGetter::CreateForIsolatedMedia(
293 profile_
, app_context
, io_data_
, descriptor
);
294 isolated_media_request_context_getter_map_
[descriptor
] = context
;
299 DevToolsNetworkController
*
300 ProfileImplIOData::Handle::GetDevToolsNetworkController() const {
301 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
302 return io_data_
->network_controller();
305 void ProfileImplIOData::Handle::ClearNetworkingHistorySince(
307 const base::Closure
& completion
) {
308 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
311 BrowserThread::PostTask(
312 BrowserThread::IO
, FROM_HERE
,
314 &ProfileImplIOData::ClearNetworkingHistorySinceOnIOThread
,
315 base::Unretained(io_data_
),
320 void ProfileImplIOData::Handle::ClearDomainReliabilityMonitor(
321 domain_reliability::DomainReliabilityClearMode mode
,
322 const base::Closure
& completion
) {
323 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
326 BrowserThread::PostTask(
327 BrowserThread::IO
, FROM_HERE
,
329 &ProfileImplIOData::ClearDomainReliabilityMonitorOnIOThread
,
330 base::Unretained(io_data_
),
335 void ProfileImplIOData::Handle::LazyInitialize() const {
339 // Set initialized_ to true at the beginning in case any of the objects
340 // below try to get the ResourceContext pointer.
342 PrefService
* pref_service
= profile_
->GetPrefs();
343 io_data_
->http_server_properties_manager_
=
344 new chrome_browser_net::HttpServerPropertiesManager(pref_service
);
345 io_data_
->set_http_server_properties(
346 scoped_ptr
<net::HttpServerProperties
>(
347 io_data_
->http_server_properties_manager_
));
348 io_data_
->session_startup_pref()->Init(
349 prefs::kRestoreOnStartup
, pref_service
);
350 io_data_
->session_startup_pref()->MoveToThread(
351 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO
));
352 #if defined(FULL_SAFE_BROWSING) || defined(MOBILE_SAFE_BROWSING)
353 io_data_
->safe_browsing_enabled()->Init(prefs::kSafeBrowsingEnabled
,
355 io_data_
->safe_browsing_enabled()->MoveToThread(
356 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO
));
358 io_data_
->InitializeOnUIThread(profile_
);
361 ProfileImplIOData::LazyParams::LazyParams()
363 media_cache_max_size(0),
365 content::CookieStoreConfig::EPHEMERAL_SESSION_COOKIES
) {}
367 ProfileImplIOData::LazyParams::~LazyParams() {}
369 ProfileImplIOData::ProfileImplIOData()
370 : ProfileIOData(Profile::REGULAR_PROFILE
),
371 http_server_properties_manager_(NULL
),
372 app_cache_max_size_(0),
373 app_media_cache_max_size_(0) {
376 ProfileImplIOData::~ProfileImplIOData() {
377 DestroyResourceContext();
379 if (media_request_context_
)
380 media_request_context_
->AssertNoURLRequests();
383 void ProfileImplIOData::InitializeInternal(
384 ProfileParams
* profile_params
,
385 content::ProtocolHandlerMap
* protocol_handlers
,
386 content::URLRequestInterceptorScopedVector request_interceptors
) const {
387 ChromeURLRequestContext
* main_context
= main_request_context();
389 IOThread
* const io_thread
= profile_params
->io_thread
;
390 IOThread::Globals
* const io_thread_globals
= io_thread
->globals();
392 network_delegate()->set_predictor(predictor_
.get());
394 // Initialize context members.
396 ApplyProfileParamsToContext(main_context
);
398 if (http_server_properties_manager_
)
399 http_server_properties_manager_
->InitializeOnIOThread();
401 main_context
->set_transport_security_state(transport_security_state());
403 main_context
->set_net_log(io_thread
->net_log());
405 main_context
->set_network_delegate(network_delegate());
407 main_context
->set_http_server_properties(http_server_properties());
409 main_context
->set_host_resolver(
410 io_thread_globals
->host_resolver
.get());
411 main_context
->set_cert_transparency_verifier(
412 io_thread_globals
->cert_transparency_verifier
.get());
413 main_context
->set_http_auth_handler_factory(
414 io_thread_globals
->http_auth_handler_factory
.get());
416 main_context
->set_fraudulent_certificate_reporter(
417 fraudulent_certificate_reporter());
419 main_context
->set_throttler_manager(
420 io_thread_globals
->throttler_manager
.get());
422 main_context
->set_proxy_service(proxy_service());
424 scoped_refptr
<net::CookieStore
> cookie_store
= NULL
;
425 net::ServerBoundCertService
* server_bound_cert_service
= NULL
;
426 if (chrome_browser_net::ShouldUseInMemoryCookiesAndCache()) {
427 // Don't use existing cookies and use an in-memory store.
428 using content::CookieStoreConfig
;
429 cookie_store
= content::CreateCookieStore(CookieStoreConfig(
431 CookieStoreConfig::EPHEMERAL_SESSION_COOKIES
,
433 profile_params
->cookie_monster_delegate
.get()));
434 // Don't use existing server-bound certs and use an in-memory store.
435 server_bound_cert_service
= new net::ServerBoundCertService(
436 new net::DefaultServerBoundCertStore(NULL
),
437 base::WorkerPool::GetTaskRunner(true));
441 // setup cookie store
442 if (!cookie_store
.get()) {
443 DCHECK(!lazy_params_
->cookie_path
.empty());
445 content::CookieStoreConfig
cookie_config(
446 lazy_params_
->cookie_path
,
447 lazy_params_
->session_cookie_mode
,
448 lazy_params_
->special_storage_policy
.get(),
449 profile_params
->cookie_monster_delegate
.get());
450 cookie_config
.crypto_delegate
=
451 chrome_browser_net::GetCookieCryptoDelegate();
452 cookie_store
= content::CreateCookieStore(cookie_config
);
455 main_context
->set_cookie_store(cookie_store
.get());
457 // Setup server bound cert service.
458 if (!server_bound_cert_service
) {
459 DCHECK(!lazy_params_
->server_bound_cert_path
.empty());
461 scoped_refptr
<SQLiteServerBoundCertStore
> server_bound_cert_db
=
462 new SQLiteServerBoundCertStore(
463 lazy_params_
->server_bound_cert_path
,
464 BrowserThread::GetBlockingPool()->GetSequencedTaskRunner(
465 BrowserThread::GetBlockingPool()->GetSequenceToken()),
466 lazy_params_
->special_storage_policy
.get());
467 server_bound_cert_service
= new net::ServerBoundCertService(
468 new net::DefaultServerBoundCertStore(server_bound_cert_db
.get()),
469 base::WorkerPool::GetTaskRunner(true));
472 set_server_bound_cert_service(server_bound_cert_service
);
473 main_context
->set_server_bound_cert_service(server_bound_cert_service
);
475 net::HttpCache::DefaultBackend
* main_backend
=
476 new net::HttpCache::DefaultBackend(
478 ChooseCacheBackendType(),
479 lazy_params_
->cache_path
,
480 lazy_params_
->cache_max_size
,
481 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE
)
483 scoped_ptr
<net::HttpCache
> main_cache
= CreateMainHttpFactory(
484 profile_params
, main_backend
);
485 main_cache
->InitializeInfiniteCache(lazy_params_
->infinite_cache_path
);
487 #if defined(OS_ANDROID) || defined(OS_IOS)
488 #if defined(SPDY_PROXY_AUTH_VALUE)
489 data_reduction_proxy::DataReductionProxySettings::
490 InitDataReductionProxySession(
491 main_cache
->GetSession(),
492 io_thread_globals
->data_reduction_proxy_params
.get());
496 if (chrome_browser_net::ShouldUseInMemoryCookiesAndCache()) {
497 main_cache
->set_mode(
498 chrome_browser_net::IsCookieRecordMode() ?
499 net::HttpCache::RECORD
: net::HttpCache::PLAYBACK
);
502 main_http_factory_
.reset(main_cache
.release());
503 main_context
->set_http_transaction_factory(main_http_factory_
.get());
505 #if !defined(DISABLE_FTP_SUPPORT)
507 new net::FtpNetworkLayer(io_thread_globals
->host_resolver
.get()));
508 #endif // !defined(DISABLE_FTP_SUPPORT)
510 scoped_ptr
<net::URLRequestJobFactoryImpl
> main_job_factory(
511 new net::URLRequestJobFactoryImpl());
512 InstallProtocolHandlers(main_job_factory
.get(), protocol_handlers
);
513 main_job_factory_
= SetUpJobFactoryDefaults(
514 main_job_factory
.Pass(),
515 request_interceptors
.Pass(),
516 profile_params
->protocol_handler_interceptor
.Pass(),
519 main_context
->set_job_factory(main_job_factory_
.get());
521 #if defined(ENABLE_EXTENSIONS)
522 InitializeExtensionsRequestContext(profile_params
);
525 // Create a media request context based on the main context, but using a
526 // media cache. It shares the same job factory as the main context.
527 StoragePartitionDescriptor
details(profile_path_
, false);
528 media_request_context_
.reset(InitializeMediaRequestContext(main_context
,
531 if (IsDomainReliabilityMonitoringEnabled()) {
532 domain_reliability_monitor_
.reset(
533 new domain_reliability::DomainReliabilityMonitor(
534 main_context
, kDomainReliabilityUploadReporterString
));
535 domain_reliability_monitor_
->AddBakedInConfigs();
536 network_delegate()->set_domain_reliability_monitor(
537 domain_reliability_monitor_
.get());
540 lazy_params_
.reset();
543 void ProfileImplIOData::
544 InitializeExtensionsRequestContext(ProfileParams
* profile_params
) const {
545 ChromeURLRequestContext
* extensions_context
= extensions_request_context();
546 IOThread
* const io_thread
= profile_params
->io_thread
;
547 IOThread::Globals
* const io_thread_globals
= io_thread
->globals();
548 ApplyProfileParamsToContext(extensions_context
);
550 extensions_context
->set_transport_security_state(transport_security_state());
552 extensions_context
->set_net_log(io_thread
->net_log());
554 extensions_context
->set_throttler_manager(
555 io_thread_globals
->throttler_manager
.get());
557 content::CookieStoreConfig
cookie_config(
558 lazy_params_
->extensions_cookie_path
,
559 lazy_params_
->session_cookie_mode
,
561 cookie_config
.crypto_delegate
=
562 chrome_browser_net::GetCookieCryptoDelegate();
563 net::CookieStore
* extensions_cookie_store
=
564 content::CreateCookieStore(cookie_config
);
565 // Enable cookies for devtools and extension URLs.
566 const char* schemes
[] = {content::kChromeDevToolsScheme
,
567 extensions::kExtensionScheme
};
568 extensions_cookie_store
->GetCookieMonster()->SetCookieableSchemes(schemes
, 2);
569 extensions_context
->set_cookie_store(extensions_cookie_store
);
571 scoped_ptr
<net::URLRequestJobFactoryImpl
> extensions_job_factory(
572 new net::URLRequestJobFactoryImpl());
573 // TODO(shalev): The extensions_job_factory has a NULL NetworkDelegate.
574 // Without a network_delegate, this protocol handler will never
575 // handle file: requests, but as a side effect it makes
576 // job_factory::IsHandledProtocol return true, which prevents attempts to
577 // handle the protocol externally. We pass NULL in to
578 // SetUpJobFactory() to get this effect.
579 extensions_job_factory_
= SetUpJobFactoryDefaults(
580 extensions_job_factory
.Pass(),
581 content::URLRequestInterceptorScopedVector(),
582 scoped_ptr
<ProtocolHandlerRegistry::JobInterceptorFactory
>(),
585 extensions_context
->set_job_factory(extensions_job_factory_
.get());
588 ChromeURLRequestContext
* ProfileImplIOData::InitializeAppRequestContext(
589 ChromeURLRequestContext
* main_context
,
590 const StoragePartitionDescriptor
& partition_descriptor
,
591 scoped_ptr
<ProtocolHandlerRegistry::JobInterceptorFactory
>
592 protocol_handler_interceptor
,
593 content::ProtocolHandlerMap
* protocol_handlers
,
594 content::URLRequestInterceptorScopedVector request_interceptors
) const {
595 // Copy most state from the main context.
596 AppRequestContext
* context
= new AppRequestContext();
597 context
->CopyFrom(main_context
);
599 base::FilePath cookie_path
= partition_descriptor
.path
.Append(
600 chrome::kCookieFilename
);
601 base::FilePath cache_path
=
602 partition_descriptor
.path
.Append(chrome::kCacheDirname
);
604 // Use a separate HTTP disk cache for isolated apps.
605 net::HttpCache::BackendFactory
* app_backend
= NULL
;
606 if (partition_descriptor
.in_memory
) {
607 app_backend
= net::HttpCache::DefaultBackend::InMemory(0);
609 app_backend
= new net::HttpCache::DefaultBackend(
611 ChooseCacheBackendType(),
614 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE
)
617 net::HttpNetworkSession
* main_network_session
=
618 main_http_factory_
->GetSession();
619 scoped_ptr
<net::HttpCache
> app_http_cache
=
620 CreateHttpFactory(main_network_session
, app_backend
);
622 scoped_refptr
<net::CookieStore
> cookie_store
= NULL
;
623 if (partition_descriptor
.in_memory
) {
624 cookie_store
= content::CreateCookieStore(content::CookieStoreConfig());
625 } else if (chrome_browser_net::ShouldUseInMemoryCookiesAndCache()) {
626 // Don't use existing cookies and use an in-memory store.
627 // TODO(creis): We should have a cookie delegate for notifying the cookie
628 // extensions API, but we need to update it to understand isolated apps
630 cookie_store
= content::CreateCookieStore(content::CookieStoreConfig());
631 app_http_cache
->set_mode(
632 chrome_browser_net::IsCookieRecordMode() ?
633 net::HttpCache::RECORD
: net::HttpCache::PLAYBACK
);
636 // Use an app-specific cookie store.
637 if (!cookie_store
.get()) {
638 DCHECK(!cookie_path
.empty());
640 // TODO(creis): We should have a cookie delegate for notifying the cookie
641 // extensions API, but we need to update it to understand isolated apps
643 content::CookieStoreConfig
cookie_config(
645 content::CookieStoreConfig::EPHEMERAL_SESSION_COOKIES
,
647 cookie_config
.crypto_delegate
=
648 chrome_browser_net::GetCookieCryptoDelegate();
649 cookie_store
= content::CreateCookieStore(cookie_config
);
652 // Transfer ownership of the cookies and cache to AppRequestContext.
653 context
->SetCookieStore(cookie_store
.get());
654 context
->SetHttpTransactionFactory(
655 scoped_ptr
<net::HttpTransactionFactory
>(
656 app_http_cache
.PassAs
<net::HttpTransactionFactory
>()));
658 scoped_ptr
<net::URLRequestJobFactoryImpl
> job_factory(
659 new net::URLRequestJobFactoryImpl());
660 InstallProtocolHandlers(job_factory
.get(), protocol_handlers
);
661 scoped_ptr
<net::URLRequestJobFactory
> top_job_factory(
662 SetUpJobFactoryDefaults(job_factory
.Pass(),
663 request_interceptors
.Pass(),
664 protocol_handler_interceptor
.Pass(),
666 ftp_factory_
.get()));
667 context
->SetJobFactory(top_job_factory
.Pass());
672 ChromeURLRequestContext
*
673 ProfileImplIOData::InitializeMediaRequestContext(
674 ChromeURLRequestContext
* original_context
,
675 const StoragePartitionDescriptor
& partition_descriptor
) const {
676 // Copy most state from the original context.
677 MediaRequestContext
* context
= new MediaRequestContext();
678 context
->CopyFrom(original_context
);
680 // For in-memory context, return immediately after creating the new
681 // context before attaching a separate cache. It is important to return
682 // a new context rather than just reusing |original_context| because
683 // the caller expects to take ownership of the pointer.
684 if (partition_descriptor
.in_memory
)
687 using content::StoragePartition
;
688 base::FilePath cache_path
;
689 int cache_max_size
= app_media_cache_max_size_
;
690 if (partition_descriptor
.path
== profile_path_
) {
691 // lazy_params_ is only valid for the default media context creation.
692 cache_path
= lazy_params_
->media_cache_path
;
693 cache_max_size
= lazy_params_
->media_cache_max_size
;
695 cache_path
= partition_descriptor
.path
.Append(chrome::kMediaCacheDirname
);
698 // Use a separate HTTP disk cache for isolated apps.
699 net::HttpCache::BackendFactory
* media_backend
=
700 new net::HttpCache::DefaultBackend(
702 ChooseCacheBackendType(),
705 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE
)
707 net::HttpNetworkSession
* main_network_session
=
708 main_http_factory_
->GetSession();
709 scoped_ptr
<net::HttpCache
> media_http_cache
=
710 CreateHttpFactory(main_network_session
, media_backend
);
712 // Transfer ownership of the cache to MediaRequestContext.
713 context
->SetHttpTransactionFactory(
714 media_http_cache
.PassAs
<net::HttpTransactionFactory
>());
716 // Note that we do not create a new URLRequestJobFactory because
717 // the media context should behave exactly like its parent context
718 // in all respects except for cache behavior on media subresources.
719 // The CopyFrom() step above means that our media context will use
720 // the same URLRequestJobFactory instance that our parent context does.
725 ChromeURLRequestContext
*
726 ProfileImplIOData::AcquireMediaRequestContext() const {
727 DCHECK(media_request_context_
);
728 return media_request_context_
.get();
731 ChromeURLRequestContext
* ProfileImplIOData::AcquireIsolatedAppRequestContext(
732 ChromeURLRequestContext
* main_context
,
733 const StoragePartitionDescriptor
& partition_descriptor
,
734 scoped_ptr
<ProtocolHandlerRegistry::JobInterceptorFactory
>
735 protocol_handler_interceptor
,
736 content::ProtocolHandlerMap
* protocol_handlers
,
737 content::URLRequestInterceptorScopedVector request_interceptors
) const {
738 // We create per-app contexts on demand, unlike the others above.
739 ChromeURLRequestContext
* app_request_context
=
740 InitializeAppRequestContext(main_context
,
741 partition_descriptor
,
742 protocol_handler_interceptor
.Pass(),
744 request_interceptors
.Pass());
745 DCHECK(app_request_context
);
746 return app_request_context
;
749 ChromeURLRequestContext
*
750 ProfileImplIOData::AcquireIsolatedMediaRequestContext(
751 ChromeURLRequestContext
* app_context
,
752 const StoragePartitionDescriptor
& partition_descriptor
) const {
753 // We create per-app media contexts on demand, unlike the others above.
754 ChromeURLRequestContext
* media_request_context
=
755 InitializeMediaRequestContext(app_context
, partition_descriptor
);
756 DCHECK(media_request_context
);
757 return media_request_context
;
760 void ProfileImplIOData::ClearNetworkingHistorySinceOnIOThread(
762 const base::Closure
& completion
) {
763 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
764 DCHECK(initialized());
766 DCHECK(transport_security_state());
767 // Completes synchronously.
768 transport_security_state()->DeleteAllDynamicDataSince(time
);
769 DCHECK(http_server_properties_manager_
);
770 http_server_properties_manager_
->Clear(completion
);
773 void ProfileImplIOData::ClearDomainReliabilityMonitorOnIOThread(
774 domain_reliability::DomainReliabilityClearMode mode
,
775 const base::Closure
& completion
) {
776 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
777 DCHECK(initialized());
779 if (domain_reliability_monitor_
)
780 domain_reliability_monitor_
->ClearBrowsingData(mode
);
782 BrowserThread::PostTask(BrowserThread::UI
, FROM_HERE
, completion
);