diff options
author | ajwong@chromium.org <ajwong@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-21 02:31:18 +0000 |
---|---|---|
committer | ajwong@chromium.org <ajwong@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-21 02:31:18 +0000 |
commit | e79b1d5a6edc56613e099fcd8fb75a05f501fc71 (patch) | |
tree | a118f4edf3f2aee250af4e71ee8493bcde5629ab | |
parent | 8643f2d60717c84be350040d553ea04dda4d6f21 (diff) | |
download | chromium_src-e79b1d5a6edc56613e099fcd8fb75a05f501fc71.zip chromium_src-e79b1d5a6edc56613e099fcd8fb75a05f501fc71.tar.gz chromium_src-e79b1d5a6edc56613e099fcd8fb75a05f501fc71.tar.bz2 |
Create a new URLRequestJobFactory for isolated request contexts.
Also includes unittest from tzik@:
http://codereview.chromium.org/10956009/
Originally the isolated URLRequestContexts used the same URLRequestJobFactory instance as the "default" request context. This breaks filesystem: because the isolated context would incorrectly dispatch to FileSystemContext of the default URLRequestContext.
This CL makes it so the isolated contexts do not share the same URLRequestJobFactory. There is now one URLRequestJobFactory per StoragePartition (the code equiv of one isolated context). Note that each RequestContext and MediaRequestContext pair still share the same URLRequestJobFactory. This is safe because they are in the isolation domain.
High level changes are:
- Each URLRequestJobFactory needs its own protocol_handler_interceptor
which requires threading the parameter through all the
URLRequestContext factory mess because this particular
object must be created on the UI thread.
- GetIsolatedMediaRequestContext no longer looks up the
app context out of the profile. Instead
GetIsolatedMediaRequestContextGetter() does this. This
makes it a little clearer that it is really a thin facade
over the related isolated context.
- The common code for URLJobFactory creation is pulled
up into SetUpJobFactoryDefaults out of both
off_the_record and the normal profile_impl. This will
avoid future divergence of the setup.
- FtpProtocolHandler also moved into SetUpJobFactoryDefaults.
Again, this is just to avoid future divergence.
- Lots of ownership passing moved to scoped_ptr<> to
be more explicit. No functionality change here, but lots
of text churn.
TBR=finnur
BUG=150861
Review URL: https://codereview.chromium.org/10969017
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@157900 0039d316-1c4b-4281-b951-d872f2087c98
14 files changed, 348 insertions, 189 deletions
diff --git a/chrome/browser/extensions/extension_fileapi_apitest.cc b/chrome/browser/extensions/extension_fileapi_apitest.cc index 43c77f6..6151e04 100644 --- a/chrome/browser/extensions/extension_fileapi_apitest.cc +++ b/chrome/browser/extensions/extension_fileapi_apitest.cc @@ -7,3 +7,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, DISABLED_FileAPI) { ASSERT_TRUE(RunExtensionTest("fileapi")) << message_; } + +IN_PROC_BROWSER_TEST_F(ExtensionApiTest, XHROnPersistentFileSystem) { + ASSERT_TRUE(RunPlatformAppTest("xhr_persistent_fs")) << message_; +} diff --git a/chrome/browser/net/chrome_url_request_context.cc b/chrome/browser/net/chrome_url_request_context.cc index 6b8bbc8..293a580 100644 --- a/chrome/browser/net/chrome_url_request_context.cc +++ b/chrome/browser/net/chrome_url_request_context.cc @@ -76,15 +76,23 @@ class FactoryForIsolatedApp : public ChromeURLRequestContextFactory { public: FactoryForIsolatedApp(const ProfileIOData* profile_io_data, const std::string& app_id, - ChromeURLRequestContextGetter* main_context) + ChromeURLRequestContextGetter* main_context, + scoped_ptr<net::URLRequestJobFactory::Interceptor> + protocol_handler_interceptor) : profile_io_data_(profile_io_data), app_id_(app_id), - main_request_context_getter_(main_context) {} + main_request_context_getter_(main_context), + protocol_handler_interceptor_(protocol_handler_interceptor.Pass()) {} virtual ChromeURLRequestContext* Create() OVERRIDE { // We will copy most of the state from the main request context. + // + // Note that this factory is one-shot. After Create() is called once, the + // factory is actually destroyed. Thus it is safe to destructively pass + // state onwards. return profile_io_data_->GetIsolatedAppRequestContext( - main_request_context_getter_->GetIOContext(), app_id_); + main_request_context_getter_->GetIOContext(), app_id_, + protocol_handler_interceptor_.Pass()); } private: @@ -92,33 +100,36 @@ class FactoryForIsolatedApp : public ChromeURLRequestContextFactory { const std::string app_id_; scoped_refptr<ChromeURLRequestContextGetter> main_request_context_getter_; + scoped_ptr<net::URLRequestJobFactory::Interceptor> + protocol_handler_interceptor_; }; // Factory that creates the media ChromeURLRequestContext for a given isolated // app. The media context is based on the corresponding isolated app's context. -// Takes the |main_context| for the profile so that it can find or create the -// isolated app's context if necessary. class FactoryForIsolatedMedia : public ChromeURLRequestContextFactory { public: FactoryForIsolatedMedia(const ProfileIOData* profile_io_data, const std::string& app_id, - ChromeURLRequestContextGetter* main_context) + ChromeURLRequestContextGetter* app_context) : profile_io_data_(profile_io_data), app_id_(app_id), - main_request_context_getter_(main_context) {} + app_context_getter_(app_context) {} virtual ChromeURLRequestContext* Create() OVERRIDE { // We will copy most of the state from the corresopnding app's - // request context, which we obtain using the main context. + // request context. We expect to have the same lifetime as + // the associated |app_context_getter_| so we can just reuse + // all its backing objects, including the + // |protocol_handler_interceptor|. This is why the API + // looks different from FactoryForIsolatedApp's. return profile_io_data_->GetIsolatedMediaRequestContext( - main_request_context_getter_->GetIOContext(), app_id_); + app_context_getter_->GetIOContext(), app_id_); } private: const ProfileIOData* const profile_io_data_; const std::string app_id_; - scoped_refptr<ChromeURLRequestContextGetter> - main_request_context_getter_; + scoped_refptr<ChromeURLRequestContextGetter> app_context_getter_; }; // Factory that creates the ChromeURLRequestContext for media. @@ -214,27 +225,29 @@ ChromeURLRequestContextGetter* ChromeURLRequestContextGetter::CreateOriginalForIsolatedApp( Profile* profile, const ProfileIOData* profile_io_data, - const std::string& app_id) { + const std::string& app_id, + scoped_ptr<net::URLRequestJobFactory::Interceptor> + protocol_handler_interceptor) { DCHECK(!profile->IsOffTheRecord()); ChromeURLRequestContextGetter* main_context = static_cast<ChromeURLRequestContextGetter*>(profile->GetRequestContext()); return new ChromeURLRequestContextGetter( profile, - new FactoryForIsolatedApp(profile_io_data, app_id, main_context)); + new FactoryForIsolatedApp(profile_io_data, app_id, main_context, + protocol_handler_interceptor.Pass())); } // static ChromeURLRequestContextGetter* ChromeURLRequestContextGetter::CreateOriginalForIsolatedMedia( Profile* profile, + ChromeURLRequestContextGetter* app_context, const ProfileIOData* profile_io_data, const std::string& app_id) { DCHECK(!profile->IsOffTheRecord()); - ChromeURLRequestContextGetter* main_context = - static_cast<ChromeURLRequestContextGetter*>(profile->GetRequestContext()); return new ChromeURLRequestContextGetter( profile, - new FactoryForIsolatedMedia(profile_io_data, app_id, main_context)); + new FactoryForIsolatedMedia(profile_io_data, app_id, app_context)); } // static @@ -260,13 +273,16 @@ ChromeURLRequestContextGetter* ChromeURLRequestContextGetter::CreateOffTheRecordForIsolatedApp( Profile* profile, const ProfileIOData* profile_io_data, - const std::string& app_id) { + const std::string& app_id, + scoped_ptr<net::URLRequestJobFactory::Interceptor> + protocol_handler_interceptor) { DCHECK(profile->IsOffTheRecord()); ChromeURLRequestContextGetter* main_context = static_cast<ChromeURLRequestContextGetter*>(profile->GetRequestContext()); return new ChromeURLRequestContextGetter( profile, - new FactoryForIsolatedApp(profile_io_data, app_id, main_context)); + new FactoryForIsolatedApp(profile_io_data, app_id, main_context, + protocol_handler_interceptor.Pass())); } void ChromeURLRequestContextGetter::CleanupOnUIThread() { diff --git a/chrome/browser/net/chrome_url_request_context.h b/chrome/browser/net/chrome_url_request_context.h index 7d20f4e..3856dfa 100644 --- a/chrome/browser/net/chrome_url_request_context.h +++ b/chrome/browser/net/chrome_url_request_context.h @@ -13,6 +13,7 @@ #include "content/public/browser/notification_registrar.h" #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context_getter.h" +#include "net/url_request/url_request_job_factory.h" class ChromeURLDataManagerBackend; class ChromeURLRequestContextFactory; @@ -144,12 +145,15 @@ class ChromeURLRequestContextGetter : public net::URLRequestContextGetter, static ChromeURLRequestContextGetter* CreateOriginalForIsolatedApp( Profile* profile, const ProfileIOData* profile_io_data, - const std::string& app_id); + const std::string& app_id, + scoped_ptr<net::URLRequestJobFactory::Interceptor> + protocol_handler_interceptor); // Create an instance for an original profile for media with isolated // storage. This is expected to get called on UI thread. static ChromeURLRequestContextGetter* CreateOriginalForIsolatedMedia( Profile* profile, + ChromeURLRequestContextGetter* app_context, const ProfileIOData* profile_io_data, const std::string& app_id); @@ -168,7 +172,9 @@ class ChromeURLRequestContextGetter : public net::URLRequestContextGetter, static ChromeURLRequestContextGetter* CreateOffTheRecordForIsolatedApp( Profile* profile, const ProfileIOData* profile_io_data, - const std::string& app_id); + const std::string& app_id, + scoped_ptr<net::URLRequestJobFactory::Interceptor> + protocol_handler_interceptor); // Clean up UI thread resources. This is expected to get called on the UI // thread before the instance is deleted on the IO thread. diff --git a/chrome/browser/profiles/off_the_record_profile_io_data.cc b/chrome/browser/profiles/off_the_record_profile_io_data.cc index 0bdf74d..6cadb70 100644 --- a/chrome/browser/profiles/off_the_record_profile_io_data.cc +++ b/chrome/browser/profiles/off_the_record_profile_io_data.cc @@ -11,6 +11,8 @@ #include "base/threading/worker_pool.h" #include "build/build_config.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/custom_handlers/protocol_handler_registry.h" +#include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h" #include "chrome/browser/io_thread.h" #include "chrome/browser/net/about_protocol_handler.h" #include "chrome/browser/net/chrome_net_log.h" @@ -30,8 +32,6 @@ #include "net/http/http_cache.h" #include "net/http/http_network_session.h" #include "net/http/http_server_properties_impl.h" -#include "net/url_request/file_protocol_handler.h" -#include "net/url_request/ftp_protocol_handler.h" #include "net/url_request/url_request_job_factory_impl.h" #include "webkit/database/database_tracker.h" @@ -128,9 +128,13 @@ OffTheRecordProfileIOData::Handle::GetIsolatedAppRequestContextGetter( if (iter != app_request_context_getter_map_.end()) return iter->second; + scoped_ptr<net::URLRequestJobFactory::Interceptor> + protocol_handler_interceptor( + ProtocolHandlerRegistryFactory::GetForProfile(profile_)-> + CreateURLInterceptor()); ChromeURLRequestContextGetter* context = ChromeURLRequestContextGetter::CreateOffTheRecordForIsolatedApp( - profile_, io_data_, app_id); + profile_, io_data_, app_id, protocol_handler_interceptor.Pass()); app_request_context_getter_map_[app_id] = context; return context; @@ -229,50 +233,33 @@ void OffTheRecordProfileIOData::LazyInitializeInternal( ftp_factory_.reset( new net::FtpNetworkLayer(main_context->host_resolver())); main_context->set_ftp_transaction_factory(ftp_factory_.get()); + extensions_context->set_ftp_transaction_factory(ftp_factory_.get()); #endif // !defined(DISABLE_FTP_SUPPORT) main_context->set_chrome_url_data_manager_backend( chrome_url_data_manager_backend()); - main_job_factory_.reset(new net::URLRequestJobFactoryImpl); - extensions_job_factory_.reset(new net::URLRequestJobFactoryImpl); + main_job_factory_.reset(new net::URLRequestJobFactoryImpl()); + extensions_job_factory_.reset(new net::URLRequestJobFactoryImpl()); - int set_protocol = main_job_factory_->SetProtocolHandler( - chrome::kFileScheme, new net::FileProtocolHandler()); - DCHECK(set_protocol); - // TODO(shalev): The extension_job_factory_ has a NULL NetworkDelegate. + SetUpJobFactoryDefaults( + main_job_factory_.get(), + profile_params->protocol_handler_interceptor.Pass(), + network_delegate(), + main_context->ftp_transaction_factory(), + main_context->ftp_auth_cache()); + // 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. - set_protocol = extensions_job_factory_->SetProtocolHandler( - chrome::kFileScheme, new net::FileProtocolHandler()); - DCHECK(set_protocol); - - set_protocol = main_job_factory_->SetProtocolHandler( - chrome::kChromeDevToolsScheme, - CreateDevToolsProtocolHandler(chrome_url_data_manager_backend(), - network_delegate())); - DCHECK(set_protocol); - set_protocol = extensions_job_factory_->SetProtocolHandler( - chrome::kChromeDevToolsScheme, - CreateDevToolsProtocolHandler(chrome_url_data_manager_backend(), NULL)); - DCHECK(set_protocol); - - net::URLRequestJobFactory* job_factories[2]; - job_factories[0] = main_job_factory_.get(); - job_factories[1] = extensions_job_factory_.get(); - - net::FtpAuthCache* ftp_auth_caches[2]; - ftp_auth_caches[0] = main_context->ftp_auth_cache(); - ftp_auth_caches[1] = extensions_context->ftp_auth_cache(); - - for (int i = 0; i < 2; i++) { - SetUpJobFactoryDefaults(job_factories[i]); - job_factories[i]->SetProtocolHandler(chrome::kAboutScheme, - new net::AboutProtocolHandler()); - CreateFtpProtocolHandler(job_factories[i], ftp_auth_caches[i]); - } + // handle the protocol externally. We pass NULL in to + // SetUpJobFactoryDefaults() to get this effect. + SetUpJobFactoryDefaults( + extensions_job_factory_.get(), + scoped_ptr<net::URLRequestJobFactoryImpl::Interceptor>(NULL), + NULL, + extensions_context->ftp_transaction_factory(), + extensions_context->ftp_auth_cache()); main_context->set_job_factory(main_job_factory_.get()); extensions_context->set_job_factory(extensions_job_factory_.get()); @@ -281,7 +268,9 @@ void OffTheRecordProfileIOData::LazyInitializeInternal( ChromeURLRequestContext* OffTheRecordProfileIOData::InitializeAppRequestContext( ChromeURLRequestContext* main_context, - const std::string& app_id) const { + const std::string& app_id, + scoped_ptr<net::URLRequestJobFactory::Interceptor> + protocol_handler_interceptor) const { AppRequestContext* context = new AppRequestContext(load_time_stats()); // Copy most state from the main context. @@ -297,10 +286,19 @@ OffTheRecordProfileIOData::InitializeAppRequestContext( net::HttpCache::DefaultBackend::InMemory(0); net::HttpNetworkSession* main_network_session = main_http_factory_->GetSession(); - net::HttpCache* app_http_cache = - new net::HttpCache(main_network_session, app_backend); - - context->SetHttpTransactionFactory(app_http_cache); + scoped_ptr<net::HttpTransactionFactory> app_http_cache( + new net::HttpCache(main_network_session, app_backend)); + + context->SetHttpTransactionFactory(app_http_cache.Pass()); + + scoped_ptr<net::URLRequestJobFactory> job_factory( + new net::URLRequestJobFactoryImpl()); + SetUpJobFactoryDefaults(job_factory.get(), + protocol_handler_interceptor.Pass(), + network_delegate(), + context->ftp_transaction_factory(), + context->ftp_auth_cache()); + context->SetJobFactory(job_factory.Pass()); return context; } @@ -321,10 +319,13 @@ OffTheRecordProfileIOData::AcquireMediaRequestContext() const { ChromeURLRequestContext* OffTheRecordProfileIOData::AcquireIsolatedAppRequestContext( ChromeURLRequestContext* main_context, - const std::string& app_id) const { + const std::string& app_id, + scoped_ptr<net::URLRequestJobFactory::Interceptor> + protocol_handler_interceptor) const { // We create per-app contexts on demand, unlike the others above. ChromeURLRequestContext* app_request_context = - InitializeAppRequestContext(main_context, app_id); + InitializeAppRequestContext(main_context, app_id, + protocol_handler_interceptor.Pass()); DCHECK(app_request_context); return app_request_context; } @@ -337,16 +338,6 @@ OffTheRecordProfileIOData::AcquireIsolatedMediaRequestContext( return NULL; } -void OffTheRecordProfileIOData::CreateFtpProtocolHandler( - net::URLRequestJobFactory* job_factory, - net::FtpAuthCache* ftp_auth_cache) const { -#if !defined(DISABLE_FTP_SUPPORT) - job_factory->SetProtocolHandler( - chrome::kFtpScheme, - new net::FtpProtocolHandler(ftp_factory_.get(), ftp_auth_cache)); -#endif // !defined(DISABLE_FTP_SUPPORT) -} - chrome_browser_net::LoadTimeStats* OffTheRecordProfileIOData::GetLoadTimeStats( IOThread::Globals* io_thread_globals) const { return NULL; diff --git a/chrome/browser/profiles/off_the_record_profile_io_data.h b/chrome/browser/profiles/off_the_record_profile_io_data.h index 4d83990..ca5c304 100644 --- a/chrome/browser/profiles/off_the_record_profile_io_data.h +++ b/chrome/browser/profiles/off_the_record_profile_io_data.h @@ -99,7 +99,9 @@ class OffTheRecordProfileIOData : public ProfileIOData { ProfileParams* profile_params) const OVERRIDE; virtual ChromeURLRequestContext* InitializeAppRequestContext( ChromeURLRequestContext* main_context, - const std::string& app_id) const OVERRIDE; + const std::string& app_id, + scoped_ptr<net::URLRequestJobFactory::Interceptor> + protocol_handler_interceptor) const OVERRIDE; virtual ChromeURLRequestContext* InitializeMediaRequestContext( ChromeURLRequestContext* original_context, const std::string& app_id) const OVERRIDE; @@ -108,15 +110,14 @@ class OffTheRecordProfileIOData : public ProfileIOData { virtual ChromeURLRequestContext* AcquireIsolatedAppRequestContext( ChromeURLRequestContext* main_context, - const std::string& app_id) const OVERRIDE; + const std::string& app_id, + scoped_ptr<net::URLRequestJobFactory::Interceptor> + protocol_handler_interceptor) const OVERRIDE; virtual ChromeURLRequestContext* AcquireIsolatedMediaRequestContext( ChromeURLRequestContext* app_context, const std::string& app_id) const OVERRIDE; - void CreateFtpProtocolHandler(net::URLRequestJobFactory* job_factory, - net::FtpAuthCache* ftp_auth_cache) const; - virtual chrome_browser_net::LoadTimeStats* GetLoadTimeStats( IOThread::Globals* io_thread_globals) const OVERRIDE; diff --git a/chrome/browser/profiles/profile_impl_io_data.cc b/chrome/browser/profiles/profile_impl_io_data.cc index 4e7e378..6a8fc08 100644 --- a/chrome/browser/profiles/profile_impl_io_data.cc +++ b/chrome/browser/profiles/profile_impl_io_data.cc @@ -11,8 +11,9 @@ #include "base/stl_util.h" #include "base/threading/worker_pool.h" #include "chrome/browser/api/prefs/pref_member.h" +#include "chrome/browser/custom_handlers/protocol_handler_registry.h" +#include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h" #include "chrome/browser/io_thread.h" -#include "chrome/browser/net/about_protocol_handler.h" #include "chrome/browser/net/chrome_net_log.h" #include "chrome/browser/net/clear_on_exit_policy.h" #include "chrome/browser/net/connect_interceptor.h" @@ -35,8 +36,6 @@ #include "net/base/server_bound_cert_service.h" #include "net/ftp/ftp_network_layer.h" #include "net/http/http_cache.h" -#include "net/url_request/file_protocol_handler.h" -#include "net/url_request/ftp_protocol_handler.h" #include "net/url_request/url_request_job_factory_impl.h" #include "webkit/quota/special_storage_policy.h" @@ -220,9 +219,13 @@ ProfileImplIOData::Handle::GetIsolatedAppRequestContextGetter( if (iter != app_request_context_getter_map_.end()) return iter->second; + scoped_ptr<net::URLRequestJobFactory::Interceptor> + protocol_handler_interceptor( + ProtocolHandlerRegistryFactory::GetForProfile(profile_)-> + CreateURLInterceptor()); ChromeURLRequestContextGetter* context = ChromeURLRequestContextGetter::CreateOriginalForIsolatedApp( - profile_, io_data_, app_id); + profile_, io_data_, app_id, protocol_handler_interceptor.Pass()); app_request_context_getter_map_[app_id] = context; return context; @@ -242,9 +245,13 @@ ProfileImplIOData::Handle::GetIsolatedMediaRequestContextGetter( 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. + ChromeURLRequestContextGetter* app_context = + GetIsolatedAppRequestContextGetter(app_id); ChromeURLRequestContextGetter* context = ChromeURLRequestContextGetter::CreateOriginalForIsolatedMedia( - profile_, io_data_, app_id); + profile_, app_context, io_data_, app_id); isolated_media_request_context_getter_map_[app_id] = context; return context; @@ -430,6 +437,7 @@ void ProfileImplIOData::LazyInitializeInternal( ftp_factory_.reset( new net::FtpNetworkLayer(io_thread_globals->host_resolver.get())); main_context->set_ftp_transaction_factory(ftp_factory_.get()); + extensions_context->set_ftp_transaction_factory(ftp_factory_.get()); #endif // !defined(DISABLE_FTP_SUPPORT) main_context->set_chrome_url_data_manager_backend( @@ -443,54 +451,27 @@ void ProfileImplIOData::LazyInitializeInternal( media_request_job_factory_.reset(new net::URLRequestJobFactoryImpl); extensions_job_factory_.reset(new net::URLRequestJobFactoryImpl); - int set_protocol = main_job_factory_->SetProtocolHandler( - chrome::kFileScheme, new net::FileProtocolHandler()); - DCHECK(set_protocol); - set_protocol = media_request_job_factory_->SetProtocolHandler( - chrome::kFileScheme, new net::FileProtocolHandler()); - DCHECK(set_protocol); + SetUpJobFactory(main_job_factory_.get(), + profile_params->protocol_handler_interceptor.Pass(), + network_delegate(), + main_context->ftp_transaction_factory(), + main_context->ftp_auth_cache()); + SetUpJobFactory(media_request_job_factory_.get(), + scoped_ptr<net::URLRequestJobFactoryImpl::Interceptor>(NULL), + network_delegate(), + media_request_context_->ftp_transaction_factory(), + media_request_context_->ftp_auth_cache()); // 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. - set_protocol = extensions_job_factory_->SetProtocolHandler( - chrome::kFileScheme, new net::FileProtocolHandler()); - DCHECK(set_protocol); - - set_protocol = main_job_factory_->SetProtocolHandler( - chrome::kChromeDevToolsScheme, - CreateDevToolsProtocolHandler(chrome_url_data_manager_backend(), - network_delegate())); - DCHECK(set_protocol); - set_protocol = media_request_job_factory_->SetProtocolHandler( - chrome::kChromeDevToolsScheme, - CreateDevToolsProtocolHandler(chrome_url_data_manager_backend(), - network_delegate())); - DCHECK(set_protocol); - set_protocol = extensions_job_factory_->SetProtocolHandler( - chrome::kChromeDevToolsScheme, - CreateDevToolsProtocolHandler(chrome_url_data_manager_backend(), NULL)); - DCHECK(set_protocol); - - net::URLRequestJobFactory* job_factories[3]; - job_factories[0] = main_job_factory_.get(); - job_factories[1] = media_request_job_factory_.get(); - job_factories[2] = extensions_job_factory_.get(); - - net::FtpAuthCache* ftp_auth_caches[3]; - ftp_auth_caches[0] = main_context->ftp_auth_cache(); - ftp_auth_caches[1] = media_request_context_->ftp_auth_cache(); - ftp_auth_caches[2] = extensions_context->ftp_auth_cache(); - - for (int i = 0; i < 3; i++) { - SetUpJobFactoryDefaults(job_factories[i]); - job_factories[i]->SetProtocolHandler(chrome::kAboutScheme, - new net::AboutProtocolHandler()); - CreateFtpProtocolHandler(job_factories[i], ftp_auth_caches[i]); - job_factories[i]->AddInterceptor( - new chrome_browser_net::ConnectInterceptor(predictor_.get())); - } + // handle the protocol externally. We pass NULL in to + // SetUpJobFactory() to get this effect. + SetUpJobFactory(extensions_job_factory_.get(), + scoped_ptr<net::URLRequestJobFactoryImpl::Interceptor>(NULL), + NULL, + extensions_context->ftp_transaction_factory(), + extensions_context->ftp_auth_cache()); main_context->set_job_factory(main_job_factory_.get()); media_request_context_->set_job_factory(media_request_job_factory_.get()); @@ -502,7 +483,9 @@ void ProfileImplIOData::LazyInitializeInternal( ChromeURLRequestContext* ProfileImplIOData::InitializeAppRequestContext( ChromeURLRequestContext* main_context, - const std::string& app_id) const { + const std::string& app_id, + scoped_ptr<net::URLRequestJobFactory::Interceptor> + protocol_handler_interceptor) const { // If this is for a guest process, we should not persist cookies and http // cache. bool is_guest_process = (app_id.find("guest-") != std::string::npos); @@ -569,7 +552,18 @@ ProfileImplIOData::InitializeAppRequestContext( // Transfer ownership of the cookies and cache to AppRequestContext. context->SetCookieStore(cookie_store); - context->SetHttpTransactionFactory(app_http_cache); + context->SetHttpTransactionFactory( + scoped_ptr<net::HttpTransactionFactory>(app_http_cache)); + + // Overwrite the job factory that we inherit from the main context so + // that we can later provide our own handles for storage related protocols. + scoped_ptr<net::URLRequestJobFactory> job_factory( + new net::URLRequestJobFactoryImpl()); + SetUpJobFactory(job_factory.get(), protocol_handler_interceptor.Pass(), + network_delegate(), + context->ftp_transaction_factory(), + context->ftp_auth_cache()); + context->SetJobFactory(job_factory.Pass()); return context; } @@ -609,11 +603,17 @@ ProfileImplIOData::InitializeMediaRequestContext( BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE)); net::HttpNetworkSession* main_network_session = main_http_factory_->GetSession(); - net::HttpCache* media_http_cache = - new net::HttpCache(main_network_session, media_backend); + scoped_ptr<net::HttpTransactionFactory> media_http_cache( + new net::HttpCache(main_network_session, media_backend)); // Transfer ownership of the cache to MediaRequestContext. - context->SetHttpTransactionFactory(media_http_cache); + context->SetHttpTransactionFactory(media_http_cache.Pass()); + + // 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; } @@ -627,10 +627,13 @@ ProfileImplIOData::AcquireMediaRequestContext() const { ChromeURLRequestContext* ProfileImplIOData::AcquireIsolatedAppRequestContext( ChromeURLRequestContext* main_context, - const std::string& app_id) const { + const std::string& app_id, + scoped_ptr<net::URLRequestJobFactory::Interceptor> + protocol_handler_interceptor) const { // We create per-app contexts on demand, unlike the others above. ChromeURLRequestContext* app_request_context = - InitializeAppRequestContext(main_context, app_id); + InitializeAppRequestContext(main_context, app_id, + protocol_handler_interceptor.Pass()); DCHECK(app_request_context); return app_request_context; } @@ -651,15 +654,19 @@ chrome_browser_net::LoadTimeStats* ProfileImplIOData::GetLoadTimeStats( return io_thread_globals->load_time_stats.get(); } -void ProfileImplIOData::CreateFtpProtocolHandler( +void ProfileImplIOData::SetUpJobFactory( net::URLRequestJobFactory* job_factory, + scoped_ptr<net::URLRequestJobFactory::Interceptor> + protocol_handler_interceptor, + net::NetworkDelegate* network_delegate, + net::FtpTransactionFactory* ftp_transaction_factory, net::FtpAuthCache* ftp_auth_cache) const { -#if !defined(DISABLE_FTP_SUPPORT) - job_factory->SetProtocolHandler( - chrome::kFtpScheme, - new net::FtpProtocolHandler(ftp_factory_.get(), - ftp_auth_cache)); -#endif // !defined(DISABLE_FTP_SUPPORT) + SetUpJobFactoryDefaults(job_factory, protocol_handler_interceptor.Pass(), + network_delegate, ftp_transaction_factory, + ftp_auth_cache); + + job_factory->AddInterceptor( + new chrome_browser_net::ConnectInterceptor(predictor_.get())); } void ProfileImplIOData::ClearNetworkingHistorySinceOnIOThread( diff --git a/chrome/browser/profiles/profile_impl_io_data.h b/chrome/browser/profiles/profile_impl_io_data.h index d13d780..3988255 100644 --- a/chrome/browser/profiles/profile_impl_io_data.h +++ b/chrome/browser/profiles/profile_impl_io_data.h @@ -139,7 +139,9 @@ class ProfileImplIOData : public ProfileIOData { ProfileParams* profile_params) const OVERRIDE; virtual ChromeURLRequestContext* InitializeAppRequestContext( ChromeURLRequestContext* main_context, - const std::string& app_id) const OVERRIDE; + const std::string& app_id, + scoped_ptr<net::URLRequestJobFactory::Interceptor> + protocol_handler_interceptor) const OVERRIDE; virtual ChromeURLRequestContext* InitializeMediaRequestContext( ChromeURLRequestContext* original_context, const std::string& app_id) const OVERRIDE; @@ -148,7 +150,9 @@ class ProfileImplIOData : public ProfileIOData { virtual ChromeURLRequestContext* AcquireIsolatedAppRequestContext( ChromeURLRequestContext* main_context, - const std::string& app_id) const OVERRIDE; + const std::string& app_id, + scoped_ptr<net::URLRequestJobFactory::Interceptor> + protocol_handler_interceptor) const OVERRIDE; virtual ChromeURLRequestContext* AcquireIsolatedMediaRequestContext( ChromeURLRequestContext* app_context, @@ -156,8 +160,12 @@ class ProfileImplIOData : public ProfileIOData { virtual chrome_browser_net::LoadTimeStats* GetLoadTimeStats( IOThread::Globals* io_thread_globals) const OVERRIDE; - void CreateFtpProtocolHandler(net::URLRequestJobFactory* job_factory, - net::FtpAuthCache* ftp_auth_cache) const; + void SetUpJobFactory(net::URLRequestJobFactory* job_factory, + scoped_ptr<net::URLRequestJobFactory::Interceptor> + protocol_handler_interceptor, + net::NetworkDelegate* network_delegate, + net::FtpTransactionFactory* ftp_transaction_factory, + net::FtpAuthCache* ftp_auth_cache) const; // Clears the networking history since |time|. void ClearNetworkingHistorySinceOnIOThread(base::Time time); diff --git a/chrome/browser/profiles/profile_io_data.cc b/chrome/browser/profiles/profile_io_data.cc index 74f94d8..86e8045 100644 --- a/chrome/browser/profiles/profile_io_data.cc +++ b/chrome/browser/profiles/profile_io_data.cc @@ -17,6 +17,7 @@ #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" @@ -62,6 +63,8 @@ #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) @@ -190,10 +193,10 @@ void ProfileIOData::InitializeOnUIThread(Profile* profile) { ProtocolHandlerRegistryFactory::GetForProfile(profile); DCHECK(protocol_handler_registry); - // the profile instance is only available here in the InitializeOnUIThread + // 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_url_interceptor.reset( + // later delivery to the job factory in LazyInitialize. + params->protocol_handler_interceptor.reset( protocol_handler_registry->CreateURLInterceptor()); ChromeProxyConfigService* proxy_config_service = @@ -238,9 +241,9 @@ ProfileIOData::MediaRequestContext::MediaRequestContext( } void ProfileIOData::MediaRequestContext::SetHttpTransactionFactory( - net::HttpTransactionFactory* http_factory) { - http_factory_.reset(http_factory); - set_http_transaction_factory(http_factory); + scoped_ptr<net::HttpTransactionFactory> http_factory) { + http_factory_ = http_factory.Pass(); + set_http_transaction_factory(http_factory_.get()); } ProfileIOData::MediaRequestContext::~MediaRequestContext() {} @@ -258,9 +261,15 @@ void ProfileIOData::AppRequestContext::SetCookieStore( } void ProfileIOData::AppRequestContext::SetHttpTransactionFactory( - net::HttpTransactionFactory* http_factory) { - http_factory_.reset(http_factory); - set_http_transaction_factory(http_factory); + scoped_ptr<net::HttpTransactionFactory> http_factory) { + http_factory_ = http_factory.Pass(); + set_http_transaction_factory(http_factory_.get()); +} + +void ProfileIOData::AppRequestContext::SetJobFactory( + scoped_ptr<net::URLRequestJobFactory> job_factory) { + job_factory_ = job_factory.Pass(); + set_job_factory(job_factory_.get()); } ProfileIOData::AppRequestContext::~AppRequestContext() {} @@ -376,13 +385,16 @@ ProfileIOData::GetExtensionsRequestContext() const { ChromeURLRequestContext* ProfileIOData::GetIsolatedAppRequestContext( ChromeURLRequestContext* main_context, - const std::string& app_id) const { + const std::string& app_id, + scoped_ptr<net::URLRequestJobFactory::Interceptor> + 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); + context = AcquireIsolatedAppRequestContext( + main_context, app_id, protocol_handler_interceptor.Pass()); app_request_context_map_[app_id] = context; } DCHECK(context); @@ -391,17 +403,13 @@ ProfileIOData::GetIsolatedAppRequestContext( ChromeURLRequestContext* ProfileIOData::GetIsolatedMediaRequestContext( - ChromeURLRequestContext* main_context, + 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 { - // Get the app context as the starting point for the media context, - // so that it uses the app's cookie store. - ChromeURLRequestContext* app_context = GetIsolatedAppRequestContext( - main_context, app_id); context = AcquireIsolatedMediaRequestContext(app_context, app_id); isolated_media_request_context_map_[app_id] = context; } @@ -591,19 +599,31 @@ void ProfileIOData::ApplyProfileParamsToContext( } void ProfileIOData::SetUpJobFactoryDefaults( - net::URLRequestJobFactory* job_factory) const { + net::URLRequestJobFactory* job_factory, + scoped_ptr<net::URLRequestJobFactory::Interceptor> + 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); - if (profile_params_->protocol_handler_url_interceptor.get()) { - job_factory->AddInterceptor( - profile_params_->protocol_handler_url_interceptor.release()); + 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()); } - bool set_protocol = job_factory->SetProtocolHandler( + set_protocol = job_factory->SetProtocolHandler( chrome::kExtensionScheme, - CreateExtensionProtocolHandler(is_incognito(), - profile_params_->extension_info_map)); + CreateExtensionProtocolHandler(is_incognito(), GetExtensionInfoMap())); DCHECK(set_protocol); set_protocol = job_factory->SetProtocolHandler( chrome::kExtensionResourceScheme, @@ -631,6 +651,16 @@ void ProfileIOData::SetUpJobFactoryDefaults( 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() { diff --git a/chrome/browser/profiles/profile_io_data.h b/chrome/browser/profiles/profile_io_data.h index 22e381f..65a94f6 100644 --- a/chrome/browser/profiles/profile_io_data.h +++ b/chrome/browser/profiles/profile_io_data.h @@ -82,9 +82,11 @@ class ProfileIOData { ChromeURLRequestContext* GetExtensionsRequestContext() const; ChromeURLRequestContext* GetIsolatedAppRequestContext( ChromeURLRequestContext* main_context, - const std::string& app_id) const; + const std::string& app_id, + scoped_ptr<net::URLRequestJobFactory::Interceptor> + protocol_handler_interceptor) const; ChromeURLRequestContext* GetIsolatedMediaRequestContext( - ChromeURLRequestContext* media_context, + ChromeURLRequestContext* app_context, const std::string& app_id) const; // These are useful when the Chrome layer is called from the content layer @@ -146,7 +148,8 @@ class ProfileIOData { explicit MediaRequestContext( chrome_browser_net::LoadTimeStats* load_time_stats); - void SetHttpTransactionFactory(net::HttpTransactionFactory* http_factory); + void SetHttpTransactionFactory( + scoped_ptr<net::HttpTransactionFactory> http_factory); private: virtual ~MediaRequestContext(); @@ -162,13 +165,16 @@ class ProfileIOData { chrome_browser_net::LoadTimeStats* load_time_stats); void SetCookieStore(net::CookieStore* cookie_store); - void SetHttpTransactionFactory(net::HttpTransactionFactory* http_factory); + void SetHttpTransactionFactory( + scoped_ptr<net::HttpTransactionFactory> http_factory); + void SetJobFactory(scoped_ptr<net::URLRequestJobFactory> job_factory); private: virtual ~AppRequestContext(); scoped_refptr<net::CookieStore> cookie_store_; scoped_ptr<net::HttpTransactionFactory> http_factory_; + scoped_ptr<net::URLRequestJobFactory> job_factory_; }; // Created on the UI thread, read on the IO thread during ProfileIOData lazy @@ -198,7 +204,7 @@ class ProfileIOData { // the URLRequestJobFactory on the IO thread. The consumer MUST take // ownership of the object by calling release() on this pointer. scoped_ptr<net::URLRequestJobFactory::Interceptor> - protocol_handler_url_interceptor; + protocol_handler_interceptor; // We need to initialize the ProxyConfigService from the UI thread // because on linux it relies on initializing things through gconf, @@ -217,7 +223,13 @@ class ProfileIOData { void InitializeOnUIThread(Profile* profile); void ApplyProfileParamsToContext(ChromeURLRequestContext* context) const; - void SetUpJobFactoryDefaults(net::URLRequestJobFactory* job_factory) const; + void SetUpJobFactoryDefaults( + net::URLRequestJobFactory* job_factory, + scoped_ptr<net::URLRequestJobFactory::Interceptor> + protocol_handler_interceptor, + net::NetworkDelegate* network_delegate, + net::FtpTransactionFactory* ftp_transaction_factory, + net::FtpAuthCache* ftp_auth_cache) const; // Lazy initializes the ProfileIOData object the first time a request context // is requested. The lazy logic is implemented here. The actual initialization @@ -309,7 +321,9 @@ class ProfileIOData { // isolated app. virtual ChromeURLRequestContext* InitializeAppRequestContext( ChromeURLRequestContext* main_context, - const std::string& app_id) const = 0; + const std::string& app_id, + scoped_ptr<net::URLRequestJobFactory::Interceptor> + protocol_handler_interceptor) const = 0; // Does an on-demand initialization of a media RequestContext for the given // isolated app. @@ -324,7 +338,9 @@ class ProfileIOData { virtual ChromeURLRequestContext* AcquireIsolatedAppRequestContext( ChromeURLRequestContext* main_context, - const std::string& app_id) const = 0; + const std::string& app_id, + scoped_ptr<net::URLRequestJobFactory::Interceptor> + protocol_handler_interceptor) const = 0; virtual ChromeURLRequestContext* AcquireIsolatedMediaRequestContext( ChromeURLRequestContext* app_context, @@ -375,6 +391,7 @@ class ProfileIOData { mutable scoped_ptr<policy::URLBlacklistManager> url_blacklist_manager_; // Pointed to by URLRequestContext. + mutable scoped_refptr<ExtensionInfoMap> extension_info_map_; mutable scoped_ptr<ChromeURLDataManagerBackend> chrome_url_data_manager_backend_; mutable scoped_ptr<net::ServerBoundCertService> server_bound_cert_service_; @@ -403,7 +420,6 @@ class ProfileIOData { mutable scoped_ptr<ResourceContext> resource_context_; - mutable scoped_refptr<ExtensionInfoMap> extension_info_map_; mutable scoped_refptr<CookieSettings> cookie_settings_; mutable scoped_ptr<chrome_browser_net::ResourcePrefetchPredictorObserver> diff --git a/chrome/test/data/extensions/api_test/xhr_persistent_fs/bg.js b/chrome/test/data/extensions/api_test/xhr_persistent_fs/bg.js new file mode 100644 index 0000000..3d6bffa --- /dev/null +++ b/chrome/test/data/extensions/api_test/xhr_persistent_fs/bg.js @@ -0,0 +1,7 @@ +// 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. + +chrome.app.runtime.onLaunched.addListener(function() { + chrome.app.window.create('main.html', {}, function () {}); +}); diff --git a/chrome/test/data/extensions/api_test/xhr_persistent_fs/main.html b/chrome/test/data/extensions/api_test/xhr_persistent_fs/main.html new file mode 100644 index 0000000..bff2b38 --- /dev/null +++ b/chrome/test/data/extensions/api_test/xhr_persistent_fs/main.html @@ -0,0 +1,7 @@ +<!DOCTYPE html> +<!-- + 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. +--> +<script src="main.js"></script> diff --git a/chrome/test/data/extensions/api_test/xhr_persistent_fs/main.js b/chrome/test/data/extensions/api_test/xhr_persistent_fs/main.js new file mode 100644 index 0000000..ddb4ab9 --- /dev/null +++ b/chrome/test/data/extensions/api_test/xhr_persistent_fs/main.js @@ -0,0 +1,43 @@ +// 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. + +function createFile() { + webkitRequestFileSystem(window.PERSISTENT, 1024, gotFS, fail); +}; + +function gotFS(fs) { + fs.root.getFile("hoge", {create: true, exclusive: false}, gotFileEntry, fail); +} + +function gotFileEntry(entry) { + entry.createWriter(gotWriter.bind(null, entry), fail); +} + +function gotWriter(entry, writer) { + writer.write(new Blob(["fuga"])); + writer.onwrite = didWrite.bind(null, entry); + writer.onerror = fail; +} + +function didWrite(entry) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", entry.toURL()); + xhr.send(); + xhr.onload = pass; + xhr.onerror = fail; +} + +function pass() { + if (window.chrome && chrome.test && chrome.test.succeed) + chrome.test.succeed(); + document.body.innerText = "PASS"; +} + +function fail() { + if (window.chrome && chrome.test && chrome.test.fail) + chrome.test.fail(); + document.body.innerText = "FAIL"; +} + +createFile(); diff --git a/chrome/test/data/extensions/api_test/xhr_persistent_fs/manifest.json b/chrome/test/data/extensions/api_test/xhr_persistent_fs/manifest.json new file mode 100644 index 0000000..f9eeb19 --- /dev/null +++ b/chrome/test/data/extensions/api_test/xhr_persistent_fs/manifest.json @@ -0,0 +1,13 @@ +{ + "name": "Test XHR for Persistent FileSystem", + "version": "1", + "manifest_version": 2, + "permissions": [ + "unlimitedStorage" + ], + "app": { + "background": { + "scripts": ["bg.js"] + } + } +} diff --git a/content/browser/storage_partition_impl_map.cc b/content/browser/storage_partition_impl_map.cc index 742242f..02bfdd6 100644 --- a/content/browser/storage_partition_impl_map.cc +++ b/content/browser/storage_partition_impl_map.cc @@ -144,11 +144,24 @@ void InitializeURLRequestContext( DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); if (!context_getter) return; // tests. + + // This code only modifies the URLRequestJobFactory on the context + // to handle blob: URLs, filesystem: URLs, and to let AppCache intercept + // the appropriate requests. This is in addition to the slew of other + // initializtion that is done in during creation of the URLRequestContext. + // We cannot yet centralize this code because URLRequestContext needs + // to be created before the StoragePartition context. + // + // TODO(ajwong): Fix the ordering so all the initialization is in one spot. net::URLRequestContext* context = context_getter->GetURLRequestContext(); net::URLRequestJobFactory* job_factory = const_cast<net::URLRequestJobFactory*>(context->job_factory()); + + // Note: if this is called twice with 2 request contexts that share one job + // factory (as is the case with a media request context and its related + // normal request context) then this will early exit. if (job_factory->IsHandledProtocol(chrome::kBlobScheme)) - return; // Already initialized this RequestContext. + return; // Already initialized this JobFactory. bool set_protocol = job_factory->SetProtocolHandler( chrome::kBlobScheme, @@ -253,15 +266,12 @@ void StoragePartitionImplMap::PostCreateInitialization( make_scoped_refptr(partition->GetFileSystemContext()), make_scoped_refptr( ChromeBlobStorageContext::GetFor(browser_context_)))); - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - base::Bind( - &InitializeURLRequestContext, - make_scoped_refptr(partition->GetMediaURLRequestContext()), - make_scoped_refptr(partition->GetAppCacheService()), - make_scoped_refptr(partition->GetFileSystemContext()), - make_scoped_refptr( - ChromeBlobStorageContext::GetFor(browser_context_)))); + + // We do not call InitializeURLRequestContext() for media contexts because, + // other than the HTTP cache, the media contexts share the same backing + // objects as their associated "normal" request context. Thus, the previous + // call serves to initialize the media request context for this storage + // partition as well. } } |