diff options
author | willchan@chromium.org <willchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-16 18:18:00 +0000 |
---|---|---|
committer | willchan@chromium.org <willchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-16 18:18:00 +0000 |
commit | c3a420945071a54182d63de697be0a80f5dab0c0 (patch) | |
tree | 5b6a16e60c10411f0ed2a5171c8139e02e29d11a | |
parent | 1d20cdf4cb74b3a1b47c7bd62d3e3d17be4c6013 (diff) | |
download | chromium_src-c3a420945071a54182d63de697be0a80f5dab0c0.zip chromium_src-c3a420945071a54182d63de697be0a80f5dab0c0.tar.gz chromium_src-c3a420945071a54182d63de697be0a80f5dab0c0.tar.bz2 |
Reland r74842
The bug was that the ProfilePolicyContext was getting initialized before the ProfileImplIOData::Handle was initialized.
BUG=67237
TEST=none
Review URL: http://codereview.chromium.org/6526029
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@75143 0039d316-1c4b-4281-b951-d872f2087c98
31 files changed, 1454 insertions, 1149 deletions
diff --git a/chrome/browser/io_thread.cc b/chrome/browser/io_thread.cc index c6b8c7b..16eec12 100644 --- a/chrome/browser/io_thread.cc +++ b/chrome/browser/io_thread.cc @@ -29,6 +29,7 @@ #include "chrome/common/net/url_fetcher.h" #include "chrome/common/pref_names.h" #include "net/base/cert_verifier.h" +#include "net/base/cookie_monster.h" #include "net/base/dnsrr_resolver.h" #include "net/base/host_cache.h" #include "net/base/host_resolver.h" diff --git a/chrome/browser/net/chrome_url_request_context.cc b/chrome/browser/net/chrome_url_request_context.cc index 573ffdc..eead9cd 100644 --- a/chrome/browser/net/chrome_url_request_context.cc +++ b/chrome/browser/net/chrome_url_request_context.cc @@ -4,40 +4,21 @@ #include "chrome/browser/net/chrome_url_request_context.h" -#include "base/command_line.h" #include "base/message_loop.h" #include "base/message_loop_proxy.h" -#include "base/string_number_conversions.h" -#include "base/string_util.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_thread.h" #include "chrome/browser/dom_ui/chrome_url_data_manager_backend.h" -#include "chrome/browser/extensions/extension_service.h" -#include "chrome/browser/extensions/user_script_master.h" #include "chrome/browser/io_thread.h" -#include "chrome/browser/net/chrome_cookie_notification_details.h" -#include "chrome/browser/net/chrome_net_log.h" -#include "chrome/browser/net/chrome_dns_cert_provenance_checker_factory.h" -#include "chrome/browser/net/sqlite_persistent_cookie_store.h" -#include "chrome/browser/net/predictor_api.h" -#include "chrome/browser/net/pref_proxy_config_service.h" +#include "chrome/browser/net/chrome_cookie_policy.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_io_data.h" -#include "chrome/common/chrome_constants.h" -#include "chrome/common/chrome_switches.h" -#include "chrome/common/extensions/extension.h" #include "chrome/common/notification_service.h" #include "chrome/common/pref_names.h" -#include "chrome/common/url_constants.h" -#include "net/base/static_cookie_policy.h" -#include "net/ftp/ftp_network_layer.h" -#include "net/http/http_cache.h" -#include "net/http/http_network_layer.h" +#include "net/base/cookie_store.h" +#include "net/ftp/ftp_transaction_factory.h" +#include "net/http/http_transaction_factory.h" #include "net/http/http_util.h" -#include "net/proxy/proxy_config_service_fixed.h" -#include "net/proxy/proxy_script_fetcher_impl.h" -#include "net/proxy/proxy_service.h" -#include "net/url_request/url_request.h" #include "webkit/glue/webkit_glue.h" #if defined(USE_NSS) @@ -50,457 +31,67 @@ #include "chrome/browser/chromeos/proxy_config_service.h" #endif // defined(OS_CHROMEOS) -namespace { - -// ---------------------------------------------------------------------------- -// Helper methods to check current thread -// ---------------------------------------------------------------------------- - -void CheckCurrentlyOnIOThread() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); -} - -void CheckCurrentlyOnMainThread() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); -} - -// ---------------------------------------------------------------------------- -// Helper methods to initialize proxy -// ---------------------------------------------------------------------------- - -net::ProxyConfigService* CreateProxyConfigService(Profile* profile) { - // The linux gconf-based proxy settings getter relies on being initialized - // from the UI thread. - CheckCurrentlyOnMainThread(); - - // Create a baseline service that provides proxy configuration in case nothing - // is configured through prefs (Note: prefs include command line and - // configuration policy). - net::ProxyConfigService* base_service = NULL; - - // TODO(port): the IO and FILE message loops are only used by Linux. Can - // that code be moved to chrome/browser instead of being in net, so that it - // can use BrowserThread instead of raw MessageLoop pointers? See bug 25354. -#if defined(OS_CHROMEOS) - base_service = new chromeos::ProxyConfigService( - profile->GetChromeOSProxyConfigServiceImpl()); -#else - base_service = net::ProxyService::CreateSystemProxyConfigService( - g_browser_process->io_thread()->message_loop(), - g_browser_process->file_thread()->message_loop()); -#endif // defined(OS_CHROMEOS) - - return new PrefProxyConfigService(profile->GetProxyConfigTracker(), - base_service); -} - -// Create a proxy service according to the options on command line. -net::ProxyService* CreateProxyService( - net::NetLog* net_log, - net::URLRequestContext* context, - net::ProxyConfigService* proxy_config_service, - const CommandLine& command_line) { - CheckCurrentlyOnIOThread(); - - bool use_v8 = !command_line.HasSwitch(switches::kWinHttpProxyResolver); - if (use_v8 && command_line.HasSwitch(switches::kSingleProcess)) { - // See the note about V8 multithreading in net/proxy/proxy_resolver_v8.h - // to understand why we have this limitation. - LOG(ERROR) << "Cannot use V8 Proxy resolver in single process mode."; - use_v8 = false; // Fallback to non-v8 implementation. - } - - size_t num_pac_threads = 0u; // Use default number of threads. - - // Check the command line for an override on the number of proxy resolver - // threads to use. - if (command_line.HasSwitch(switches::kNumPacThreads)) { - std::string s = command_line.GetSwitchValueASCII(switches::kNumPacThreads); - - // Parse the switch (it should be a positive integer formatted as decimal). - int n; - if (base::StringToInt(s, &n) && n > 0) { - num_pac_threads = static_cast<size_t>(n); - } else { - LOG(ERROR) << "Invalid switch for number of PAC threads: " << s; - } - } - - net::ProxyService* proxy_service; - if (use_v8) { - proxy_service = net::ProxyService::CreateUsingV8ProxyResolver( - proxy_config_service, - num_pac_threads, - new net::ProxyScriptFetcherImpl(context), - context->host_resolver(), - net_log); - } else { - proxy_service = net::ProxyService::CreateUsingSystemProxyResolver( - proxy_config_service, - num_pac_threads, - net_log); - } - -#if defined(OS_CHROMEOS) - if (chromeos::CrosLibrary::Get()->EnsureLoaded()) { - chromeos::CrosLibrary::Get()->GetLibCrosServiceLibrary()-> - RegisterNetworkProxyHandler(proxy_service); - } -#endif // defined(OS_CHROMEOS) - - return proxy_service; -} - -// ---------------------------------------------------------------------------- -// CookieMonster::Delegate implementation -// ---------------------------------------------------------------------------- -class ChromeCookieMonsterDelegate : public net::CookieMonster::Delegate { +class ChromeURLRequestContextFactory { public: - explicit ChromeCookieMonsterDelegate(Profile* profile) { - CheckCurrentlyOnMainThread(); - profile_getter_ = new ProfileGetter(profile); - } - - // net::CookieMonster::Delegate implementation. - virtual void OnCookieChanged( - const net::CookieMonster::CanonicalCookie& cookie, - bool removed) { - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - NewRunnableMethod(this, - &ChromeCookieMonsterDelegate::OnCookieChangedAsyncHelper, - cookie, - removed)); - } - - private: - // This class allows us to safely access the Profile pointer. The Delegate - // itself cannot observe the PROFILE_DESTROYED notification, since it cannot - // guarantee to be deleted on the UI thread and therefore unregister from - // the notifications. All methods of ProfileGetter must be invoked on the UI - // thread. - class ProfileGetter - : public base::RefCountedThreadSafe<ProfileGetter, - BrowserThread::DeleteOnUIThread>, - public NotificationObserver { - public: - explicit ProfileGetter(Profile* profile) : profile_(profile) { - CheckCurrentlyOnMainThread(); - registrar_.Add(this, - NotificationType::PROFILE_DESTROYED, - Source<Profile>(profile_)); - } - - // NotificationObserver implementation. - void Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details) { - CheckCurrentlyOnMainThread(); - if (NotificationType::PROFILE_DESTROYED == type) { - Profile* profile = Source<Profile>(source).ptr(); - if (profile_ == profile) - profile_ = NULL; - } - } - - Profile* get() { - CheckCurrentlyOnMainThread(); - return profile_; - } - - private: - friend class ::BrowserThread; - friend class DeleteTask<ProfileGetter>; + ChromeURLRequestContextFactory() {} + virtual ~ChromeURLRequestContextFactory() {} - virtual ~ProfileGetter() {} + // Called to create a new instance (will only be called once). + virtual scoped_refptr<ChromeURLRequestContext> Create() = 0; - NotificationRegistrar registrar_; - - Profile* profile_; - }; - - virtual ~ChromeCookieMonsterDelegate() {} - - void OnCookieChangedAsyncHelper( - const net::CookieMonster::CanonicalCookie& cookie, - bool removed) { - if (profile_getter_->get()) { - ChromeCookieDetails cookie_details(&cookie, removed); - NotificationService::current()->Notify( - NotificationType::COOKIE_CHANGED, - Source<Profile>(profile_getter_->get()), - Details<ChromeCookieDetails>(&cookie_details)); - } - } - - scoped_refptr<ProfileGetter> profile_getter_; + protected: + DISALLOW_COPY_AND_ASSIGN(ChromeURLRequestContextFactory); }; +namespace { + // ---------------------------------------------------------------------------- // Helper factories // ---------------------------------------------------------------------------- // Factory that creates the main ChromeURLRequestContext. -class FactoryForOriginal : public ChromeURLRequestContextFactory { +class FactoryForMain : public ChromeURLRequestContextFactory { public: - FactoryForOriginal(Profile* profile, - const ProfileIOData* profile_io_data) - : ChromeURLRequestContextFactory(profile), - profile_io_data_(profile_io_data), - // We need to initialize the ProxyConfigService from the UI thread - // because on linux it relies on initializing things through gconf, - // and needs to be on the main thread. - proxy_config_service_(CreateProxyConfigService(profile)) { - } + explicit FactoryForMain(const ProfileIOData* profile_io_data) + : profile_io_data_(profile_io_data) {} - virtual scoped_refptr<ChromeURLRequestContext> Create(); + virtual scoped_refptr<ChromeURLRequestContext> Create() { + return profile_io_data_->GetMainRequestContext(); + } private: const scoped_refptr<const ProfileIOData> profile_io_data_; - scoped_ptr<net::ProxyConfigService> proxy_config_service_; }; -scoped_refptr<ChromeURLRequestContext> FactoryForOriginal::Create() { - scoped_refptr<ChromeURLRequestContext> context = - profile_io_data_->GetMainRequestContext(); - ApplyProfileParametersToContext(context); - - IOThread::Globals* io_thread_globals = io_thread()->globals(); - const ProfileIOData::LazyParams& params = profile_io_data_->lazy_params(); - - context->set_dns_cert_checker( - CreateDnsCertProvenanceChecker(io_thread_globals->dnsrr_resolver.get(), - context)); - - const CommandLine& command_line = *CommandLine::ForCurrentProcess(); - - context->set_proxy_service( - CreateProxyService(io_thread()->net_log(), - io_thread_globals->proxy_script_fetcher_context.get(), - proxy_config_service_.release(), - command_line)); - - net::HttpCache::DefaultBackend* backend = new net::HttpCache::DefaultBackend( - net::DISK_CACHE, params.cache_path, params.cache_max_size, - BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE)); - net::HttpCache* cache = new net::HttpCache( - context->host_resolver(), - context->cert_verifier(), - context->dnsrr_resolver(), - context->dns_cert_checker(), - context->proxy_service(), - context->ssl_config_service(), - context->http_auth_handler_factory(), - &io_thread_globals->network_delegate, - io_thread()->net_log(), - backend); - - bool record_mode = chrome::kRecordModeEnabled && - command_line.HasSwitch(switches::kRecordMode); - bool playback_mode = command_line.HasSwitch(switches::kPlaybackMode); - - if (record_mode || playback_mode) { - // Don't use existing cookies and use an in-memory store. - context->set_cookie_store(new net::CookieMonster(NULL, - cookie_monster_delegate_)); - cache->set_mode( - record_mode ? net::HttpCache::RECORD : net::HttpCache::PLAYBACK); - } - context->set_http_transaction_factory(cache); - - context->set_ftp_transaction_factory( - new net::FtpNetworkLayer(context->host_resolver())); - - // setup cookie store - if (!context->cookie_store()) { - DCHECK(!params.cookie_path.empty()); - - scoped_refptr<SQLitePersistentCookieStore> cookie_db = - new SQLitePersistentCookieStore(params.cookie_path); - cookie_db->SetClearLocalStateOnExit(clear_local_state_on_exit_); - context->set_cookie_store(new net::CookieMonster(cookie_db.get(), - cookie_monster_delegate_)); - } - - context->set_cookie_policy( - new ChromeCookiePolicy(host_content_settings_map_)); - - appcache_service_->set_request_context(context); - return context; -} - // Factory that creates the ChromeURLRequestContext for extensions. class FactoryForExtensions : public ChromeURLRequestContextFactory { public: - FactoryForExtensions(Profile* profile, const ProfileIOData* profile_io_data, - bool incognito) - : ChromeURLRequestContextFactory(profile), - profile_io_data_(profile_io_data), - incognito_(incognito) { - DCHECK(incognito || profile_io_data); - } - - virtual scoped_refptr<ChromeURLRequestContext> Create(); - - private: - const scoped_refptr<const ProfileIOData> profile_io_data_; - const bool incognito_; -}; + explicit FactoryForExtensions(const ProfileIOData* profile_io_data) + : profile_io_data_(profile_io_data) {} -scoped_refptr<ChromeURLRequestContext> FactoryForExtensions::Create() { - scoped_refptr<ChromeURLRequestContext> context = NULL; - if (incognito_) - context = new ChromeURLRequestContext; - else - context = profile_io_data_->GetExtensionsRequestContext(); - ApplyProfileParametersToContext(context); - - IOThread::Globals* io_thread_globals = io_thread()->globals(); - - // All we care about for extensions is the cookie store. For incognito, we - // use a non-persistent cookie store. - scoped_refptr<SQLitePersistentCookieStore> cookie_db = NULL; - if (!incognito_) { - const FilePath& cookie_store_path = - profile_io_data_->lazy_params().extensions_cookie_path; - DCHECK(!cookie_store_path.empty()); - cookie_db = new SQLitePersistentCookieStore(cookie_store_path); + virtual scoped_refptr<ChromeURLRequestContext> Create() { + return profile_io_data_->GetExtensionsRequestContext(); } - net::CookieMonster* cookie_monster = - new net::CookieMonster(cookie_db.get(), NULL); - - // Enable cookies for devtools and extension URLs. - const char* schemes[] = {chrome::kChromeDevToolsScheme, - chrome::kExtensionScheme}; - cookie_monster->SetCookieableSchemes(schemes, 2); - context->set_cookie_store(cookie_monster); - context->set_network_delegate(&io_thread_globals->network_delegate); - // TODO(cbentzel): How should extensions handle HTTP Authentication? - context->set_http_auth_handler_factory( - io_thread_globals->http_auth_handler_factory.get()); - - return context; -} - -// Factory that creates the ChromeURLRequestContext for incognito profile. -class FactoryForOffTheRecord : public ChromeURLRequestContextFactory { - public: - explicit FactoryForOffTheRecord(Profile* profile) - : ChromeURLRequestContextFactory(profile), - proxy_config_service_(CreateProxyConfigService(profile)), - original_context_getter_( - static_cast<ChromeURLRequestContextGetter*>( - profile->GetOriginalProfile()->GetRequestContext())) { - } - - virtual scoped_refptr<ChromeURLRequestContext> Create(); - private: - scoped_ptr<net::ProxyConfigService> proxy_config_service_; - scoped_refptr<ChromeURLRequestContextGetter> original_context_getter_; + const scoped_refptr<const ProfileIOData> profile_io_data_; }; -scoped_refptr<ChromeURLRequestContext> FactoryForOffTheRecord::Create() { - scoped_refptr<ChromeURLRequestContext> context = new ChromeURLRequestContext; - ApplyProfileParametersToContext(context); - - IOThread::Globals* io_thread_globals = io_thread()->globals(); - context->set_host_resolver(io_thread_globals->host_resolver.get()); - context->set_cert_verifier(io_thread_globals->cert_verifier.get()); - context->set_http_auth_handler_factory( - io_thread_globals->http_auth_handler_factory.get()); - context->set_network_delegate(&io_thread_globals->network_delegate); - - const CommandLine& command_line = *CommandLine::ForCurrentProcess(); - context->set_proxy_service( - CreateProxyService(io_thread()->net_log(), - io_thread_globals->proxy_script_fetcher_context.get(), - proxy_config_service_.release(), - command_line)); - - net::HttpCache::BackendFactory* backend = - net::HttpCache::DefaultBackend::InMemory(0); - - net::HttpCache* cache = - new net::HttpCache(io_thread_globals->host_resolver.get(), - io_thread_globals->cert_verifier.get(), - context->dnsrr_resolver(), - NULL /* dns_cert_checker */, - context->proxy_service(), - context->ssl_config_service(), - io_thread_globals->http_auth_handler_factory.get(), - &io_thread_globals->network_delegate, - io_thread()->net_log(), - backend); - context->set_cookie_store(new net::CookieMonster(NULL, - cookie_monster_delegate_)); - context->set_cookie_policy( - new ChromeCookiePolicy(host_content_settings_map_)); - context->set_http_transaction_factory(cache); - - context->set_ftp_transaction_factory( - new net::FtpNetworkLayer(context->host_resolver())); - - appcache_service_->set_request_context(context); - - context->set_net_log(io_thread()->net_log()); - return context; -} - // Factory that creates the ChromeURLRequestContext for media. class FactoryForMedia : public ChromeURLRequestContextFactory { public: - FactoryForMedia(Profile* profile, - const ProfileIOData* profile_io_data) - : ChromeURLRequestContextFactory(profile), - main_context_getter_( - static_cast<ChromeURLRequestContextGetter*>( - profile->GetRequestContext())), - profile_io_data_(profile_io_data) { + explicit FactoryForMedia(const ProfileIOData* profile_io_data) + : profile_io_data_(profile_io_data) { } - virtual scoped_refptr<ChromeURLRequestContext> Create(); + virtual scoped_refptr<ChromeURLRequestContext> Create() { + return profile_io_data_->GetMediaRequestContext(); + } private: - scoped_refptr<ChromeURLRequestContextGetter> main_context_getter_; const scoped_refptr<const ProfileIOData> profile_io_data_; }; -scoped_refptr<ChromeURLRequestContext> FactoryForMedia::Create() { - scoped_refptr<ChromeURLRequestContext> context = - profile_io_data_->GetMediaRequestContext(); - ApplyProfileParametersToContext(context); - - ChromeURLRequestContext* main_context = main_context_getter_->GetIOContext(); - - const ProfileIOData::LazyParams& params = profile_io_data_->lazy_params(); - - // TODO(willchan): Make a global ProxyService available in IOThread::Globals. - context->set_proxy_service(main_context->proxy_service()); - context->set_network_delegate(main_context->network_delegate()); - - // Also share the cookie store of the common profile. - context->set_cookie_store(main_context->cookie_store()); - context->set_cookie_policy( - static_cast<ChromeCookiePolicy*>(main_context->cookie_policy())); - - // Create a media cache with default size. - // TODO(hclam): make the maximum size of media cache configurable. - net::HttpCache::DefaultBackend* backend = new net::HttpCache::DefaultBackend( - net::MEDIA_CACHE, params.media_cache_path, params.media_cache_max_size, - BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE)); - - net::HttpCache* main_cache = - main_context->http_transaction_factory()->GetCache(); - net::HttpNetworkSession* network_session = main_cache->GetSession(); - net::HttpCache* cache = new net::HttpCache(network_session, backend); - context->set_http_transaction_factory(cache); - context->set_net_log(io_thread()->net_log()); - - return context; -} - } // namespace // ---------------------------------------------------------------------------- @@ -514,14 +105,12 @@ ChromeURLRequestContextGetter::ChromeURLRequestContextGetter( factory_(factory), url_request_context_(NULL) { DCHECK(factory); - - // If a base profile was specified, listen for changes to the preferences. - if (profile) - RegisterPrefsObserver(profile); + DCHECK(profile); + RegisterPrefsObserver(profile); } ChromeURLRequestContextGetter::~ChromeURLRequestContextGetter() { - CheckCurrentlyOnIOThread(); + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); DCHECK(registrar_.IsEmpty()) << "Probably didn't call CleanupOnUIThread"; @@ -539,7 +128,7 @@ ChromeURLRequestContextGetter::~ChromeURLRequestContextGetter() { // Lazily create a ChromeURLRequestContext using our factory. net::URLRequestContext* ChromeURLRequestContextGetter::GetURLRequestContext() { - CheckCurrentlyOnIOThread(); + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); if (!url_request_context_) { DCHECK(factory_.get()); @@ -601,7 +190,7 @@ ChromeURLRequestContextGetter* ChromeURLRequestContextGetter::CreateOriginal( DCHECK(!profile->IsOffTheRecord()); return new ChromeURLRequestContextGetter( profile, - new FactoryForOriginal(profile, profile_io_data)); + new FactoryForMain(profile_io_data)); } // static @@ -611,7 +200,7 @@ ChromeURLRequestContextGetter::CreateOriginalForMedia( DCHECK(!profile->IsOffTheRecord()); return new ChromeURLRequestContextGetter( profile, - new FactoryForMedia(profile, profile_io_data)); + new FactoryForMedia(profile_io_data)); } // static @@ -621,29 +210,31 @@ ChromeURLRequestContextGetter::CreateOriginalForExtensions( DCHECK(!profile->IsOffTheRecord()); return new ChromeURLRequestContextGetter( profile, - new FactoryForExtensions(profile, profile_io_data, false)); + new FactoryForExtensions(profile_io_data)); } // static ChromeURLRequestContextGetter* -ChromeURLRequestContextGetter::CreateOffTheRecord(Profile* profile) { +ChromeURLRequestContextGetter::CreateOffTheRecord( + Profile* profile, const ProfileIOData* profile_io_data) { DCHECK(profile->IsOffTheRecord()); return new ChromeURLRequestContextGetter( - profile, new FactoryForOffTheRecord(profile)); + profile, new FactoryForMain(profile_io_data)); } // static ChromeURLRequestContextGetter* ChromeURLRequestContextGetter::CreateOffTheRecordForExtensions( - Profile* profile) { + Profile* profile, const ProfileIOData* profile_io_data) { DCHECK(profile->IsOffTheRecord()); return new ChromeURLRequestContextGetter( - profile, new FactoryForExtensions(profile, NULL, true)); + profile, new FactoryForExtensions(profile_io_data)); } void ChromeURLRequestContextGetter::CleanupOnUIThread() { - CheckCurrentlyOnMainThread(); + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); // Unregister for pref notifications. + DCHECK(!registrar_.IsEmpty()) << "Called more than once!"; registrar_.RemoveAll(); } @@ -652,7 +243,7 @@ void ChromeURLRequestContextGetter::Observe( NotificationType type, const NotificationSource& source, const NotificationDetails& details) { - CheckCurrentlyOnMainThread(); + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); if (NotificationType::PREF_CHANGED == type) { std::string* pref_name_in = Details<std::string>(details).ptr(); @@ -692,7 +283,7 @@ void ChromeURLRequestContextGetter::Observe( } void ChromeURLRequestContextGetter::RegisterPrefsObserver(Profile* profile) { - CheckCurrentlyOnMainThread(); + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); registrar_.Init(profile->GetPrefs()); registrar_.Add(prefs::kAcceptLanguages, this); @@ -730,7 +321,13 @@ void ChromeURLRequestContextGetter::GetCookieStoreAsyncHelper( ChromeURLRequestContext::ChromeURLRequestContext() : is_off_the_record_(false) { - CheckCurrentlyOnIOThread(); + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); +} + +void ChromeURLRequestContext::set_chrome_cookie_policy( + ChromeCookiePolicy* cookie_policy) { + chrome_cookie_policy_ = cookie_policy; // Take a strong reference. + set_cookie_policy(cookie_policy); } ChromeURLDataManagerBackend* @@ -741,18 +338,11 @@ ChromeURLDataManagerBackend* } ChromeURLRequestContext::~ChromeURLRequestContext() { - CheckCurrentlyOnIOThread(); + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); if (appcache_service_.get() && appcache_service_->request_context() == this) appcache_service_->set_request_context(NULL); - if (proxy_service_ && - proxy_service_->GetProxyScriptFetcher() && - proxy_service_->GetProxyScriptFetcher()->GetRequestContext() == this) { - // Remove the ProxyScriptFetcher's weak reference to this context. - proxy_service_->SetProxyScriptFetcher(NULL); - } - #if defined(USE_NSS) if (is_main()) { net::URLRequestContext* ocsp_context = net::GetURLRequestContextForOCSP(); @@ -769,13 +359,10 @@ ChromeURLRequestContext::~ChromeURLRequestContext() { Source<net::URLRequestContext>(this), NotificationService::NoDetails()); - delete ftp_transaction_factory_; - delete http_transaction_factory_; - // cookie_policy_'s lifetime is auto-managed by chrome_cookie_policy_. We // null this out here to avoid a dangling reference to chrome_cookie_policy_ // when ~net::URLRequestContext runs. - cookie_policy_ = NULL; + set_cookie_policy(NULL); } const std::string& ChromeURLRequestContext::GetUserAgent( @@ -785,97 +372,15 @@ const std::string& ChromeURLRequestContext::GetUserAgent( void ChromeURLRequestContext::OnAcceptLanguageChange( const std::string& accept_language) { - CheckCurrentlyOnIOThread(); - accept_language_ = - net::HttpUtil::GenerateAcceptLanguageHeader(accept_language); + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + set_accept_language( + net::HttpUtil::GenerateAcceptLanguageHeader(accept_language)); } void ChromeURLRequestContext::OnDefaultCharsetChange( const std::string& default_charset) { - CheckCurrentlyOnIOThread(); - referrer_charset_ = default_charset; - accept_charset_ = - net::HttpUtil::GenerateAcceptCharsetHeader(default_charset); -} - -// ---------------------------------------------------------------------------- -// ChromeURLRequestContextFactory -// ---------------------------------------------------------------------------- - -// Extract values from |profile| and copy them into -// ChromeURLRequestContextFactory. We will use them later when constructing the -// ChromeURLRequestContext on the IO thread (see -// ApplyProfileParametersToContext() which reverses this). -ChromeURLRequestContextFactory::ChromeURLRequestContextFactory(Profile* profile) - : is_off_the_record_(profile->IsOffTheRecord()), - io_thread_(g_browser_process->io_thread()) { - CheckCurrentlyOnMainThread(); - PrefService* prefs = profile->GetPrefs(); - - // Set up Accept-Language and Accept-Charset header values - accept_language_ = net::HttpUtil::GenerateAcceptLanguageHeader( - prefs->GetString(prefs::kAcceptLanguages)); - std::string default_charset = prefs->GetString(prefs::kDefaultCharset); - accept_charset_ = - net::HttpUtil::GenerateAcceptCharsetHeader(default_charset); - clear_local_state_on_exit_ = prefs->GetBoolean(prefs::kClearSiteDataOnExit); - - // At this point, we don't know the charset of the referring page - // where a url request originates from. This is used to get a suggested - // filename from Content-Disposition header made of raw 8bit characters. - // Down the road, it can be overriden if it becomes known (for instance, - // when download request is made through the context menu in a web page). - // At the moment, it'll remain 'undeterministic' when a user - // types a URL in the omnibar or click on a download link in a page. - // For the latter, we need a change on the webkit-side. - // We initialize it to the default charset here and a user will - // have an *arguably* better default charset for interpreting a raw 8bit - // C-D header field. It means the native OS codepage fallback in - // net_util::GetSuggestedFilename is unlikely to be taken. - referrer_charset_ = default_charset; - - host_content_settings_map_ = profile->GetHostContentSettingsMap(); - host_zoom_map_ = profile->GetHostZoomMap(); - transport_security_state_ = profile->GetTransportSecurityState(); - - if (profile->GetUserScriptMaster()) - user_script_dir_path_ = profile->GetUserScriptMaster()->user_script_dir(); - - ssl_config_service_ = profile->GetSSLConfigService(); - profile_dir_path_ = profile->GetPath(); - cookie_monster_delegate_ = new ChromeCookieMonsterDelegate(profile); - appcache_service_ = profile->GetAppCacheService(); - database_tracker_ = profile->GetDatabaseTracker(); - blob_storage_context_ = profile->GetBlobStorageContext(); - file_system_context_ = profile->GetFileSystemContext(); - extension_info_map_ = profile->GetExtensionInfoMap(); - extension_io_event_router_ = profile->GetExtensionIOEventRouter(); - prerender_manager_ = profile->GetPrerenderManager(); -} - -ChromeURLRequestContextFactory::~ChromeURLRequestContextFactory() { - CheckCurrentlyOnIOThread(); -} - -void ChromeURLRequestContextFactory::ApplyProfileParametersToContext( - ChromeURLRequestContext* context) { - // Apply all the parameters. NOTE: keep this in sync with - // ChromeURLRequestContextFactory(Profile*). - context->set_is_off_the_record(is_off_the_record_); - context->set_accept_language(accept_language_); - context->set_accept_charset(accept_charset_); - context->set_referrer_charset(referrer_charset_); - context->set_user_script_dir_path(user_script_dir_path_); - context->set_host_content_settings_map(host_content_settings_map_); - context->set_host_zoom_map(host_zoom_map_); - context->set_transport_security_state( - transport_security_state_); - context->set_ssl_config_service(ssl_config_service_); - context->set_appcache_service(appcache_service_); - context->set_database_tracker(database_tracker_); - context->set_blob_storage_context(blob_storage_context_); - context->set_file_system_context(file_system_context_); - context->set_extension_info_map(extension_info_map_); - context->set_extension_io_event_router(extension_io_event_router_); - context->set_prerender_manager(prerender_manager_); + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + set_referrer_charset(default_charset); + set_accept_charset( + net::HttpUtil::GenerateAcceptCharsetHeader(default_charset)); } diff --git a/chrome/browser/net/chrome_url_request_context.h b/chrome/browser/net/chrome_url_request_context.h index 42760a1..ef557cf 100644 --- a/chrome/browser/net/chrome_url_request_context.h +++ b/chrome/browser/net/chrome_url_request_context.h @@ -17,32 +17,27 @@ #include "chrome/browser/extensions/extension_io_event_router.h" #include "chrome/browser/extensions/extension_webrequest_api.h" #include "chrome/browser/host_zoom_map.h" -#include "chrome/browser/io_thread.h" -#include "chrome/browser/net/chrome_cookie_policy.h" #include "chrome/browser/prefs/pref_change_registrar.h" #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/prerender/prerender_manager.h" #include "chrome/common/extensions/extension_icon_set.h" #include "chrome/common/net/url_request_context_getter.h" -#include "net/base/cookie_monster.h" #include "net/base/cookie_policy.h" #include "net/url_request/url_request_context.h" #include "webkit/database/database_tracker.h" #include "webkit/fileapi/file_system_context.h" -class CommandLine; -class PrefService; -class Profile; -class ProfileIOData; - +class ChromeCookiePolicy; +class ChromeURLDataManagerBackend; +class ChromeURLRequestContextFactory; +class IOThread; namespace net { class DnsCertProvenanceChecker; class NetworkDelegate; } - -class ChromeURLDataManagerBackend; -class ChromeURLRequestContext; -class ChromeURLRequestContextFactory; +class PrefService; +class Profile; +class ProfileIOData; // Subclass of net::URLRequestContext which can be used to store extra // information for requests. @@ -105,38 +100,9 @@ class ChromeURLRequestContext : public net::URLRequestContext { ChromeURLDataManagerBackend* GetChromeURLDataManagerBackend(); - protected: - virtual ~ChromeURLRequestContext(); - - public: // Setters to simplify initializing from factory objects. + void set_chrome_cookie_policy(ChromeCookiePolicy* cookie_policy); - void set_accept_language(const std::string& accept_language) { - accept_language_ = accept_language; - } - void set_accept_charset(const std::string& accept_charset) { - accept_charset_ = accept_charset; - } - void set_referrer_charset(const std::string& referrer_charset) { - referrer_charset_ = referrer_charset; - } - void set_transport_security_state( - net::TransportSecurityState* state) { - transport_security_state_ = state; - } - void set_ssl_config_service(net::SSLConfigService* service) { - ssl_config_service_ = service; - } - void set_dns_cert_checker(net::DnsCertProvenanceChecker* ctx) { - dns_cert_checker_.reset(ctx); - } - void set_ftp_transaction_factory(net::FtpTransactionFactory* factory) { - ftp_transaction_factory_ = factory; - } - void set_cookie_policy(ChromeCookiePolicy* cookie_policy) { - chrome_cookie_policy_ = cookie_policy; // Take a strong reference. - cookie_policy_ = cookie_policy; - } void set_user_script_dir_path(const FilePath& path) { user_script_dir_path_ = path; } @@ -179,6 +145,9 @@ class ChromeURLRequestContext : public net::URLRequestContext { void OnDefaultCharsetChange(const std::string& default_charset); protected: + virtual ~ChromeURLRequestContext(); + + private: // Path to the directory user scripts are stored in. FilePath user_script_dir_path_; @@ -198,7 +167,6 @@ class ChromeURLRequestContext : public net::URLRequestContext { bool is_off_the_record_; - private: DISALLOW_COPY_AND_ASSIGN(ChromeURLRequestContext); }; @@ -256,12 +224,13 @@ class ChromeURLRequestContextGetter : public URLRequestContextGetter, // Create an instance for use with an OTR profile. This is expected to get // called on the UI thread. - static ChromeURLRequestContextGetter* CreateOffTheRecord(Profile* profile); + static ChromeURLRequestContextGetter* CreateOffTheRecord( + Profile* profile, const ProfileIOData* profile_io_data); // Create an instance for an OTR profile for extensions. This is expected // to get called on UI thread. static ChromeURLRequestContextGetter* CreateOffTheRecordForExtensions( - Profile* profile); + Profile* profile, const ProfileIOData* profile_io_data); // Clean up UI thread resources. This is expected to get called on the UI // thread before the instance is deleted on the IO thread. @@ -308,62 +277,4 @@ class ChromeURLRequestContextGetter : public URLRequestContextGetter, DISALLOW_COPY_AND_ASSIGN(ChromeURLRequestContextGetter); }; -// Base class for a ChromeURLRequestContext factory. This includes -// the shared functionality like extracting the default language/charset -// from a profile. -// -// Except for the constructor, all methods of this class must be called from -// the IO thread. -class ChromeURLRequestContextFactory { - public: - // Extract properties of interested from |profile|, for setting later into - // a ChromeURLRequestContext using ApplyProfileParametersToContext(). - explicit ChromeURLRequestContextFactory(Profile* profile); - - virtual ~ChromeURLRequestContextFactory(); - - // Called to create a new instance (will only be called once). - virtual scoped_refptr<ChromeURLRequestContext> Create() = 0; - - protected: - IOThread* io_thread() { return io_thread_; } - - // Assigns this factory's properties to |context|. - void ApplyProfileParametersToContext(ChromeURLRequestContext* context); - - // Values extracted from the Profile. - // - // NOTE: If you add any parameters here, keep it in sync with - // ApplyProfileParametersToContext(). - bool is_off_the_record_; - bool clear_local_state_on_exit_; - std::string accept_language_; - std::string accept_charset_; - std::string referrer_charset_; - - // TODO(aa): I think this can go away now as we no longer support standalone - // user scripts. - // TODO(willchan): Make these non-refcounted. - FilePath user_script_dir_path_; - scoped_refptr<HostContentSettingsMap> host_content_settings_map_; - scoped_refptr<ChromeAppCacheService> appcache_service_; - scoped_refptr<webkit_database::DatabaseTracker> database_tracker_; - scoped_refptr<HostZoomMap> host_zoom_map_; - scoped_refptr<net::TransportSecurityState> transport_security_state_; - scoped_refptr<net::SSLConfigService> ssl_config_service_; - scoped_refptr<net::CookieMonster::Delegate> cookie_monster_delegate_; - scoped_refptr<ChromeBlobStorageContext> blob_storage_context_; - scoped_refptr<fileapi::FileSystemContext> file_system_context_; - scoped_refptr<ExtensionInfoMap> extension_info_map_; - scoped_refptr<ExtensionIOEventRouter> extension_io_event_router_; - scoped_refptr<prerender::PrerenderManager> prerender_manager_; - - FilePath profile_dir_path_; - - private: - IOThread* const io_thread_; - - DISALLOW_COPY_AND_ASSIGN(ChromeURLRequestContextFactory); -}; - #endif // CHROME_BROWSER_NET_CHROME_URL_REQUEST_CONTEXT_H_ diff --git a/chrome/browser/net/connection_tester.cc b/chrome/browser/net/connection_tester.cc index d0a7c95..a83c885 100644 --- a/chrome/browser/net/connection_tester.cc +++ b/chrome/browser/net/connection_tester.cc @@ -49,52 +49,56 @@ class ExperimentURLRequestContext : public net::URLRequestContext { int rv; // Create a custom HostResolver for this experiment. + net::HostResolver* host_resolver_tmp = NULL; rv = CreateHostResolver(experiment.host_resolver_experiment, - &host_resolver_); + &host_resolver_tmp); if (rv != net::OK) return rv; // Failure. + set_host_resolver(host_resolver_tmp); // Create a custom ProxyService for this this experiment. + scoped_refptr<net::ProxyService> proxy_service_tmp = NULL; rv = CreateProxyService(experiment.proxy_settings_experiment, - &proxy_service_); + &proxy_service_tmp); if (rv != net::OK) return rv; // Failure. + set_proxy_service(proxy_service_tmp); // The rest of the dependencies are standard, and don't depend on the // experiment being run. - cert_verifier_ = new net::CertVerifier; - dnsrr_resolver_ = new net::DnsRRResolver; - ftp_transaction_factory_ = new net::FtpNetworkLayer(host_resolver_); - ssl_config_service_ = new net::SSLConfigServiceDefaults; - http_auth_handler_factory_ = net::HttpAuthHandlerFactory::CreateDefault( - host_resolver_); + set_cert_verifier(new net::CertVerifier); + set_dnsrr_resolver(new net::DnsRRResolver); + set_ftp_transaction_factory(new net::FtpNetworkLayer(host_resolver_tmp)); + set_ssl_config_service(new net::SSLConfigServiceDefaults); + set_http_auth_handler_factory(net::HttpAuthHandlerFactory::CreateDefault( + host_resolver_tmp)); net::HttpNetworkSession::Params session_params; - session_params.host_resolver = host_resolver_; - session_params.dnsrr_resolver = dnsrr_resolver_; - session_params.cert_verifier = cert_verifier_; - session_params.proxy_service = proxy_service_; - session_params.http_auth_handler_factory = http_auth_handler_factory_; - session_params.ssl_config_service = ssl_config_service_; + session_params.host_resolver = host_resolver_tmp; + session_params.dnsrr_resolver = dnsrr_resolver(); + session_params.cert_verifier = cert_verifier(); + session_params.proxy_service = proxy_service_tmp; + session_params.http_auth_handler_factory = http_auth_handler_factory(); + session_params.ssl_config_service = ssl_config_service(); scoped_refptr<net::HttpNetworkSession> network_session( new net::HttpNetworkSession(session_params)); - http_transaction_factory_ = new net::HttpCache( + set_http_transaction_factory(new net::HttpCache( network_session, - net::HttpCache::DefaultBackend::InMemory(0)); + net::HttpCache::DefaultBackend::InMemory(0))); // In-memory cookie store. - cookie_store_ = new net::CookieMonster(NULL, NULL); + set_cookie_store(new net::CookieMonster(NULL, NULL)); return net::OK; } protected: virtual ~ExperimentURLRequestContext() { - delete ftp_transaction_factory_; - delete http_transaction_factory_; - delete http_auth_handler_factory_; - delete dnsrr_resolver_; - delete cert_verifier_; - delete host_resolver_; + delete ftp_transaction_factory(); + delete http_transaction_factory(); + delete http_auth_handler_factory(); + delete dnsrr_resolver(); + delete cert_verifier(); + delete host_resolver(); } private: diff --git a/chrome/browser/policy/device_management_service.cc b/chrome/browser/policy/device_management_service.cc index 965a42c..dc26e6f 100644 --- a/chrome/browser/policy/device_management_service.cc +++ b/chrome/browser/policy/device_management_service.cc @@ -42,27 +42,26 @@ DeviceManagementRequestContext::DeviceManagementRequestContext( // Share resolver, proxy service and ssl bits with the baseline context. This // is important so we don't make redundant requests (e.g. when resolving proxy // auto configuration). - net_log_ = base_context->net_log(); - host_resolver_ = base_context->host_resolver(); - proxy_service_ = base_context->proxy_service(); - ssl_config_service_ = base_context->ssl_config_service(); + set_net_log(base_context->net_log()); + set_host_resolver(base_context->host_resolver()); + set_proxy_service(base_context->proxy_service()); + set_ssl_config_service(base_context->ssl_config_service()); // Share the http session. - http_transaction_factory_ = + set_http_transaction_factory( new net::HttpNetworkLayer( - base_context->http_transaction_factory()->GetSession()); + base_context->http_transaction_factory()->GetSession())); // No cookies, please. - cookie_store_ = new net::CookieMonster(NULL, NULL); + set_cookie_store(new net::CookieMonster(NULL, NULL)); // Initialize these to sane values for our purposes. - accept_language_ = "*"; - accept_charset_ = "*"; + set_accept_language("*"); + set_accept_charset("*"); } DeviceManagementRequestContext::~DeviceManagementRequestContext() { - delete http_transaction_factory_; - delete http_auth_handler_factory_; + delete http_transaction_factory(); } const std::string& DeviceManagementRequestContext::GetUserAgent( diff --git a/chrome/browser/profiles/off_the_record_profile_io_data.cc b/chrome/browser/profiles/off_the_record_profile_io_data.cc new file mode 100644 index 0000000..ac8cf03 --- /dev/null +++ b/chrome/browser/profiles/off_the_record_profile_io_data.cc @@ -0,0 +1,188 @@ +// Copyright (c) 2011 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/off_the_record_profile_io_data.h" + +#include "base/command_line.h" +#include "base/logging.h" +#include "build/build_config.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/browser_thread.h" +#include "chrome/browser/io_thread.h" +#include "chrome/browser/net/chrome_cookie_policy.h" +#include "chrome/browser/net/chrome_dns_cert_provenance_checker_factory.h" +#include "chrome/browser/net/chrome_net_log.h" +#include "chrome/browser/net/chrome_url_request_context.h" +#include "chrome/common/url_constants.h" +#include "net/ftp/ftp_network_layer.h" +#include "net/http/http_cache.h" + +OffTheRecordProfileIOData::Handle::Handle(Profile* profile) + : io_data_(new OffTheRecordProfileIOData), + profile_(profile), + initialized_(false) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + DCHECK(profile); + DCHECK(!io_data_->lazy_params_.get()); + LazyParams* lazy_params = new LazyParams; + lazy_params->io_thread = g_browser_process->io_thread(); + io_data_->lazy_params_.reset(lazy_params); +} + +OffTheRecordProfileIOData::Handle::~Handle() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + if (main_request_context_getter_) + main_request_context_getter_->CleanupOnUIThread(); + if (extensions_request_context_getter_) + extensions_request_context_getter_->CleanupOnUIThread(); +} + +scoped_refptr<ChromeURLRequestContextGetter> +OffTheRecordProfileIOData::Handle::GetMainRequestContextGetter() const { + // TODO(oshima): Re-enable when ChromeOS only accesses the profile on the UI + // thread. +#if !defined(OS_CHROMEOS) + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); +#endif // defined(OS_CHROMEOS) + LazyInitialize(); + if (!main_request_context_getter_) { + main_request_context_getter_ = + ChromeURLRequestContextGetter::CreateOffTheRecord(profile_, io_data_); + } + return main_request_context_getter_; +} + +scoped_refptr<ChromeURLRequestContextGetter> +OffTheRecordProfileIOData::Handle::GetExtensionsRequestContextGetter() const { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + LazyInitialize(); + if (!extensions_request_context_getter_) { + extensions_request_context_getter_ = + ChromeURLRequestContextGetter::CreateOffTheRecordForExtensions( + profile_, io_data_); + } + return extensions_request_context_getter_; +} + +void OffTheRecordProfileIOData::Handle::LazyInitialize() const { + if (!initialized_) { + InitializeProfileParams(profile_, &io_data_->lazy_params_->profile_params); + initialized_ = true; + } +} + +OffTheRecordProfileIOData::LazyParams::LazyParams() : io_thread(NULL) {} +OffTheRecordProfileIOData::LazyParams::~LazyParams() {} + +OffTheRecordProfileIOData::OffTheRecordProfileIOData() + : ProfileIOData(true), + initialized_(false) {} +OffTheRecordProfileIOData::~OffTheRecordProfileIOData() {} + +void OffTheRecordProfileIOData::LazyInitializeInternal() const { + main_request_context_ = new RequestContext; + extensions_request_context_ = new RequestContext; + + IOThread* const io_thread = lazy_params_->io_thread; + IOThread::Globals* const io_thread_globals = io_thread->globals(); + const ProfileParams& profile_params = lazy_params_->profile_params; + const CommandLine& command_line = *CommandLine::ForCurrentProcess(); + + ApplyProfileParamsToContext(profile_params, main_request_context_); + ApplyProfileParamsToContext(profile_params, extensions_request_context_); + profile_params.appcache_service->set_request_context(main_request_context_); + + scoped_refptr<ChromeCookiePolicy> cookie_policy = + new ChromeCookiePolicy(profile_params.host_content_settings_map); + main_request_context_->set_chrome_cookie_policy(cookie_policy); + extensions_request_context_->set_chrome_cookie_policy(cookie_policy); + + main_request_context_->set_net_log(lazy_params_->io_thread->net_log()); + extensions_request_context_->set_net_log(lazy_params_->io_thread->net_log()); + + main_request_context_->set_host_resolver( + io_thread_globals->host_resolver.get()); + main_request_context_->set_cert_verifier( + io_thread_globals->cert_verifier.get()); + main_request_context_->set_dnsrr_resolver( + io_thread_globals->dnsrr_resolver.get()); + // TODO(willchan): Enable this when we can support ExtensionIOEventRouter for + // OTR profiles. +#if 0 + main_request_context_->set_network_delegate( + &io_thread_globals->network_delegate); +#endif + main_request_context_->set_http_auth_handler_factory( + io_thread_globals->http_auth_handler_factory.get()); + + dns_cert_checker_.reset( + CreateDnsCertProvenanceChecker(io_thread_globals->dnsrr_resolver.get(), + main_request_context_)); + main_request_context_->set_dns_cert_checker(dns_cert_checker_.get()); + + main_request_context_->set_proxy_service( + CreateProxyService( + io_thread->net_log(), + io_thread_globals->proxy_script_fetcher_context.get(), + lazy_params_->profile_params.proxy_config_service.release(), + command_line)); + + main_request_context_->set_cookie_store( + new net::CookieMonster(NULL, profile_params.cookie_monster_delegate)); + // All we care about for extensions is the cookie store. For incognito, we + // use a non-persistent cookie store. + + net::CookieMonster* extensions_cookie_store = + new net::CookieMonster(NULL, NULL); + // Enable cookies for devtools and extension URLs. + const char* schemes[] = {chrome::kChromeDevToolsScheme, + chrome::kExtensionScheme}; + extensions_cookie_store->SetCookieableSchemes(schemes, 2); + + extensions_request_context_->set_cookie_store( + new net::CookieMonster(NULL, NULL)); + + net::HttpCache::BackendFactory* main_backend = + net::HttpCache::DefaultBackend::InMemory(0); + net::HttpCache* cache = + new net::HttpCache(main_request_context_->host_resolver(), + main_request_context_->cert_verifier(), + main_request_context_->dnsrr_resolver(), + main_request_context_->dns_cert_checker(), + main_request_context_->proxy_service(), + main_request_context_->ssl_config_service(), + main_request_context_->http_auth_handler_factory(), + main_request_context_->network_delegate(), + main_request_context_->net_log(), + main_backend); + + main_http_factory_.reset(cache); + main_request_context_->set_http_transaction_factory(cache); + main_request_context_->set_ftp_transaction_factory( + new net::FtpNetworkLayer(main_request_context_->host_resolver())); +} + +scoped_refptr<ChromeURLRequestContext> +OffTheRecordProfileIOData::AcquireMainRequestContext() const { + DCHECK(main_request_context_); + scoped_refptr<ChromeURLRequestContext> context = main_request_context_; + main_request_context_->set_profile_io_data(this); + main_request_context_ = NULL; + return context; +} + +scoped_refptr<ChromeURLRequestContext> +OffTheRecordProfileIOData::AcquireMediaRequestContext() const { + NOTREACHED(); + return NULL; +} + +scoped_refptr<ChromeURLRequestContext> +OffTheRecordProfileIOData::AcquireExtensionsRequestContext() const { + DCHECK(extensions_request_context_); + scoped_refptr<ChromeURLRequestContext> context = extensions_request_context_; + extensions_request_context_->set_profile_io_data(this); + extensions_request_context_ = NULL; + return context; +} diff --git a/chrome/browser/profiles/off_the_record_profile_io_data.h b/chrome/browser/profiles/off_the_record_profile_io_data.h new file mode 100644 index 0000000..6ce50f3 --- /dev/null +++ b/chrome/browser/profiles/off_the_record_profile_io_data.h @@ -0,0 +1,110 @@ +// Copyright (c) 2011 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. + +#ifndef CHROME_BROWSER_PROFILES_OFF_THE_RECORD_PROFILE_IO_DATA_H_ +#define CHROME_BROWSER_PROFILES_OFF_THE_RECORD_PROFILE_IO_DATA_H_ +#pragma once + +#include "base/basictypes.h" +#include "base/file_path.h" +#include "base/ref_counted.h" +#include "base/scoped_ptr.h" +#include "chrome/browser/profiles/profile_io_data.h" + +class ChromeURLRequestContext; +class ChromeURLRequestContextGetter; +class IOThread; +class Profile; + +// OffTheRecordProfile owns a OffTheRecordProfileIOData::Handle, which holds a +// reference to the OffTheRecordProfileIOData. OffTheRecordProfileIOData is +// intended to own all the objects owned by OffTheRecordProfile which live on +// the IO thread, such as, but not limited to, network objects like +// CookieMonster, HttpTransactionFactory, etc. OffTheRecordProfileIOData is +// owned by the OffTheRecordProfile and OffTheRecordProfileIOData's +// ChromeURLRequestContexts. When all of them go away, then ProfileIOData will +// be deleted. Note that the OffTheRecordProfileIOData will typically outlive +// the Profile it is "owned" by, so it's important for OffTheRecordProfileIOData +// not to hold any references to the Profile beyond what's used by LazyParams +// (which should be deleted after lazy initialization). + +class OffTheRecordProfileIOData : public ProfileIOData { + public: + class Handle { + public: + explicit Handle(Profile* profile); + ~Handle(); + + scoped_refptr<ChromeURLRequestContextGetter> + GetMainRequestContextGetter() const; + scoped_refptr<ChromeURLRequestContextGetter> + GetExtensionsRequestContextGetter() const; + + private: + // Lazily initialize ProfileParams. We do this on the calls to + // Get*RequestContextGetter(), so we only initialize ProfileParams right + // before posting a task to the IO thread to start using them. This prevents + // objects that are supposed to be deleted on the IO thread, but are created + // on the UI thread from being unnecessarily initialized. + void LazyInitialize() const; + + // Ordering is important here. Do not reorder unless you know what you're + // doing. We need to release |io_data_| *before* the getters, because we + // want to make sure that the last reference for |io_data_| is on the IO + // thread. The getters will be deleted on the IO thread, so they will + // release their refs to their contexts, which will release the last refs to + // the ProfileIOData on the IO thread. + mutable scoped_refptr<ChromeURLRequestContextGetter> + main_request_context_getter_; + mutable scoped_refptr<ChromeURLRequestContextGetter> + extensions_request_context_getter_; + const scoped_refptr<OffTheRecordProfileIOData> io_data_; + + Profile* const profile_; + + mutable bool initialized_; + + DISALLOW_COPY_AND_ASSIGN(Handle); + }; + + private: + friend class base::RefCountedThreadSafe<OffTheRecordProfileIOData>; + + struct LazyParams { + LazyParams(); + ~LazyParams(); + + IOThread* io_thread; + ProfileParams profile_params; + }; + + OffTheRecordProfileIOData(); + ~OffTheRecordProfileIOData(); + + // Lazily initializes ProfileIOData. + virtual void LazyInitializeInternal() const; + virtual scoped_refptr<ChromeURLRequestContext> + AcquireMainRequestContext() const; + virtual scoped_refptr<ChromeURLRequestContext> + AcquireMediaRequestContext() const; + virtual scoped_refptr<ChromeURLRequestContext> + AcquireExtensionsRequestContext() const; + + // Lazy initialization params. + mutable scoped_ptr<LazyParams> lazy_params_; + + mutable bool initialized_; + mutable scoped_refptr<RequestContext> main_request_context_; + // NOTE: |media_request_context_| just points to the same context that + // |main_request_context_| points to. + mutable scoped_refptr<RequestContext> media_request_context_; + mutable scoped_refptr<RequestContext> extensions_request_context_; + + mutable scoped_ptr<net::DnsCertProvenanceChecker> dns_cert_checker_; + mutable scoped_ptr<net::HttpTransactionFactory> main_http_factory_; + + DISALLOW_COPY_AND_ASSIGN(OffTheRecordProfileIOData); +}; + +#endif // CHROME_BROWSER_PROFILES_OFF_THE_RECORD_PROFILE_IO_DATA_H_ diff --git a/chrome/browser/profiles/profile.cc b/chrome/browser/profiles/profile.cc index d54c56c..0d96782 100644 --- a/chrome/browser/profiles/profile.cc +++ b/chrome/browser/profiles/profile.cc @@ -7,26 +7,32 @@ #include <string> #include "base/command_line.h" +#include "base/compiler_specific.h" #include "base/file_path.h" #include "base/file_util.h" #include "base/path_service.h" #include "base/scoped_ptr.h" #include "base/string_util.h" +#include "build/build_config.h" +#include "chrome/browser/appcache/chrome_appcache_service.h" #include "chrome/browser/background_contents_service.h" #include "chrome/browser/browser_list.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_thread.h" #include "chrome/browser/chrome_blob_storage_context.h" #include "chrome/browser/dom_ui/chrome_url_data_manager.h" +#include "chrome/browser/content_settings/host_content_settings_map.h" #include "chrome/browser/download/download_manager.h" #include "chrome/browser/extensions/extension_message_service.h" #include "chrome/browser/extensions/extension_pref_store.h" #include "chrome/browser/extensions/extension_process_manager.h" #include "chrome/browser/file_system/browser_file_system_helper.h" +#include "chrome/browser/host_zoom_map.h" #include "chrome/browser/in_process_webkit/webkit_context.h" -#include "chrome/browser/net/chrome_url_request_context.h" #include "chrome/browser/net/pref_proxy_config_service.h" #include "chrome/browser/notifications/desktop_notification_service.h" +#include "chrome/browser/prefs/pref_service.h" +#include "chrome/browser/profiles/off_the_record_profile_io_data.h" #include "chrome/browser/ssl/ssl_host_state.h" #include "chrome/browser/sync/profile_sync_service.h" #include "chrome/browser/themes/browser_theme_provider.h" @@ -70,12 +76,6 @@ URLRequestContextGetter* Profile::default_request_context_; namespace { -// TODO(pathorn): Duplicated in profile_impl.cc -void CleanupRequestContext(ChromeURLRequestContextGetter* context) { - if (context) - context->CleanupOnUIThread(); -} - } // namespace Profile::Profile() @@ -157,8 +157,10 @@ class OffTheRecordProfileImpl : public Profile, explicit OffTheRecordProfileImpl(Profile* real_profile) : profile_(real_profile), prefs_(real_profile->GetOffTheRecordPrefs()), - start_time_(Time::Now()) { - request_context_ = ChromeURLRequestContextGetter::CreateOffTheRecord(this); + ALLOW_THIS_IN_INITIALIZER_LIST(io_data_(this)), + start_time_(Time::Now()), + db_tracker_(new webkit_database::DatabaseTracker( + profile_->GetPath(), true)) { extension_process_manager_.reset(ExtensionProcessManager::Create(this)); BrowserList::AddObserver(this); @@ -167,15 +169,20 @@ class OffTheRecordProfileImpl : public Profile, new BackgroundContentsService(this, CommandLine::ForCurrentProcess())); DCHECK(real_profile->GetPrefs()->GetBoolean(prefs::kIncognitoEnabled)); + + // TODO(oshima): Remove the need to eagerly initialize the request context + // getter. chromeos::OnlineAttempt is illegally trying to access this + // Profile member from a thread other than the UI thread, so we need to + // prevent a race. +#if defined(OS_CHROMEOS) + GetRequestContext(); +#endif // defined(OS_CHROMEOS) } virtual ~OffTheRecordProfileImpl() { NotificationService::current()->Notify(NotificationType::PROFILE_DESTROYED, Source<Profile>(this), NotificationService::NoDetails()); - CleanupRequestContext(request_context_); - CleanupRequestContext(extensions_request_context_); - // Clean up all DB files/directories BrowserThread::PostTask( BrowserThread::FILE, FROM_HERE, @@ -231,10 +238,6 @@ class OffTheRecordProfileImpl : public Profile, } virtual webkit_database::DatabaseTracker* GetDatabaseTracker() { - if (!db_tracker_) { - db_tracker_ = new webkit_database::DatabaseTracker( - GetPath(), IsOffTheRecord()); - } return db_tracker_; } @@ -408,21 +411,16 @@ class OffTheRecordProfileImpl : public Profile, } virtual URLRequestContextGetter* GetRequestContext() { - return request_context_; + return io_data_.GetMainRequestContextGetter(); } virtual URLRequestContextGetter* GetRequestContextForMedia() { // In OTR mode, media request context is the same as the original one. - return request_context_; + return io_data_.GetMainRequestContextGetter(); } URLRequestContextGetter* GetRequestContextForExtensions() { - if (!extensions_request_context_) { - extensions_request_context_ = - ChromeURLRequestContextGetter::CreateOffTheRecordForExtensions(this); - } - - return extensions_request_context_; + return io_data_.GetExtensionsRequestContextGetter(); } virtual net::SSLConfigService* GetSSLConfigService() { @@ -678,11 +676,7 @@ class OffTheRecordProfileImpl : public Profile, scoped_ptr<ExtensionProcessManager> extension_process_manager_; - // The context to use for requests made from this OTR session. - scoped_refptr<ChromeURLRequestContextGetter> request_context_; - - // The context to use for requests made by an extension while in OTR mode. - scoped_refptr<ChromeURLRequestContextGetter> extensions_request_context_; + OffTheRecordProfileIOData::Handle io_data_; // The download manager that only stores downloaded items in memory. scoped_refptr<DownloadManager> download_manager_; diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc index 15f9e9a..ecd7c0c 100644 --- a/chrome/browser/profiles/profile_impl.cc +++ b/chrome/browser/profiles/profile_impl.cc @@ -5,6 +5,7 @@ #include "chrome/browser/profiles/profile_impl.h" #include "base/command_line.h" +#include "base/compiler_specific.h" #include "base/environment.h" #include "base/file_path.h" #include "base/file_util.h" @@ -245,6 +246,7 @@ ProfileImpl::ProfileImpl(const FilePath& path) : path_(path), visited_link_event_listener_(new VisitedLinkEventListener()), extension_devtools_manager_(NULL), + ALLOW_THIS_IN_INITIALIZER_LIST(io_data_(this)), host_content_settings_map_(NULL), host_zoom_map_(NULL), history_service_created_(false), @@ -279,26 +281,6 @@ ProfileImpl::ProfileImpl(const FilePath& path) chrome::GetUserCacheDirectory(path_, &base_cache_path_); file_util::CreateDirectory(base_cache_path_); - FilePath cookie_path = GetPath(); - cookie_path = cookie_path.Append(chrome::kCookieFilename); - FilePath cache_path = base_cache_path_; - int cache_max_size; - GetCacheParameters(kNormalContext, &cache_path, &cache_max_size); - cache_path = GetCachePath(cache_path); - - FilePath media_cache_path = base_cache_path_; - int media_cache_max_size; - GetCacheParameters(kMediaContext, &media_cache_path, &media_cache_max_size); - media_cache_path = GetMediaCachePath(media_cache_path); - - FilePath extensions_cookie_path = GetPath(); - extensions_cookie_path = - extensions_cookie_path.Append(chrome::kExtensionsCookieFilename); - - io_data_.Init(cookie_path, cache_path, cache_max_size, - media_cache_path, media_cache_max_size, extensions_cookie_path, - this); - // Listen for theme installations from our original profile. registrar_.Add(this, NotificationType::THEME_INSTALLED, Source<Profile>(GetOriginalProfile())); @@ -331,8 +313,6 @@ ProfileImpl::ProfileImpl(const FilePath& path) extension_io_event_router_ = new ExtensionIOEventRouter(this); extension_info_map_ = new ExtensionInfoMap(); - GetPolicyContext()->Initialize(); - clear_local_state_on_exit_ = prefs->GetBoolean(prefs::kClearSiteDataOnExit); // Log the profile size after a reasonable startup delay. @@ -340,6 +320,34 @@ ProfileImpl::ProfileImpl(const FilePath& path) new ProfileSizeTask(path_), 112000); InstantController::RecordMetrics(this); + + FilePath cookie_path = GetPath(); + cookie_path = cookie_path.Append(chrome::kCookieFilename); + FilePath cache_path = base_cache_path_; + int cache_max_size; + GetCacheParameters(kNormalContext, &cache_path, &cache_max_size); + cache_path = GetCachePath(cache_path); + + FilePath media_cache_path = base_cache_path_; + int media_cache_max_size; + GetCacheParameters(kMediaContext, &media_cache_path, &media_cache_max_size); + media_cache_path = GetMediaCachePath(media_cache_path); + + FilePath extensions_cookie_path = GetPath(); + extensions_cookie_path = + extensions_cookie_path.Append(chrome::kExtensionsCookieFilename); + + ssl_config_service_manager_.reset( + SSLConfigServiceManager::CreateDefaultManager(this)); + + // Make sure we initialize the ProfileIOData after everything else has been + // initialized that we might be reading from the IO thread. + io_data_.Init(cookie_path, cache_path, cache_max_size, + media_cache_path, media_cache_max_size, extensions_cookie_path); + + // Initialize the ProfilePolicyContext after |io_data_| since it requires + // the URLRequestContextGetter to be initialized. + GetPolicyContext()->Initialize(); } void ProfileImpl::InitExtensions() { diff --git a/chrome/browser/profiles/profile_impl.h b/chrome/browser/profiles/profile_impl.h index 09ab45a..0934dbb 100644 --- a/chrome/browser/profiles/profile_impl.h +++ b/chrome/browser/profiles/profile_impl.h @@ -12,9 +12,9 @@ #include "base/ref_counted.h" #include "base/scoped_ptr.h" #include "base/timer.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/profiles/profile_io_data.h" #include "chrome/browser/prefs/pref_change_registrar.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_impl_io_data.h" #include "chrome/browser/spellcheck_host_observer.h" #include "chrome/common/notification_observer.h" #include "chrome/common/notification_registrar.h" @@ -217,7 +217,7 @@ class ProfileImpl : public Profile, scoped_ptr<ProfileSyncService> sync_service_; scoped_refptr<CloudPrintProxyService> cloud_print_proxy_service_; - ProfileIOData::Handle io_data_; + ProfileImplIOData::Handle io_data_; scoped_ptr<SSLConfigServiceManager> ssl_config_service_manager_; diff --git a/chrome/browser/profiles/profile_impl_io_data.cc b/chrome/browser/profiles/profile_impl_io_data.cc new file mode 100644 index 0000000..c746a63 --- /dev/null +++ b/chrome/browser/profiles/profile_impl_io_data.cc @@ -0,0 +1,282 @@ +// Copyright (c) 2011 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 "base/command_line.h" +#include "base/logging.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/browser_thread.h" +#include "chrome/browser/io_thread.h" +#include "chrome/browser/net/chrome_cookie_policy.h" +#include "chrome/browser/net/chrome_dns_cert_provenance_checker_factory.h" +#include "chrome/browser/net/chrome_net_log.h" +#include "chrome/browser/net/sqlite_persistent_cookie_store.h" +#include "chrome/common/chrome_constants.h" +#include "chrome/common/chrome_switches.h" +#include "chrome/common/url_constants.h" +#include "net/ftp/ftp_network_layer.h" +#include "net/http/http_cache.h" + +ProfileImplIOData::Handle::Handle(Profile* profile) + : io_data_(new ProfileImplIOData), + profile_(profile), + initialized_(false) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + DCHECK(profile); +} + +ProfileImplIOData::Handle::~Handle() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + if (main_request_context_getter_) + main_request_context_getter_->CleanupOnUIThread(); + if (media_request_context_getter_) + media_request_context_getter_->CleanupOnUIThread(); + if (extensions_request_context_getter_) + extensions_request_context_getter_->CleanupOnUIThread(); +} + +void ProfileImplIOData::Handle::Init(const FilePath& cookie_path, + const FilePath& cache_path, + int cache_max_size, + const FilePath& media_cache_path, + int media_cache_max_size, + const FilePath& extensions_cookie_path) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + DCHECK(!io_data_->lazy_params_.get()); + LazyParams* lazy_params = new LazyParams; + + lazy_params->cookie_path = cookie_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->io_thread = g_browser_process->io_thread(); + + io_data_->lazy_params_.reset(lazy_params); +} + +scoped_refptr<ChromeURLRequestContextGetter> +ProfileImplIOData::Handle::GetMainRequestContextGetter() const { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + LazyInitialize(); + if (!main_request_context_getter_) { + main_request_context_getter_ = + ChromeURLRequestContextGetter::CreateOriginal( + profile_, io_data_); + } + return main_request_context_getter_; +} + +scoped_refptr<ChromeURLRequestContextGetter> +ProfileImplIOData::Handle::GetMediaRequestContextGetter() const { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + LazyInitialize(); + if (!media_request_context_getter_) { + media_request_context_getter_ = + ChromeURLRequestContextGetter::CreateOriginalForMedia( + profile_, io_data_); + } + return media_request_context_getter_; +} + +scoped_refptr<ChromeURLRequestContextGetter> +ProfileImplIOData::Handle::GetExtensionsRequestContextGetter() const { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + LazyInitialize(); + if (!extensions_request_context_getter_) { + extensions_request_context_getter_ = + ChromeURLRequestContextGetter::CreateOriginalForExtensions( + profile_, io_data_); + } + return extensions_request_context_getter_; +} + +void ProfileImplIOData::Handle::LazyInitialize() const { + if (!initialized_) { + InitializeProfileParams(profile_, &io_data_->lazy_params_->profile_params); + initialized_ = true; + } +} + +ProfileImplIOData::LazyParams::LazyParams() + : cache_max_size(0), + media_cache_max_size(0), + io_thread(NULL) {} +ProfileImplIOData::LazyParams::~LazyParams() {} + +ProfileImplIOData::ProfileImplIOData() : ProfileIOData(false) {} +ProfileImplIOData::~ProfileImplIOData() {} + +void ProfileImplIOData::LazyInitializeInternal() const { + main_request_context_ = new RequestContext; + media_request_context_ = new RequestContext; + extensions_request_context_ = new RequestContext; + + IOThread* const io_thread = lazy_params_->io_thread; + IOThread::Globals* const io_thread_globals = io_thread->globals(); + const ProfileParams& profile_params = lazy_params_->profile_params; + const CommandLine& command_line = *CommandLine::ForCurrentProcess(); + bool record_mode = chrome::kRecordModeEnabled && + command_line.HasSwitch(switches::kRecordMode); + bool playback_mode = command_line.HasSwitch(switches::kPlaybackMode); + + // Initialize context members. + + ApplyProfileParamsToContext(profile_params, main_request_context_); + ApplyProfileParamsToContext(profile_params, media_request_context_); + ApplyProfileParamsToContext(profile_params, extensions_request_context_); + profile_params.appcache_service->set_request_context(main_request_context_); + scoped_refptr<ChromeCookiePolicy> cookie_policy = + new ChromeCookiePolicy(profile_params.host_content_settings_map); + + main_request_context_->set_chrome_cookie_policy(cookie_policy); + media_request_context_->set_chrome_cookie_policy(cookie_policy); + extensions_request_context_->set_chrome_cookie_policy(cookie_policy); + + main_request_context_->set_net_log(lazy_params_->io_thread->net_log()); + media_request_context_->set_net_log(lazy_params_->io_thread->net_log()); + extensions_request_context_->set_net_log(lazy_params_->io_thread->net_log()); + + main_request_context_->set_host_resolver( + io_thread_globals->host_resolver.get()); + media_request_context_->set_host_resolver( + io_thread_globals->host_resolver.get()); + main_request_context_->set_cert_verifier( + io_thread_globals->cert_verifier.get()); + media_request_context_->set_cert_verifier( + io_thread_globals->cert_verifier.get()); + main_request_context_->set_dnsrr_resolver( + io_thread_globals->dnsrr_resolver.get()); + media_request_context_->set_dnsrr_resolver( + io_thread_globals->dnsrr_resolver.get()); + main_request_context_->set_network_delegate( + &io_thread_globals->network_delegate); + // TODO(willchan): Enable for media request context. +#if 0 + media_request_context_->set_network_delegate( + &io_thread_globals->network_delegate); +#endif + main_request_context_->set_http_auth_handler_factory( + io_thread_globals->http_auth_handler_factory.get()); + media_request_context_->set_http_auth_handler_factory( + io_thread_globals->http_auth_handler_factory.get()); + + dns_cert_checker_.reset( + CreateDnsCertProvenanceChecker(io_thread_globals->dnsrr_resolver.get(), + main_request_context_)); + main_request_context_->set_dns_cert_checker(dns_cert_checker_.get()); + media_request_context_->set_dns_cert_checker(dns_cert_checker_.get()); + + net::ProxyService* proxy_service = + CreateProxyService( + io_thread->net_log(), + io_thread_globals->proxy_script_fetcher_context.get(), + lazy_params_->profile_params.proxy_config_service.release(), + command_line); + main_request_context_->set_proxy_service(proxy_service); + media_request_context_->set_proxy_service(proxy_service); + + net::HttpCache::DefaultBackend* main_backend = + new net::HttpCache::DefaultBackend( + net::DISK_CACHE, + lazy_params_->cache_path, + lazy_params_->cache_max_size, + BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE)); + net::HttpCache* main_cache = new net::HttpCache( + main_request_context_->host_resolver(), + main_request_context_->cert_verifier(), + main_request_context_->dnsrr_resolver(), + main_request_context_->dns_cert_checker(), + main_request_context_->proxy_service(), + main_request_context_->ssl_config_service(), + main_request_context_->http_auth_handler_factory(), + main_request_context_->network_delegate(), + main_request_context_->net_log(), + main_backend); + + net::HttpCache::DefaultBackend* media_backend = + new net::HttpCache::DefaultBackend( + net::MEDIA_CACHE, lazy_params_->media_cache_path, + lazy_params_->media_cache_max_size, + BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE)); + net::HttpNetworkSession* main_network_session = main_cache->GetSession(); + net::HttpCache* media_cache = + new net::HttpCache(main_network_session, media_backend); + + scoped_refptr<net::CookieStore> cookie_store = NULL; + if (record_mode || playback_mode) { + // Don't use existing cookies and use an in-memory store. + cookie_store = new net::CookieMonster( + NULL, profile_params.cookie_monster_delegate); + main_cache->set_mode( + record_mode ? net::HttpCache::RECORD : net::HttpCache::PLAYBACK); + } + + // setup cookie store + if (!cookie_store) { + DCHECK(!lazy_params_->cookie_path.empty()); + + scoped_refptr<SQLitePersistentCookieStore> cookie_db = + new SQLitePersistentCookieStore(lazy_params_->cookie_path); + cookie_db->SetClearLocalStateOnExit( + profile_params.clear_local_state_on_exit); + cookie_store = + new net::CookieMonster(cookie_db.get(), + profile_params.cookie_monster_delegate); + } + + net::CookieMonster* extensions_cookie_store = + new net::CookieMonster( + new SQLitePersistentCookieStore( + lazy_params_->extensions_cookie_path), NULL); + // Enable cookies for devtools and extension URLs. + const char* schemes[] = {chrome::kChromeDevToolsScheme, + chrome::kExtensionScheme}; + extensions_cookie_store->SetCookieableSchemes(schemes, 2); + + main_request_context_->set_cookie_store(cookie_store); + media_request_context_->set_cookie_store(cookie_store); + extensions_request_context_->set_cookie_store( + extensions_cookie_store); + + main_http_factory_.reset(main_cache); + media_http_factory_.reset(media_cache); + main_request_context_->set_http_transaction_factory(main_cache); + media_request_context_->set_http_transaction_factory(media_cache); + + main_request_context_->set_ftp_transaction_factory( + new net::FtpNetworkLayer(io_thread_globals->host_resolver.get())); + + lazy_params_.reset(); +} + +scoped_refptr<ChromeURLRequestContext> +ProfileImplIOData::AcquireMainRequestContext() const { + DCHECK(main_request_context_); + scoped_refptr<ChromeURLRequestContext> context = main_request_context_; + main_request_context_->set_profile_io_data(this); + main_request_context_ = NULL; + return context; +} + +scoped_refptr<ChromeURLRequestContext> +ProfileImplIOData::AcquireMediaRequestContext() const { + DCHECK(media_request_context_); + scoped_refptr<ChromeURLRequestContext> context = media_request_context_; + media_request_context_->set_profile_io_data(this); + media_request_context_ = NULL; + return context; +} + +scoped_refptr<ChromeURLRequestContext> +ProfileImplIOData::AcquireExtensionsRequestContext() const { + DCHECK(extensions_request_context_); + scoped_refptr<ChromeURLRequestContext> context = extensions_request_context_; + extensions_request_context_->set_profile_io_data(this); + extensions_request_context_ = NULL; + return context; +} diff --git a/chrome/browser/profiles/profile_impl_io_data.h b/chrome/browser/profiles/profile_impl_io_data.h new file mode 100644 index 0000000..ffc5e82 --- /dev/null +++ b/chrome/browser/profiles/profile_impl_io_data.h @@ -0,0 +1,114 @@ +// Copyright (c) 2011 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. + +#ifndef CHROME_BROWSER_PROFILES_PROFILE_IMPL_IO_DATA_H_ +#define CHROME_BROWSER_PROFILES_PROFILE_IMPL_IO_DATA_H_ +#pragma once + +#include "base/basictypes.h" +#include "base/ref_counted.h" +#include "chrome/browser/profiles/profile_io_data.h" + +class ProfileImplIOData : public ProfileIOData { + public: + class Handle { + public: + explicit Handle(Profile* profile); + ~Handle(); + + bool HasMainRequestContext() const { + return main_request_context_getter_ != NULL; + } + + // Init() must be called before ~Handle(). It records all the necessary + // parameters needed to construct a ChromeURLRequestContextGetter. + void Init(const FilePath& cookie_path, + const FilePath& cache_path, + int cache_max_size, + const FilePath& media_cache_path, + int media_cache_max_size, + const FilePath& extensions_cookie_path); + + scoped_refptr<ChromeURLRequestContextGetter> + GetMainRequestContextGetter() const; + scoped_refptr<ChromeURLRequestContextGetter> + GetMediaRequestContextGetter() const; + scoped_refptr<ChromeURLRequestContextGetter> + GetExtensionsRequestContextGetter() const; + + private: + // Lazily initialize ProfileParams. We do this on the calls to + // Get*RequestContextGetter(), so we only initialize ProfileParams right + // before posting a task to the IO thread to start using them. This prevents + // objects that are supposed to be deleted on the IO thread, but are created + // on the UI thread from being unnecessarily initialized. + void LazyInitialize() const; + + // Ordering is important here. Do not reorder unless you know what you're + // doing. We need to release |io_data_| *before* the getters, because we + // want to make sure that the last reference for |io_data_| is on the IO + // thread. The getters will be deleted on the IO thread, so they will + // release their refs to their contexts, which will release the last refs to + // the ProfileIOData on the IO thread. + mutable scoped_refptr<ChromeURLRequestContextGetter> + main_request_context_getter_; + mutable scoped_refptr<ChromeURLRequestContextGetter> + media_request_context_getter_; + mutable scoped_refptr<ChromeURLRequestContextGetter> + extensions_request_context_getter_; + const scoped_refptr<ProfileImplIOData> io_data_; + + Profile* const profile_; + + mutable bool initialized_; + + DISALLOW_COPY_AND_ASSIGN(Handle); + }; + + private: + friend class base::RefCountedThreadSafe<ProfileImplIOData>; + + struct LazyParams { + LazyParams(); + ~LazyParams(); + + // All of these parameters are intended to be read on the IO thread. + FilePath cookie_path; + FilePath cache_path; + int cache_max_size; + FilePath media_cache_path; + int media_cache_max_size; + FilePath extensions_cookie_path; + IOThread* io_thread; + + ProfileParams profile_params; + }; + + ProfileImplIOData(); + virtual ~ProfileImplIOData(); + + // Lazily initializes ProfileImplIOData. + virtual void LazyInitializeInternal() const; + virtual scoped_refptr<ChromeURLRequestContext> + AcquireMainRequestContext() const; + virtual scoped_refptr<ChromeURLRequestContext> + AcquireMediaRequestContext() const; + virtual scoped_refptr<ChromeURLRequestContext> + AcquireExtensionsRequestContext() const; + + // Lazy initialization params. + mutable scoped_ptr<LazyParams> lazy_params_; + + mutable scoped_refptr<RequestContext> main_request_context_; + mutable scoped_refptr<RequestContext> media_request_context_; + mutable scoped_refptr<RequestContext> extensions_request_context_; + + mutable scoped_ptr<net::DnsCertProvenanceChecker> dns_cert_checker_; + mutable scoped_ptr<net::HttpTransactionFactory> main_http_factory_; + mutable scoped_ptr<net::HttpTransactionFactory> media_http_factory_; + + DISALLOW_COPY_AND_ASSIGN(ProfileImplIOData); +}; + +#endif // CHROME_BROWSER_PROFILES_PROFILE_IMPL_IO_DATA_H_ diff --git a/chrome/browser/profiles/profile_io_data.cc b/chrome/browser/profiles/profile_io_data.cc index a2f6c5f..4926d68 100644 --- a/chrome/browser/profiles/profile_io_data.cc +++ b/chrome/browser/profiles/profile_io_data.cc @@ -7,107 +7,182 @@ #include "base/basictypes.h" #include "base/command_line.h" #include "base/logging.h" -#include "build/build_config.h" +#include "base/string_number_conversions.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_thread.h" -#include "chrome/browser/net/chrome_net_log.h" -#include "chrome/browser/net/chrome_url_request_context.h" +#include "chrome/browser/io_thread.h" +#include "chrome/browser/net/chrome_cookie_notification_details.h" +#include "chrome/browser/net/pref_proxy_config_service.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/prefs/pref_service.h" +#include "chrome/browser/extensions/user_script_master.h" +#include "chrome/common/chrome_switches.h" +#include "chrome/common/notification_service.h" +#include "chrome/common/pref_names.h" +#include "net/http/http_util.h" +#include "net/proxy/proxy_config_service_fixed.h" +#include "net/proxy/proxy_script_fetcher_impl.h" +#include "net/proxy/proxy_service.h" -ProfileIOData::Handle::Handle() : io_data_(new ProfileIOData) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); -} +#if defined(OS_CHROMEOS) +#include "chrome/browser/chromeos/cros/cros_library.h" +#include "chrome/browser/chromeos/cros/libcros_service_library.h" +#include "chrome/browser/chromeos/proxy_config_service.h" +#endif // defined(OS_CHROMEOS) -ProfileIOData::Handle::~Handle() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - if (main_request_context_getter_) - main_request_context_getter_->CleanupOnUIThread(); - if (media_request_context_getter_) - media_request_context_getter_->CleanupOnUIThread(); - if (extensions_request_context_getter_) - extensions_request_context_getter_->CleanupOnUIThread(); -} +namespace { -void ProfileIOData::Handle::Init(const FilePath& cookie_path, - const FilePath& cache_path, - int cache_max_size, - const FilePath& media_cache_path, - int media_cache_max_size, - const FilePath& extensions_cookie_path, - Profile* profile) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - DCHECK(!io_data_->lazy_params_.get()); - LazyParams* lazy_params = new LazyParams; - lazy_params->cookie_path = cookie_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->profile = profile; - lazy_params->io_thread = g_browser_process->io_thread(); - io_data_->lazy_params_.reset(lazy_params); -} +// ---------------------------------------------------------------------------- +// CookieMonster::Delegate implementation +// ---------------------------------------------------------------------------- +class ChromeCookieMonsterDelegate : public net::CookieMonster::Delegate { + public: + explicit ChromeCookieMonsterDelegate(Profile* profile) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + profile_getter_ = new ProfileGetter(profile); + } -scoped_refptr<ChromeURLRequestContextGetter> -ProfileIOData::Handle::GetMainRequestContextGetter() const { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - if (!main_request_context_getter_) { - main_request_context_getter_ = - ChromeURLRequestContextGetter::CreateOriginal( - io_data_->lazy_params_->profile, io_data_); + // net::CookieMonster::Delegate implementation. + virtual void OnCookieChanged( + const net::CookieMonster::CanonicalCookie& cookie, + bool removed) { + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + NewRunnableMethod(this, + &ChromeCookieMonsterDelegate::OnCookieChangedAsyncHelper, + cookie, + removed)); } - return main_request_context_getter_; -} -scoped_refptr<ChromeURLRequestContextGetter> -ProfileIOData::Handle::GetMediaRequestContextGetter() const { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - if (!media_request_context_getter_) { - media_request_context_getter_ = - ChromeURLRequestContextGetter::CreateOriginalForMedia( - io_data_->lazy_params_->profile, io_data_); + private: + // This class allows us to safely access the Profile pointer. The Delegate + // itself cannot observe the PROFILE_DESTROYED notification, since it cannot + // guarantee to be deleted on the UI thread and therefore unregister from + // the notifications. All methods of ProfileGetter must be invoked on the UI + // thread. + class ProfileGetter + : public base::RefCountedThreadSafe<ProfileGetter, + BrowserThread::DeleteOnUIThread>, + public NotificationObserver { + public: + explicit ProfileGetter(Profile* profile) : profile_(profile) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + registrar_.Add(this, + NotificationType::PROFILE_DESTROYED, + Source<Profile>(profile_)); + } + + // NotificationObserver implementation. + void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + if (NotificationType::PROFILE_DESTROYED == type) { + Profile* profile = Source<Profile>(source).ptr(); + if (profile_ == profile) + profile_ = NULL; + } + } + + Profile* get() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + return profile_; + } + + private: + friend class ::BrowserThread; + friend class DeleteTask<ProfileGetter>; + + virtual ~ProfileGetter() {} + + NotificationRegistrar registrar_; + + Profile* profile_; + }; + + virtual ~ChromeCookieMonsterDelegate() {} + + void OnCookieChangedAsyncHelper( + const net::CookieMonster::CanonicalCookie& cookie, + bool removed) { + if (profile_getter_->get()) { + ChromeCookieDetails cookie_details(&cookie, removed); + NotificationService::current()->Notify( + NotificationType::COOKIE_CHANGED, + Source<Profile>(profile_getter_->get()), + Details<ChromeCookieDetails>(&cookie_details)); + } } - return media_request_context_getter_; -} -scoped_refptr<ChromeURLRequestContextGetter> -ProfileIOData::Handle::GetExtensionsRequestContextGetter() const { + scoped_refptr<ProfileGetter> profile_getter_; +}; + +} // namespace + +void ProfileIOData::InitializeProfileParams(Profile* profile, + ProfileParams* params) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - if (!extensions_request_context_getter_) { - extensions_request_context_getter_ = - ChromeURLRequestContextGetter::CreateOriginalForExtensions( - io_data_->lazy_params_->profile, io_data_); - } - return extensions_request_context_getter_; -} + PrefService* pref_service = profile->GetPrefs(); + params->is_off_the_record = profile->IsOffTheRecord(); + params->clear_local_state_on_exit = + pref_service->GetBoolean(prefs::kClearSiteDataOnExit); -ProfileIOData::LazyParams::LazyParams() - : cache_max_size(0), - media_cache_max_size(0), - io_thread(NULL), - profile(NULL) { -} + params->appcache_service = profile->GetAppCacheService(); -ProfileIOData::LazyParams::~LazyParams() {} + // Set up Accept-Language and Accept-Charset header values + params->accept_language = net::HttpUtil::GenerateAcceptLanguageHeader( + pref_service->GetString(prefs::kAcceptLanguages)); + std::string default_charset = pref_service->GetString(prefs::kDefaultCharset); + params->accept_charset = + net::HttpUtil::GenerateAcceptCharsetHeader(default_charset); -class ProfileIOData::RequestContext : public ChromeURLRequestContext { - public: - RequestContext(); - ~RequestContext(); + // At this point, we don't know the charset of the referring page + // where a url request originates from. This is used to get a suggested + // filename from Content-Disposition header made of raw 8bit characters. + // Down the road, it can be overriden if it becomes known (for instance, + // when download request is made through the context menu in a web page). + // At the moment, it'll remain 'undeterministic' when a user + // types a URL in the omnibar or click on a download link in a page. + // For the latter, we need a change on the webkit-side. + // We initialize it to the default charset here and a user will + // have an *arguably* better default charset for interpreting a raw 8bit + // C-D header field. It means the native OS codepage fallback in + // net_util::GetSuggestedFilename is unlikely to be taken. + params->referrer_charset = default_charset; + + params->host_content_settings_map = profile->GetHostContentSettingsMap(); + params->host_zoom_map = profile->GetHostZoomMap(); + params->transport_security_state = profile->GetTransportSecurityState(); - void set_profile_io_data(const ProfileIOData* profile_io_data) { - profile_io_data_ = profile_io_data; + if (profile->GetUserScriptMaster()) { + params->user_script_dir_path = + profile->GetUserScriptMaster()->user_script_dir(); } - private: - scoped_refptr<const ProfileIOData> profile_io_data_; -}; + params->ssl_config_service = profile->GetSSLConfigService(); + params->cookie_monster_delegate = new ChromeCookieMonsterDelegate(profile); + params->database_tracker = profile->GetDatabaseTracker(); + params->appcache_service = profile->GetAppCacheService(); + params->blob_storage_context = profile->GetBlobStorageContext(); + params->file_system_context = profile->GetFileSystemContext(); + params->extension_info_map = profile->GetExtensionInfoMap(); + params->extension_io_event_router = profile->GetExtensionIOEventRouter(); + params->prerender_manager = profile->GetPrerenderManager(); + + params->proxy_config_service.reset(CreateProxyConfigService(profile)); +} ProfileIOData::RequestContext::RequestContext() {} ProfileIOData::RequestContext::~RequestContext() {} -ProfileIOData::ProfileIOData() : initialized_(false) { +ProfileIOData::ProfileParams::ProfileParams() + : is_off_the_record(false), + clear_local_state_on_exit(false) {} +ProfileIOData::ProfileParams::~ProfileParams() {} + +ProfileIOData::ProfileIOData(bool is_off_the_record) + : initialized_(false) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); } @@ -125,78 +200,144 @@ ProfileIOData::~ProfileIOData() { scoped_refptr<ChromeURLRequestContext> ProfileIOData::GetMainRequestContext() const { LazyInitialize(); - DCHECK(main_request_context_); - scoped_refptr<ChromeURLRequestContext> context = main_request_context_; - main_request_context_->set_profile_io_data(this); - main_request_context_ = NULL; + scoped_refptr<ChromeURLRequestContext> context = + AcquireMainRequestContext(); + DCHECK(context); return context; } scoped_refptr<ChromeURLRequestContext> ProfileIOData::GetMediaRequestContext() const { LazyInitialize(); - DCHECK(media_request_context_); - scoped_refptr<ChromeURLRequestContext> context = media_request_context_; - media_request_context_->set_profile_io_data(this); - media_request_context_ = NULL; + scoped_refptr<ChromeURLRequestContext> context = + AcquireMediaRequestContext(); + DCHECK(context); return context; } scoped_refptr<ChromeURLRequestContext> ProfileIOData::GetExtensionsRequestContext() const { LazyInitialize(); - DCHECK(extensions_request_context_); - scoped_refptr<ChromeURLRequestContext> context = extensions_request_context_; - extensions_request_context_->set_profile_io_data(this); - extensions_request_context_ = NULL; + scoped_refptr<ChromeURLRequestContext> context = + AcquireExtensionsRequestContext(); + DCHECK(context); return context; } -const ProfileIOData::LazyParams& ProfileIOData::lazy_params() const { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - DCHECK(lazy_params_.get()); - return *lazy_params_; -} - void ProfileIOData::LazyInitialize() const { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); if (initialized_) return; + LazyInitializeInternal(); + initialized_ = true; +} - main_request_context_ = new RequestContext; - media_request_context_ = new RequestContext; - extensions_request_context_ = new RequestContext; - - // Initialize context members. - IOThread::Globals* io_thread_globals = lazy_params_->io_thread->globals(); - - main_request_context_->set_net_log(lazy_params_->io_thread->net_log()); - media_request_context_->set_net_log(lazy_params_->io_thread->net_log()); - - main_request_context_->set_host_resolver( - io_thread_globals->host_resolver.get()); - main_request_context_->set_cert_verifier( - io_thread_globals->cert_verifier.get()); - main_request_context_->set_dnsrr_resolver( - io_thread_globals->dnsrr_resolver.get()); - main_request_context_->set_network_delegate( - &io_thread_globals->network_delegate); - - main_request_context_->set_http_auth_handler_factory( - io_thread_globals->http_auth_handler_factory.get()); - media_request_context_->set_http_auth_handler_factory( - io_thread_globals->http_auth_handler_factory.get()); - // TODO(cbentzel): How should extensions handle HTTP Authentication? - extensions_request_context_->set_http_auth_handler_factory( - io_thread_globals->http_auth_handler_factory.get()); - - // TODO(willchan): Initialize more of the contexts! - - // TODO(willchan): Enable this when LazyInitialize() is able to fully - // initialize all the ChromeURLRequestContexts. -#if 0 - params_.reset(); -#endif +// static +void ProfileIOData::ApplyProfileParamsToContext( + const ProfileParams& profile_params, + ChromeURLRequestContext* context) { + context->set_is_off_the_record(profile_params.is_off_the_record); + context->set_accept_language(profile_params.accept_language); + context->set_accept_charset(profile_params.accept_charset); + context->set_referrer_charset(profile_params.referrer_charset); + context->set_user_script_dir_path(profile_params.user_script_dir_path); + context->set_host_content_settings_map( + profile_params.host_content_settings_map); + context->set_host_zoom_map(profile_params.host_zoom_map); + context->set_transport_security_state( + profile_params.transport_security_state); + context->set_ssl_config_service(profile_params.ssl_config_service); + context->set_database_tracker(profile_params.database_tracker); + context->set_appcache_service(profile_params.appcache_service); + context->set_blob_storage_context(profile_params.blob_storage_context); + context->set_file_system_context(profile_params.file_system_context); + context->set_extension_info_map(profile_params.extension_info_map); + context->set_extension_io_event_router( + profile_params.extension_io_event_router); + context->set_prerender_manager(profile_params.prerender_manager); +} - initialized_ = true; +// static +net::ProxyConfigService* ProfileIOData::CreateProxyConfigService( + Profile* profile) { + // The linux gconf-based proxy settings getter relies on being initialized + // from the UI thread. + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + + // Create a baseline service that provides proxy configuration in case nothing + // is configured through prefs (Note: prefs include command line and + // configuration policy). + net::ProxyConfigService* base_service = NULL; + + // TODO(port): the IO and FILE message loops are only used by Linux. Can + // that code be moved to chrome/browser instead of being in net, so that it + // can use BrowserThread instead of raw MessageLoop pointers? See bug 25354. +#if defined(OS_CHROMEOS) + base_service = new chromeos::ProxyConfigService( + profile->GetChromeOSProxyConfigServiceImpl()); +#else + base_service = net::ProxyService::CreateSystemProxyConfigService( + g_browser_process->io_thread()->message_loop(), + g_browser_process->file_thread()->message_loop()); +#endif // defined(OS_CHROMEOS) + + return new PrefProxyConfigService(profile->GetProxyConfigTracker(), + base_service); +} + +// static +net::ProxyService* ProfileIOData::CreateProxyService( + net::NetLog* net_log, + net::URLRequestContext* context, + net::ProxyConfigService* proxy_config_service, + const CommandLine& command_line) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + + bool use_v8 = !command_line.HasSwitch(switches::kWinHttpProxyResolver); + if (use_v8 && command_line.HasSwitch(switches::kSingleProcess)) { + // See the note about V8 multithreading in net/proxy/proxy_resolver_v8.h + // to understand why we have this limitation. + LOG(ERROR) << "Cannot use V8 Proxy resolver in single process mode."; + use_v8 = false; // Fallback to non-v8 implementation. + } + + size_t num_pac_threads = 0u; // Use default number of threads. + + // Check the command line for an override on the number of proxy resolver + // threads to use. + if (command_line.HasSwitch(switches::kNumPacThreads)) { + std::string s = command_line.GetSwitchValueASCII(switches::kNumPacThreads); + + // Parse the switch (it should be a positive integer formatted as decimal). + int n; + if (base::StringToInt(s, &n) && n > 0) { + num_pac_threads = static_cast<size_t>(n); + } else { + LOG(ERROR) << "Invalid switch for number of PAC threads: " << s; + } + } + + net::ProxyService* proxy_service; + if (use_v8) { + proxy_service = net::ProxyService::CreateUsingV8ProxyResolver( + proxy_config_service, + num_pac_threads, + new net::ProxyScriptFetcherImpl(context), + context->host_resolver(), + net_log); + } else { + proxy_service = net::ProxyService::CreateUsingSystemProxyResolver( + proxy_config_service, + num_pac_threads, + net_log); + } + +#if defined(OS_CHROMEOS) + if (chromeos::CrosLibrary::Get()->EnsureLoaded()) { + chromeos::CrosLibrary::Get()->GetLibCrosServiceLibrary()-> + RegisterNetworkProxyHandler(proxy_service); + } +#endif // defined(OS_CHROMEOS) + + return proxy_service; } diff --git a/chrome/browser/profiles/profile_io_data.h b/chrome/browser/profiles/profile_io_data.h index 2d7f888..c598b91 100644 --- a/chrome/browser/profiles/profile_io_data.h +++ b/chrome/browser/profiles/profile_io_data.h @@ -10,85 +10,53 @@ #include "base/file_path.h" #include "base/ref_counted.h" #include "base/scoped_ptr.h" +#include "chrome/browser/net/chrome_url_request_context.h" +#include "net/base/cookie_monster.h" +class CommandLine; +class ChromeAppCacheService; +class ChromeBlobStorageContext; class ChromeURLRequestContext; class ChromeURLRequestContextGetter; +class ExtensionInfoMap; +class ExtensionIOEventRouter; +namespace fileapi { +class FileSystemContext; +} +class HostContentSettingsMap; +class HostZoomMap; class IOThread; +namespace net { +class DnsCertProvenanceChecker; +class NetLog; +class ProxyConfigService; +class ProxyService; +class SSLConfigService; +class TransportSecurityState; +} // namespace net +namespace prerender { +class PrerenderManager; +}; // namespace prerender class Profile; - -// ProfileImpl owns a ProfileIOData::Handle, which holds a reference to the -// ProfileIOData. ProfileIOData is intended to own all the objects owned by -// ProfileImpl which live on the IO thread, such as, but not limited to, network -// objects like CookieMonster, HttpTransactionFactory, etc. ProfileIOData is -// owned by the ProfileImpl and ProfileIOData's ChromeURLRequestContexts. When -// all of them go away, then ProfileIOData will be deleted. Note that the -// ProfileIOData will typically outlive the Profile it is "owned" by, so it's -// important for ProfileIOData not to hold any references to the Profile beyond -// what's used by LazyParams (which should be deleted after lazy -// initialization). +namespace webkit_database { +class DatabaseTracker; +} // webkit_database + +// Conceptually speaking, the ProfileIOData represents data that lives on the IO +// thread that is owned by a Profile, such as, but not limited to, network +// objects like CookieMonster, HttpTransactionFactory, etc. The Profile +// implementation will maintain a reference to the ProfileIOData. The +// ProfileIOData will originally own a reference to the ChromeURLRequestContexts +// that reference its members. When an accessor for a ChromeURLRequestContext is +// invoked, then ProfileIOData will release its reference to the +// ChromeURLRequestContext and the ChromeURLRequestContext will acquire a +// reference to the ProfileIOData, so they exchange ownership. This is done +// because it's possible for a context's accessor never to be invoked, so this +// ownership reversal prevents shutdown leaks. ProfileIOData will lazily +// initialize its members on the first invocation of a ChromeURLRequestContext +// accessor. class ProfileIOData : public base::RefCountedThreadSafe<ProfileIOData> { public: - class Handle { - public: - Handle(); - ~Handle(); - - // Init() must be called before ~Handle(). It records all the necessary - // parameters needed to construct a ChromeURLRequestContextGetter. - void Init(const FilePath& cookie_path, - const FilePath& cache_path, - int cache_max_size, - const FilePath& media_cache_path, - int media_cache_max_size, - const FilePath& extensions_cookie_path, - Profile* profile); - - bool HasMainRequestContext() const { - return main_request_context_getter_ != NULL; - } - scoped_refptr<ChromeURLRequestContextGetter> - GetMainRequestContextGetter() const; - scoped_refptr<ChromeURLRequestContextGetter> - GetMediaRequestContextGetter() const; - scoped_refptr<ChromeURLRequestContextGetter> - GetExtensionsRequestContextGetter() const; - - private: - // Ordering is important here. Do not reorder unless you know what you're - // doing. |io_data_| must be released before the getters to ensure - // that ProfileIOData is deleted on the IO thread. - mutable scoped_refptr<ChromeURLRequestContextGetter> - main_request_context_getter_; - mutable scoped_refptr<ChromeURLRequestContextGetter> - media_request_context_getter_; - mutable scoped_refptr<ChromeURLRequestContextGetter> - extensions_request_context_getter_; - const scoped_refptr<ProfileIOData> io_data_; - - DISALLOW_COPY_AND_ASSIGN(Handle); - }; - - // TODO(willchan): Move this to the private section when - // ChromeURLRequestContextFactory subclasses don't need it anymore. - struct LazyParams { - LazyParams(); - ~LazyParams(); - - // All of these parameters are intended to be read on the IO thread. - FilePath cookie_path; - FilePath cache_path; - int cache_max_size; - FilePath media_cache_path; - int media_cache_max_size; - FilePath extensions_cookie_path; - IOThread* io_thread; - - // TODO(willchan): Kill this, since the IO thread shouldn't be reading from - // the Profile. Instead, replace this with the parameters we want to copy - // from the UI thread to the IO thread. - Profile* profile; - }; - // These should only be called at most once each. Ownership is reversed they // get called, from ProfileIOData owning ChromeURLRequestContext to vice // versa. @@ -96,30 +64,93 @@ class ProfileIOData : public base::RefCountedThreadSafe<ProfileIOData> { scoped_refptr<ChromeURLRequestContext> GetMediaRequestContext() const; scoped_refptr<ChromeURLRequestContext> GetExtensionsRequestContext() const; - // TODO(willchan): Delete this when ChromeURLRequestContextFactory subclasses - // don't need it anymore. - const LazyParams& lazy_params() const; - - private: + protected: friend class base::RefCountedThreadSafe<ProfileIOData>; - class RequestContext; + class RequestContext : public ChromeURLRequestContext { + public: + RequestContext(); + ~RequestContext(); + + // Setter is used to transfer ownership of the ProfileIOData to the context. + void set_profile_io_data(const ProfileIOData* profile_io_data) { + profile_io_data_ = profile_io_data; + } - ProfileIOData(); - ~ProfileIOData(); + private: + scoped_refptr<const ProfileIOData> profile_io_data_; + }; - // Lazily initializes ProfileIOData. + // Created on the UI thread, read on the IO thread during ProfileIOData lazy + // initialization. + struct ProfileParams { + ProfileParams(); + ~ProfileParams(); + + bool is_off_the_record; + bool clear_local_state_on_exit; + std::string accept_language; + std::string accept_charset; + std::string referrer_charset; + FilePath user_script_dir_path; + scoped_refptr<HostContentSettingsMap> host_content_settings_map; + scoped_refptr<HostZoomMap> host_zoom_map; + scoped_refptr<net::TransportSecurityState> transport_security_state; + scoped_refptr<net::SSLConfigService> ssl_config_service; + scoped_refptr<net::CookieMonster::Delegate> cookie_monster_delegate; + scoped_refptr<webkit_database::DatabaseTracker> database_tracker; + scoped_refptr<ChromeAppCacheService> appcache_service; + scoped_refptr<ChromeBlobStorageContext> blob_storage_context; + scoped_refptr<fileapi::FileSystemContext> file_system_context; + scoped_refptr<ExtensionInfoMap> extension_info_map; + scoped_refptr<ExtensionIOEventRouter> extension_io_event_router; + scoped_refptr<prerender::PrerenderManager> prerender_manager; + // We need to initialize the ProxyConfigService from the UI thread + // because on linux it relies on initializing things through gconf, + // and needs to be on the main thread. + scoped_ptr<net::ProxyConfigService> proxy_config_service; + }; + + explicit ProfileIOData(bool is_off_the_record); + virtual ~ProfileIOData(); + + // Static helper functions to assist in common operations executed by + // subtypes. + + static void InitializeProfileParams(Profile* profile, ProfileParams* params); + static void ApplyProfileParamsToContext(const ProfileParams& profile_params, + ChromeURLRequestContext* context); + static net::ProxyConfigService* CreateProxyConfigService(Profile* profile); + static net::ProxyService* CreateProxyService( + net::NetLog* net_log, + net::URLRequestContext* context, + net::ProxyConfigService* proxy_config_service, + const CommandLine& command_line); + + // Lazy initializes the ProfileIOData object the first time a request context + // is requested. The lazy logic is implemented here. The actual initialization + // is done in LazyInitializeInternal(), implemented by subtypes. Static helper + // functions have been provided to assist in common operations. void LazyInitialize() const; - // Lazy initialization params. - // TODO(willchan): Delete after Initialize() finishes initializing all the - // contexts. - scoped_ptr<const LazyParams> lazy_params_; + // -------------------------------------------- + // Virtual interface for subtypes to implement: + // -------------------------------------------- + + // Does that actual initialization of the ProfileIOData subtype. Subtypes + // should use the static helper functions above to implement this. + virtual void LazyInitializeInternal() const = 0; + + // These functions are used to transfer ownership of the lazily initialized + // context from ProfileIOData to the URLRequestContextGetter. + virtual scoped_refptr<ChromeURLRequestContext> + AcquireMainRequestContext() const = 0; + virtual scoped_refptr<ChromeURLRequestContext> + AcquireMediaRequestContext() const = 0; + virtual scoped_refptr<ChromeURLRequestContext> + AcquireExtensionsRequestContext() const = 0; mutable bool initialized_; - mutable scoped_refptr<RequestContext> main_request_context_; - mutable scoped_refptr<RequestContext> media_request_context_; - mutable scoped_refptr<RequestContext> extensions_request_context_; DISALLOW_COPY_AND_ASSIGN(ProfileIOData); }; diff --git a/chrome/browser/renderer_host/resource_dispatcher_host.cc b/chrome/browser/renderer_host/resource_dispatcher_host.cc index c049ba4..d3d3d2b 100644 --- a/chrome/browser/renderer_host/resource_dispatcher_host.cc +++ b/chrome/browser/renderer_host/resource_dispatcher_host.cc @@ -62,6 +62,7 @@ #include "chrome/common/url_constants.h" #include "net/base/auth.h" #include "net/base/cert_status_flags.h" +#include "net/base/cookie_monster.h" #include "net/base/load_flags.h" #include "net/base/mime_util.h" #include "net/base/net_errors.h" diff --git a/chrome/browser/sync/glue/http_bridge.cc b/chrome/browser/sync/glue/http_bridge.cc index b51975c..0557c64 100644 --- a/chrome/browser/sync/glue/http_bridge.cc +++ b/chrome/browser/sync/glue/http_bridge.cc @@ -73,12 +73,12 @@ HttpBridge::RequestContext::RequestContext( : baseline_context_(baseline_context) { // Create empty, in-memory cookie store. - cookie_store_ = new net::CookieMonster(NULL, NULL); + set_cookie_store(new net::CookieMonster(NULL, NULL)); // We don't use a cache for bridged loads, but we do want to share proxy info. - host_resolver_ = baseline_context->host_resolver(); - proxy_service_ = baseline_context->proxy_service(); - ssl_config_service_ = baseline_context->ssl_config_service(); + set_host_resolver(baseline_context->host_resolver()); + set_proxy_service(baseline_context->proxy_service()); + set_ssl_config_service(baseline_context->ssl_config_service()); // We want to share the HTTP session data with the network layer factory, // which includes auth_cache for proxies. @@ -87,7 +87,7 @@ HttpBridge::RequestContext::RequestContext( net::HttpNetworkSession* session = baseline_context->http_transaction_factory()->GetSession(); DCHECK(session); - http_transaction_factory_ = new net::HttpNetworkLayer(session); + set_http_transaction_factory(new net::HttpNetworkLayer(session)); // TODO(timsteele): We don't currently listen for pref changes of these // fields or CookiePolicy; I'm not sure we want to strictly follow the @@ -96,19 +96,19 @@ HttpBridge::RequestContext::RequestContext( // should be tied to whatever the sync servers expect (if anything). These // fields should probably just be settable by sync backend; though we should // figure out if we need to give the user explicit control over policies etc. - accept_language_ = baseline_context->accept_language(); - accept_charset_ = baseline_context->accept_charset(); + set_accept_language(baseline_context->accept_language()); + set_accept_charset(baseline_context->accept_charset()); // We default to the browser's user agent. This can (and should) be overridden // with set_user_agent. - user_agent_ = webkit_glue::GetUserAgent(GURL()); + set_user_agent(webkit_glue::GetUserAgent(GURL())); - net_log_ = baseline_context->net_log(); + set_net_log(baseline_context->net_log()); } HttpBridge::RequestContext::~RequestContext() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - delete http_transaction_factory_; + delete http_transaction_factory(); } HttpBridge::HttpBridge(HttpBridge::RequestContextGetter* context_getter) diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index f6616a6..e97e48b 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -1902,10 +1902,14 @@ 'browser/process_singleton_win.cc', 'browser/profile_import_process_host.cc', 'browser/profile_import_process_host.h', + 'browser/profiles/off_the_record_profile_io_data.cc', + 'browser/profiles/off_the_record_profile_io_data.h', 'browser/profiles/profile.cc', 'browser/profiles/profile.h', 'browser/profiles/profile_impl.cc', 'browser/profiles/profile_impl.h', + 'browser/profiles/profile_impl_io_data.cc', + 'browser/profiles/profile_impl_io_data.h', 'browser/profiles/profile_io_data.cc', 'browser/profiles/profile_io_data.h', 'browser/profiles/profile_manager.cc', diff --git a/chrome/service/net/service_url_request_context.cc b/chrome/service/net/service_url_request_context.cc index e5d75cc..b09794e 100644 --- a/chrome/service/net/service_url_request_context.cc +++ b/chrome/service/net/service_url_request_context.cc @@ -105,9 +105,9 @@ std::string MakeUserAgentForServiceProcess() { ServiceURLRequestContext::ServiceURLRequestContext( const std::string& user_agent) : user_agent_(user_agent) { - host_resolver_ = + set_host_resolver( net::CreateSystemHostResolver(net::HostResolver::kDefaultParallelism, - NULL, NULL); + NULL, NULL)); DCHECK(g_service_process); // TODO(sanjeevr): Change CreateSystemProxyConfigService to accept a // MessageLoopProxy* instead of MessageLoop*. @@ -116,29 +116,30 @@ ServiceURLRequestContext::ServiceURLRequestContext( net::ProxyService::CreateSystemProxyConfigService( g_service_process->io_thread()->message_loop(), g_service_process->file_thread()->message_loop()); - proxy_service_ = net::ProxyService::CreateUsingSystemProxyResolver( - proxy_config_service, 0u, NULL); - cert_verifier_ = new net::CertVerifier; - dnsrr_resolver_ = new net::DnsRRResolver; - ftp_transaction_factory_ = new net::FtpNetworkLayer(host_resolver_); - ssl_config_service_ = new net::SSLConfigServiceDefaults; - http_auth_handler_factory_ = net::HttpAuthHandlerFactory::CreateDefault( - host_resolver_); + set_proxy_service(net::ProxyService::CreateUsingSystemProxyResolver( + proxy_config_service, 0u, NULL)); + set_cert_verifier(new net::CertVerifier); + set_dnsrr_resolver(new net::DnsRRResolver); + set_ftp_transaction_factory(new net::FtpNetworkLayer(host_resolver())); + set_ssl_config_service(new net::SSLConfigServiceDefaults); + set_http_auth_handler_factory(net::HttpAuthHandlerFactory::CreateDefault( + host_resolver())); net::HttpNetworkSession::Params session_params; - session_params.host_resolver = host_resolver_; - session_params.cert_verifier = cert_verifier_; - session_params.dnsrr_resolver = dnsrr_resolver_; - session_params.proxy_service = proxy_service_; - session_params.ssl_config_service = ssl_config_service_; + session_params.host_resolver = host_resolver(); + session_params.cert_verifier = cert_verifier(); + session_params.dnsrr_resolver = dnsrr_resolver(); + session_params.proxy_service = proxy_service(); + session_params.ssl_config_service = ssl_config_service(); scoped_refptr<net::HttpNetworkSession> network_session( new net::HttpNetworkSession(session_params)); - http_transaction_factory_ = new net::HttpCache( - network_session, - net::HttpCache::DefaultBackend::InMemory(0)); + set_http_transaction_factory( + new net::HttpCache( + network_session, + net::HttpCache::DefaultBackend::InMemory(0))); // In-memory cookie store. - cookie_store_ = new net::CookieMonster(NULL, NULL); - accept_language_ = "en-us,fr"; - accept_charset_ = "iso-8859-1,*,utf-8"; + set_cookie_store(new net::CookieMonster(NULL, NULL)); + set_accept_language("en-us,fr"); + set_accept_charset("iso-8859-1,*,utf-8"); } const std::string& ServiceURLRequestContext::GetUserAgent( @@ -150,11 +151,12 @@ const std::string& ServiceURLRequestContext::GetUserAgent( } ServiceURLRequestContext::~ServiceURLRequestContext() { - delete ftp_transaction_factory_; - delete http_transaction_factory_; - delete http_auth_handler_factory_; - delete cert_verifier_; - delete dnsrr_resolver_; + delete ftp_transaction_factory(); + delete http_transaction_factory(); + delete http_auth_handler_factory(); + delete cert_verifier(); + delete dnsrr_resolver(); + delete host_resolver(); } ServiceURLRequestContextGetter::ServiceURLRequestContextGetter() diff --git a/chrome/service/net/service_url_request_context.h b/chrome/service/net/service_url_request_context.h index 47d5c23e..7ffda3c 100644 --- a/chrome/service/net/service_url_request_context.h +++ b/chrome/service/net/service_url_request_context.h @@ -32,9 +32,6 @@ class MessageLoopProxy; class ServiceURLRequestContext : public net::URLRequestContext { public: explicit ServiceURLRequestContext(const std::string& user_agent); - void set_cookie_policy(net::CookiePolicy* policy) { - cookie_policy_ = policy; - } // Overridden from net::URLRequestContext: virtual const std::string& GetUserAgent(const GURL& url) const; @@ -68,4 +65,3 @@ class ServiceURLRequestContextGetter : public URLRequestContextGetter { }; #endif // CHROME_SERVICE_NET_SERVICE_URL_REQUEST_CONTEXT_H_ - diff --git a/chrome/test/testing_profile.cc b/chrome/test/testing_profile.cc index 9ddc8d1..3839847 100644 --- a/chrome/test/testing_profile.cc +++ b/chrome/test/testing_profile.cc @@ -122,7 +122,7 @@ class TestExtensionURLRequestContext : public net::URLRequestContext { net::CookieMonster* cookie_monster = new net::CookieMonster(NULL, NULL); const char* schemes[] = {chrome::kExtensionScheme}; cookie_monster->SetCookieableSchemes(schemes, 1); - cookie_store_ = cookie_monster; + set_cookie_store(cookie_monster); } }; diff --git a/chrome_frame/metrics_service.cc b/chrome_frame/metrics_service.cc index 706b591..a1242cb 100644 --- a/chrome_frame/metrics_service.cc +++ b/chrome_frame/metrics_service.cc @@ -142,10 +142,10 @@ class ChromeFrameUploadRequestContext : public net::URLRequestContext { ~ChromeFrameUploadRequestContext() { DVLOG(1) << __FUNCTION__; - delete http_transaction_factory_; - delete http_auth_handler_factory_; - delete cert_verifier_; - delete host_resolver_; + delete http_transaction_factory(); + delete http_auth_handler_factory(); + delete cert_verifier(); + delete host_resolver(); } void Initialize() { @@ -153,19 +153,19 @@ class ChromeFrameUploadRequestContext : public net::URLRequestContext { user_agent_ = http_utils::AddChromeFrameToUserAgentValue( user_agent_); - host_resolver_ = + set_host_resolver( net::CreateSystemHostResolver(net::HostResolver::kDefaultParallelism, - NULL, NULL); - cert_verifier_ = new net::CertVerifier; + NULL, NULL)); + set_cert_verifier(new net::CertVerifier); net::ProxyConfigService* proxy_config_service = net::ProxyService::CreateSystemProxyConfigService(NULL, NULL); DCHECK(proxy_config_service); - proxy_service_ = net::ProxyService::CreateUsingSystemProxyResolver( - proxy_config_service, 0, NULL); - DCHECK(proxy_service_); + set_proxy_service(net::ProxyService::CreateUsingSystemProxyResolver( + proxy_config_service, 0, NULL)); + DCHECK(proxy_service()); - ssl_config_service_ = new net::SSLConfigServiceDefaults; + set_ssl_config_service(new net::SSLConfigServiceDefaults); url_security_manager_.reset( net::URLSecurityManager::Create(NULL, NULL)); @@ -174,23 +174,23 @@ class ChromeFrameUploadRequestContext : public net::URLRequestContext { std::vector<std::string> supported_schemes; base::SplitString(csv_auth_schemes, ',', &supported_schemes); - http_auth_handler_factory_ = net::HttpAuthHandlerRegistryFactory::Create( - supported_schemes, url_security_manager_.get(), host_resolver_, - std::string(), false, false); + set_http_auth_handler_factory(net::HttpAuthHandlerRegistryFactory::Create( + supported_schemes, url_security_manager_.get(), host_resolver(), + std::string(), false, false)); net::HttpNetworkSession::Params session_params; - session_params.host_resolver = host_resolver_; - session_params.cert_verifier = cert_verifier_; - session_params.proxy_service = proxy_service_; + session_params.host_resolver = host_resolver(); + session_params.cert_verifier = cert_verifier(); + session_params.proxy_service = proxy_service(); session_params.http_auth_handler_factory = - http_auth_handler_factory_; - session_params.ssl_config_service = ssl_config_service_; + http_auth_handler_factory(); + session_params.ssl_config_service = ssl_config_service(); scoped_refptr<net::HttpNetworkSession> network_session = new net::HttpNetworkSession(session_params); - http_transaction_factory_ = new net::HttpCache( + set_http_transaction_factory(new net::HttpCache( network_session, - net::HttpCache::DefaultBackend::InMemory(0)); + net::HttpCache::DefaultBackend::InMemory(0))); } virtual const std::string& GetUserAgent(const GURL& url) const { diff --git a/net/base/cookie_policy.h b/net/base/cookie_policy.h index c32c8a9..43b689f 100644 --- a/net/base/cookie_policy.h +++ b/net/base/cookie_policy.h @@ -21,6 +21,8 @@ enum { class CookiePolicy { public: + virtual ~CookiePolicy() {} + // Determines if the URL's cookies may be read. // // Returns: @@ -57,9 +59,6 @@ class CookiePolicy { const GURL& first_party_for_cookies, const std::string& cookie_line, CompletionCallback* callback) = 0; - - protected: - virtual ~CookiePolicy() {} }; } // namespace net diff --git a/net/proxy/proxy_script_fetcher_impl_unittest.cc b/net/proxy/proxy_script_fetcher_impl_unittest.cc index 3dc4494..56cccb1 100644 --- a/net/proxy/proxy_script_fetcher_impl_unittest.cc +++ b/net/proxy/proxy_script_fetcher_impl_unittest.cc @@ -41,30 +41,30 @@ class RequestContext : public URLRequestContext { public: RequestContext() { ProxyConfig no_proxy; - host_resolver_ = + set_host_resolver( CreateSystemHostResolver(HostResolver::kDefaultParallelism, - NULL, NULL); - cert_verifier_ = new CertVerifier; - proxy_service_ = ProxyService::CreateFixed(no_proxy); - ssl_config_service_ = new SSLConfigServiceDefaults; + NULL, NULL)); + set_cert_verifier(new CertVerifier); + set_proxy_service(ProxyService::CreateFixed(no_proxy)); + set_ssl_config_service(new SSLConfigServiceDefaults); HttpNetworkSession::Params params; - params.host_resolver = host_resolver_; - params.cert_verifier = cert_verifier_; - params.proxy_service = proxy_service_; - params.ssl_config_service = ssl_config_service_; + params.host_resolver = host_resolver(); + params.cert_verifier = cert_verifier(); + params.proxy_service = proxy_service(); + params.ssl_config_service = ssl_config_service(); scoped_refptr<HttpNetworkSession> network_session( new HttpNetworkSession(params)); - http_transaction_factory_ = new HttpCache( + set_http_transaction_factory(new HttpCache( network_session, - HttpCache::DefaultBackend::InMemory(0)); + HttpCache::DefaultBackend::InMemory(0))); } private: ~RequestContext() { - delete http_transaction_factory_; - delete cert_verifier_; - delete host_resolver_; + delete http_transaction_factory(); + delete cert_verifier(); + delete host_resolver(); } }; diff --git a/net/spdy/spdy_test_util.cc b/net/spdy/spdy_test_util.cc index 5340f22..6342b16 100644 --- a/net/spdy/spdy_test_util.cc +++ b/net/spdy/spdy_test_util.cc @@ -914,32 +914,32 @@ HttpNetworkSession* SpdySessionDependencies::SpdyCreateSessionDeterministic( } SpdyURLRequestContext::SpdyURLRequestContext() { - host_resolver_ = new MockHostResolver(); - cert_verifier_ = new CertVerifier; - proxy_service_ = ProxyService::CreateDirect(); - ssl_config_service_ = new SSLConfigServiceDefaults; - http_auth_handler_factory_ = HttpAuthHandlerFactory::CreateDefault( - host_resolver_); + set_host_resolver(new MockHostResolver()); + set_cert_verifier(new CertVerifier); + set_proxy_service(ProxyService::CreateDirect()); + set_ssl_config_service(new SSLConfigServiceDefaults); + set_http_auth_handler_factory(HttpAuthHandlerFactory::CreateDefault( + host_resolver())); net::HttpNetworkSession::Params params; params.client_socket_factory = &socket_factory_; - params.host_resolver = host_resolver_; - params.cert_verifier = cert_verifier_; - params.proxy_service = proxy_service_; - params.ssl_config_service = ssl_config_service_; - params.http_auth_handler_factory = http_auth_handler_factory_; - params.network_delegate = network_delegate_; + params.host_resolver = host_resolver(); + params.cert_verifier = cert_verifier(); + params.proxy_service = proxy_service(); + params.ssl_config_service = ssl_config_service(); + params.http_auth_handler_factory = http_auth_handler_factory(); + params.network_delegate = network_delegate(); scoped_refptr<HttpNetworkSession> network_session( new HttpNetworkSession(params)); - http_transaction_factory_ = new HttpCache( + set_http_transaction_factory(new HttpCache( network_session, - HttpCache::DefaultBackend::InMemory(0)); + HttpCache::DefaultBackend::InMemory(0))); } SpdyURLRequestContext::~SpdyURLRequestContext() { - delete http_transaction_factory_; - delete http_auth_handler_factory_; - delete cert_verifier_; - delete host_resolver_; + delete http_transaction_factory(); + delete http_auth_handler_factory(); + delete cert_verifier(); + delete host_resolver(); } const SpdyHeaderInfo make_spdy_header(spdy::SpdyControlType type) { diff --git a/net/url_request/url_request_context.cc b/net/url_request/url_request_context.cc index 6eb075c..2f558cc 100644 --- a/net/url_request/url_request_context.cc +++ b/net/url_request/url_request_context.cc @@ -7,22 +7,24 @@ #include "base/string_util.h" #include "net/base/cookie_store.h" #include "net/base/host_resolver.h" +#include "net/ftp/ftp_transaction_factory.h" +#include "net/http/http_transaction_factory.h" namespace net { URLRequestContext::URLRequestContext() - : net_log_(NULL), + : is_main_(false), + net_log_(NULL), host_resolver_(NULL), cert_verifier_(NULL), dnsrr_resolver_(NULL), dns_cert_checker_(NULL), - http_transaction_factory_(NULL), - ftp_transaction_factory_(NULL), http_auth_handler_factory_(NULL), network_delegate_(NULL), cookie_policy_(NULL), transport_security_state_(NULL), - is_main_(false) { + http_transaction_factory_(NULL), + ftp_transaction_factory_(NULL) { } void URLRequestContext::set_cookie_store(CookieStore* cookie_store) { diff --git a/net/url_request/url_request_context.h b/net/url_request/url_request_context.h index 18315dc..45240d7 100644 --- a/net/url_request/url_request_context.h +++ b/net/url_request/url_request_context.h @@ -75,21 +75,22 @@ class URLRequestContext } DnsCertProvenanceChecker* dns_cert_checker() const { - return dns_cert_checker_.get(); + return dns_cert_checker_; } - - // Get the proxy service for this context. - ProxyService* proxy_service() const { - return proxy_service_; + void set_dns_cert_checker(net::DnsCertProvenanceChecker* dns_cert_checker) { + dns_cert_checker_ = dns_cert_checker; } + // Get the proxy service for this context. + ProxyService* proxy_service() const { return proxy_service_; } void set_proxy_service(ProxyService* proxy_service) { proxy_service_ = proxy_service; } // Get the ssl config service for this context. - SSLConfigService* ssl_config_service() const { - return ssl_config_service_; + SSLConfigService* ssl_config_service() const { return ssl_config_service_; } + void set_ssl_config_service(net::SSLConfigService* service) { + ssl_config_service_ = service; } // Gets the HTTP Authentication Handler Factory for this context. @@ -105,7 +106,6 @@ class URLRequestContext HttpTransactionFactory* http_transaction_factory() const { return http_transaction_factory_; } - void set_http_transaction_factory(HttpTransactionFactory* factory) { http_transaction_factory_ = factory; } @@ -114,33 +114,49 @@ class URLRequestContext FtpTransactionFactory* ftp_transaction_factory() { return ftp_transaction_factory_; } + void set_ftp_transaction_factory(net::FtpTransactionFactory* factory) { + ftp_transaction_factory_ = factory; + } void set_network_delegate(HttpNetworkDelegate* network_delegate) { network_delegate_ = network_delegate; } - HttpNetworkDelegate* network_delegate() { return network_delegate_; } + HttpNetworkDelegate* network_delegate() const { return network_delegate_; } // Gets the cookie store for this context (may be null, in which case // cookies are not stored). - CookieStore* cookie_store() { return cookie_store_.get(); } - + CookieStore* cookie_store() const { return cookie_store_.get(); } void set_cookie_store(CookieStore* cookie_store); // Gets the cookie policy for this context (may be null, in which case // cookies are allowed). - CookiePolicy* cookie_policy() { return cookie_policy_; } + CookiePolicy* cookie_policy() const { return cookie_policy_; } + void set_cookie_policy(CookiePolicy* cookie_policy) { + cookie_policy_ = cookie_policy; + } - TransportSecurityState* transport_security_state() { - return transport_security_state_; } + TransportSecurityState* transport_security_state() const { + return transport_security_state_; + } + void set_transport_security_state( + net::TransportSecurityState* state) { + transport_security_state_ = state; + } // Gets the FTP authentication cache for this context. FtpAuthCache* ftp_auth_cache() { return &ftp_auth_cache_; } // Gets the value of 'Accept-Charset' header field. const std::string& accept_charset() const { return accept_charset_; } + void set_accept_charset(const std::string& accept_charset) { + accept_charset_ = accept_charset; + } // Gets the value of 'Accept-Language' header field. const std::string& accept_language() const { return accept_language_; } + void set_accept_language(const std::string& accept_language) { + accept_language_ = accept_language; + } // Gets the UA string to use for the given URL. Pass an invalid URL (such as // GURL()) to get the default UA string. Subclasses should override this @@ -164,18 +180,20 @@ class URLRequestContext virtual ~URLRequestContext(); - // The following members are expected to be initialized and owned by - // subclasses. + private: + // Indicates whether or not this is the main URLRequestContext. + bool is_main_; + + // Ownership for these members are not defined here. Clients should either + // provide storage elsewhere or have a subclass take ownership. NetLog* net_log_; HostResolver* host_resolver_; CertVerifier* cert_verifier_; DnsRRResolver* dnsrr_resolver_; - scoped_ptr<DnsCertProvenanceChecker> dns_cert_checker_; + DnsCertProvenanceChecker* dns_cert_checker_; + HttpAuthHandlerFactory* http_auth_handler_factory_; scoped_refptr<ProxyService> proxy_service_; scoped_refptr<SSLConfigService> ssl_config_service_; - HttpTransactionFactory* http_transaction_factory_; - FtpTransactionFactory* ftp_transaction_factory_; - HttpAuthHandlerFactory* http_auth_handler_factory_; HttpNetworkDelegate* network_delegate_; scoped_refptr<CookieStore> cookie_store_; CookiePolicy* cookie_policy_; @@ -188,9 +206,8 @@ class URLRequestContext // filename for file download. std::string referrer_charset_; - private: - // Indicates whether or not this is the main URLRequestContext. - bool is_main_; + HttpTransactionFactory* http_transaction_factory_; + FtpTransactionFactory* ftp_transaction_factory_; DISALLOW_COPY_AND_ASSIGN(URLRequestContext); }; diff --git a/net/url_request/url_request_test_util.cc b/net/url_request/url_request_test_util.cc index 3e93648..b20cfc7 100644 --- a/net/url_request/url_request_test_util.cc +++ b/net/url_request/url_request_test_util.cc @@ -79,52 +79,52 @@ void TestCookiePolicy::DoSetCookiePolicy(const GURL& url, TestURLRequestContext::TestURLRequestContext() { - host_resolver_ = + set_host_resolver( net::CreateSystemHostResolver(net::HostResolver::kDefaultParallelism, - NULL, NULL); - proxy_service_ = net::ProxyService::CreateDirect(); + NULL, NULL)); + set_proxy_service(net::ProxyService::CreateDirect()); Init(); } TestURLRequestContext::TestURLRequestContext(const std::string& proxy) { - host_resolver_ = + set_host_resolver( net::CreateSystemHostResolver(net::HostResolver::kDefaultParallelism, - NULL, NULL); + NULL, NULL)); net::ProxyConfig proxy_config; proxy_config.proxy_rules().ParseFromString(proxy); - proxy_service_ = net::ProxyService::CreateFixed(proxy_config); + set_proxy_service(net::ProxyService::CreateFixed(proxy_config)); Init(); } TestURLRequestContext::~TestURLRequestContext() { - delete ftp_transaction_factory_; - delete http_transaction_factory_; - delete http_auth_handler_factory_; - delete cert_verifier_; - delete host_resolver_; + delete ftp_transaction_factory(); + delete http_transaction_factory(); + delete http_auth_handler_factory(); + delete cert_verifier(); + delete host_resolver(); } void TestURLRequestContext::Init() { - cert_verifier_ = new net::CertVerifier; - ftp_transaction_factory_ = new net::FtpNetworkLayer(host_resolver_); - ssl_config_service_ = new net::SSLConfigServiceDefaults; - http_auth_handler_factory_ = net::HttpAuthHandlerFactory::CreateDefault( - host_resolver_); + set_cert_verifier(new net::CertVerifier); + set_ftp_transaction_factory(new net::FtpNetworkLayer(host_resolver())); + set_ssl_config_service(new net::SSLConfigServiceDefaults); + set_http_auth_handler_factory(net::HttpAuthHandlerFactory::CreateDefault( + host_resolver())); net::HttpNetworkSession::Params params; - params.host_resolver = host_resolver_; - params.cert_verifier = cert_verifier_; - params.proxy_service = proxy_service_; - params.ssl_config_service = ssl_config_service_; - params.http_auth_handler_factory = http_auth_handler_factory_; - params.network_delegate = network_delegate_; - - http_transaction_factory_ = new net::HttpCache( + params.host_resolver = host_resolver(); + params.cert_verifier = cert_verifier(); + params.proxy_service = proxy_service(); + params.ssl_config_service = ssl_config_service(); + params.http_auth_handler_factory = http_auth_handler_factory(); + params.network_delegate = network_delegate(); + + set_http_transaction_factory(new net::HttpCache( new net::HttpNetworkSession(params), - net::HttpCache::DefaultBackend::InMemory(0)); + net::HttpCache::DefaultBackend::InMemory(0))); // In-memory cookie store. - cookie_store_ = new net::CookieMonster(NULL, NULL); - accept_language_ = "en-us,fr"; - accept_charset_ = "iso-8859-1,*,utf-8"; + set_cookie_store(new net::CookieMonster(NULL, NULL)); + set_accept_language("en-us,fr"); + set_accept_charset("iso-8859-1,*,utf-8"); } diff --git a/net/url_request/url_request_test_util.h b/net/url_request/url_request_test_util.h index ab71db1..3f8b4b4 100644 --- a/net/url_request/url_request_test_util.h +++ b/net/url_request/url_request_test_util.h @@ -76,10 +76,6 @@ class TestURLRequestContext : public net::URLRequestContext { TestURLRequestContext(); explicit TestURLRequestContext(const std::string& proxy); - void set_cookie_policy(net::CookiePolicy* policy) { - cookie_policy_ = policy; - } - protected: virtual ~TestURLRequestContext(); diff --git a/net/url_request/view_cache_helper_unittest.cc b/net/url_request/view_cache_helper_unittest.cc index 5a656f2..e9e497b 100644 --- a/net/url_request/view_cache_helper_unittest.cc +++ b/net/url_request/view_cache_helper_unittest.cc @@ -28,7 +28,7 @@ class TestURLRequestContext : public net::URLRequestContext { TestURLRequestContext::TestURLRequestContext() : cache_(reinterpret_cast<net::HttpTransactionFactory*>(NULL), NULL, net::HttpCache::DefaultBackend::InMemory(0)) { - http_transaction_factory_ = &cache_; + set_http_transaction_factory(&cache_); } void WriteHeaders(disk_cache::Entry* entry, int flags, const std::string data) { diff --git a/net/websockets/websocket_job_unittest.cc b/net/websockets/websocket_job_unittest.cc index 2133cfa..37013b9 100644 --- a/net/websockets/websocket_job_unittest.cc +++ b/net/websockets/websocket_job_unittest.cc @@ -181,8 +181,8 @@ class MockURLRequestContext : public URLRequestContext { public: MockURLRequestContext(CookieStore* cookie_store, CookiePolicy* cookie_policy) { - cookie_store_ = cookie_store; - cookie_policy_ = cookie_policy; + set_cookie_store(cookie_store); + set_cookie_policy(cookie_policy); } private: diff --git a/webkit/tools/test_shell/test_shell_request_context.cc b/webkit/tools/test_shell/test_shell_request_context.cc index 4d7a68a..6502674 100644 --- a/webkit/tools/test_shell/test_shell_request_context.cc +++ b/webkit/tools/test_shell/test_shell_request_context.cc @@ -36,12 +36,12 @@ void TestShellRequestContext::Init( const FilePath& cache_path, net::HttpCache::Mode cache_mode, bool no_proxy) { - cookie_store_ = new net::CookieMonster(NULL, NULL); - cookie_policy_ = new net::StaticCookiePolicy(); + set_cookie_store(new net::CookieMonster(NULL, NULL)); + set_cookie_policy(new net::StaticCookiePolicy()); // hard-code A-L and A-C for test shells - accept_language_ = "en-us,en"; - accept_charset_ = "iso-8859-1,*,utf-8"; + set_accept_language("en-us,en"); + set_accept_charset("iso-8859-1,*,utf-8"); #if defined(OS_POSIX) && !defined(OS_MACOSX) // Use no proxy to avoid ProxyConfigServiceLinux. @@ -60,41 +60,41 @@ void TestShellRequestContext::Init( net::ProxyService::CreateSystemProxyConfigService( MessageLoop::current(), NULL)); #endif - host_resolver_ = + set_host_resolver( net::CreateSystemHostResolver(net::HostResolver::kDefaultParallelism, - NULL, NULL); - cert_verifier_ = new net::CertVerifier; - proxy_service_ = net::ProxyService::CreateUsingSystemProxyResolver( - proxy_config_service.release(), 0, NULL); - ssl_config_service_ = net::SSLConfigService::CreateSystemSSLConfigService(); + NULL, NULL)); + set_cert_verifier(new net::CertVerifier); + set_proxy_service(net::ProxyService::CreateUsingSystemProxyResolver( + proxy_config_service.release(), 0, NULL)); + set_ssl_config_service(net::SSLConfigService::CreateSystemSSLConfigService()); - http_auth_handler_factory_ = net::HttpAuthHandlerFactory::CreateDefault( - host_resolver_); + set_http_auth_handler_factory(net::HttpAuthHandlerFactory::CreateDefault( + host_resolver())); net::HttpCache::DefaultBackend* backend = new net::HttpCache::DefaultBackend( cache_path.empty() ? net::MEMORY_CACHE : net::DISK_CACHE, cache_path, 0, SimpleResourceLoaderBridge::GetCacheThread()); net::HttpCache* cache = - new net::HttpCache(host_resolver_, cert_verifier_, NULL, NULL, - proxy_service_, ssl_config_service_, - http_auth_handler_factory_, NULL, NULL, backend); + new net::HttpCache(host_resolver(), cert_verifier(), NULL, NULL, + proxy_service(), ssl_config_service(), + http_auth_handler_factory(), NULL, NULL, backend); cache->set_mode(cache_mode); - http_transaction_factory_ = cache; + set_http_transaction_factory(cache); - ftp_transaction_factory_ = new net::FtpNetworkLayer(host_resolver_); + set_ftp_transaction_factory(new net::FtpNetworkLayer(host_resolver())); blob_storage_controller_.reset(new webkit_blob::BlobStorageController()); } TestShellRequestContext::~TestShellRequestContext() { - delete ftp_transaction_factory_; - delete http_transaction_factory_; - delete http_auth_handler_factory_; - delete static_cast<net::StaticCookiePolicy*>(cookie_policy_); - delete cert_verifier_; - delete host_resolver_; + delete ftp_transaction_factory(); + delete http_transaction_factory(); + delete http_auth_handler_factory(); + delete cookie_policy(); + delete cert_verifier(); + delete host_resolver(); } const std::string& TestShellRequestContext::GetUserAgent( |