| Index: chrome/browser/net/chrome_url_request_context.cc
|
| ===================================================================
|
| --- chrome/browser/net/chrome_url_request_context.cc (revision 29872)
|
| +++ chrome/browser/net/chrome_url_request_context.cc (working copy)
|
| @@ -24,10 +24,31 @@
|
| #include "net/http/http_cache.h"
|
| #include "net/http/http_network_layer.h"
|
| #include "net/http/http_util.h"
|
| +#include "net/proxy/proxy_config_service_fixed.h"
|
| #include "net/proxy/proxy_service.h"
|
| #include "net/url_request/url_request.h"
|
| #include "webkit/glue/webkit_glue.h"
|
|
|
| +#if defined(OS_LINUX)
|
| +#include "net/ocsp/nss_ocsp.h"
|
| +#endif
|
| +
|
| +// TODO(eroman): Fix the definition ordering to match-up with the declaration
|
| +// ordering (this was done to help keep the diffs simple during
|
| +// refactor).
|
| +
|
| +// TODO(eroman): The ChromeURLRequestContext's Blacklist* is shared with the
|
| +// Profile... This is a problem since the Profile dies before
|
| +// the IO thread, so we may end up accessing a deleted variable.
|
| +
|
| +static void CheckCurrentlyOnIOThread() {
|
| + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
|
| +}
|
| +
|
| +static void CheckCurrentlyOnMainThread() {
|
| + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
|
| +}
|
| +
|
| net::ProxyConfig* CreateProxyConfig(const CommandLine& command_line) {
|
| // Scan for all "enable" type proxy switches.
|
| static const char* proxy_switches[] = {
|
| @@ -86,10 +107,33 @@
|
| return proxy_config;
|
| }
|
|
|
| +static net::ProxyConfigService* CreateProxyConfigService(
|
| + const CommandLine& command_line) {
|
| + // The linux gconf-based proxy settings getter relies on being initialized
|
| + // from the UI thread.
|
| + CheckCurrentlyOnMainThread();
|
| +
|
| + scoped_ptr<net::ProxyConfig> proxy_config_from_cmd_line(
|
| + CreateProxyConfig(command_line));
|
| +
|
| + if (!proxy_config_from_cmd_line.get()) {
|
| + // Use system settings.
|
| + return net::ProxyService::CreateSystemProxyConfigService(
|
| + g_browser_process->io_thread()->message_loop(),
|
| + g_browser_process->file_thread()->message_loop());
|
| + }
|
| +
|
| + // Otherwise use the fixed settings from the command line.
|
| + return new net::ProxyConfigServiceFixed(*proxy_config_from_cmd_line.get());
|
| +}
|
| +
|
| // Create a proxy service according to the options on command line.
|
| -static net::ProxyService* CreateProxyService(URLRequestContext* context,
|
| - const CommandLine& command_line) {
|
| - scoped_ptr<net::ProxyConfig> proxy_config(CreateProxyConfig(command_line));
|
| +static net::ProxyService* CreateProxyService(
|
| + URLRequestContext* context,
|
| + net::ProxyConfigService* proxy_config_service,
|
| + const CommandLine& command_line,
|
| + MessageLoop* io_loop) {
|
| + CheckCurrentlyOnIOThread();
|
|
|
| bool use_v8 = !command_line.HasSwitch(switches::kWinHttpProxyResolver);
|
| if (use_v8 && command_line.HasSwitch(switches::kSingleProcess)) {
|
| @@ -100,38 +144,87 @@
|
| }
|
|
|
| return net::ProxyService::Create(
|
| - proxy_config.get(),
|
| + proxy_config_service,
|
| use_v8,
|
| context,
|
| - g_browser_process->io_thread()->message_loop(),
|
| - g_browser_process->file_thread()->message_loop());
|
| + io_loop);
|
| }
|
|
|
| +// Lazily create a ChromeURLRequestContext using our factory.
|
| +URLRequestContext* ChromeURLRequestContextGetter::GetURLRequestContext() {
|
| + CheckCurrentlyOnIOThread();
|
| +
|
| + if (!url_request_context_) {
|
| + DCHECK(factory_.get());
|
| + url_request_context_ = factory_->Create();
|
| + factory_.reset();
|
| + }
|
| +
|
| + return url_request_context_;
|
| +}
|
| +
|
| +// Factory that creates the main ChromeURLRequestContext.
|
| +class FactoryForOriginal : public ChromeURLRequestContextFactory {
|
| + public:
|
| + FactoryForOriginal(Profile* profile,
|
| + const FilePath& cookie_store_path,
|
| + const FilePath& disk_cache_path,
|
| + int cache_size)
|
| + : ChromeURLRequestContextFactory(profile),
|
| + cookie_store_path_(cookie_store_path),
|
| + disk_cache_path_(disk_cache_path),
|
| + cache_size_(cache_size),
|
| + // 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(
|
| + *CommandLine::ForCurrentProcess())) {
|
| + }
|
| +
|
| + virtual ChromeURLRequestContext* Create();
|
| +
|
| + private:
|
| + FilePath cookie_store_path_;
|
| + FilePath disk_cache_path_;
|
| + int cache_size_;
|
| +
|
| + scoped_ptr<net::ProxyConfigService> proxy_config_service_;
|
| +};
|
| +
|
| // static
|
| -ChromeURLRequestContext* ChromeURLRequestContext::CreateOriginal(
|
| +ChromeURLRequestContextGetter* ChromeURLRequestContextGetter::CreateOriginal(
|
| Profile* profile, const FilePath& cookie_store_path,
|
| - const FilePath& disk_cache_path, int cache_size,
|
| - ChromeAppCacheService* appcache_service) {
|
| + const FilePath& disk_cache_path, int cache_size) {
|
| DCHECK(!profile->IsOffTheRecord());
|
| - ChromeURLRequestContext* context = new ChromeURLRequestContext(
|
| - profile, appcache_service);
|
| + return new ChromeURLRequestContextGetter(
|
| + profile,
|
| + new FactoryForOriginal(profile,
|
| + cookie_store_path,
|
| + disk_cache_path,
|
| + cache_size));
|
| +}
|
|
|
| - // The appcache service uses the profile's original context for UpdateJobs.
|
| - DCHECK(!appcache_service->request_context());
|
| - appcache_service->set_request_context(context);
|
| +ChromeURLRequestContext* FactoryForOriginal::Create() {
|
| + ChromeURLRequestContext* context = new ChromeURLRequestContext;
|
| + ApplyProfileParametersToContext(context);
|
|
|
| // Global host resolver for the context.
|
| - context->host_resolver_ = chrome_browser_net::GetGlobalHostResolver();
|
| + context->set_host_resolver(chrome_browser_net::GetGlobalHostResolver());
|
|
|
| const CommandLine& command_line = *CommandLine::ForCurrentProcess();
|
|
|
| - context->proxy_service_ = CreateProxyService(context, command_line);
|
| + context->set_proxy_service(
|
| + CreateProxyService(context,
|
| + proxy_config_service_.release(),
|
| + command_line,
|
| + MessageLoop::current() /*io_loop*/));
|
|
|
| net::HttpCache* cache =
|
| - new net::HttpCache(context->host_resolver_,
|
| - context->proxy_service_,
|
| - context->ssl_config_service_,
|
| - disk_cache_path, cache_size);
|
| + new net::HttpCache(context->host_resolver(),
|
| + context->proxy_service(),
|
| + context->ssl_config_service(),
|
| + disk_cache_path_, cache_size_);
|
|
|
| if (command_line.HasSwitch(switches::kDisableByteRangeSupport))
|
| cache->set_enable_range_support(false);
|
| @@ -142,97 +235,145 @@
|
|
|
| if (record_mode || playback_mode) {
|
| // Don't use existing cookies and use an in-memory store.
|
| - context->cookie_store_ = new net::CookieMonster();
|
| + context->set_cookie_store(new net::CookieMonster());
|
| cache->set_mode(
|
| record_mode ? net::HttpCache::RECORD : net::HttpCache::PLAYBACK);
|
| }
|
| - context->http_transaction_factory_ = cache;
|
| + context->set_http_transaction_factory(cache);
|
|
|
| // The kWininetFtp switch is Windows specific because we have two FTP
|
| // implementations on Windows.
|
| #if defined(OS_WIN)
|
| if (!command_line.HasSwitch(switches::kWininetFtp))
|
| - context->ftp_transaction_factory_ =
|
| - new net::FtpNetworkLayer(context->host_resolver_);
|
| + context->set_ftp_transaction_factory(
|
| + new net::FtpNetworkLayer(context->host_resolver()));
|
| #else
|
| - context->ftp_transaction_factory_ =
|
| - new net::FtpNetworkLayer(context->host_resolver_);
|
| + context->set_ftp_transaction_factory(
|
| + new net::FtpNetworkLayer(context->host_resolver()));
|
| #endif
|
|
|
| // setup cookie store
|
| - if (!context->cookie_store_) {
|
| - DCHECK(!cookie_store_path.empty());
|
| + if (!context->cookie_store()) {
|
| + DCHECK(!cookie_store_path_.empty());
|
|
|
| scoped_refptr<SQLitePersistentCookieStore> cookie_db =
|
| new SQLitePersistentCookieStore(
|
| - cookie_store_path,
|
| - g_browser_process->db_thread()->message_loop());
|
| - context->cookie_store_ = new net::CookieMonster(cookie_db.get());
|
| + cookie_store_path_,
|
| + db_loop_);
|
| + context->set_cookie_store(new net::CookieMonster(cookie_db.get()));
|
| }
|
|
|
| + // Create a new AppCacheService (issues fetches through the
|
| + // main URLRequestContext that we just created).
|
| + context->set_appcache_service(
|
| + new ChromeAppCacheService(profile_dir_path_, false));
|
| + context->appcache_service()->set_request_context(context);
|
| +
|
| +#if defined(OS_LINUX)
|
| + // TODO(ukai): find a better way to set the URLRequestContext for OCSP.
|
| + net::SetURLRequestContextForOCSP(context);
|
| +#endif
|
| +
|
| return context;
|
| }
|
|
|
| // static
|
| -ChromeURLRequestContext* ChromeURLRequestContext::CreateOriginalForMedia(
|
| - Profile* profile, const FilePath& disk_cache_path, int cache_size,
|
| - ChromeAppCacheService* appcache_service) {
|
| +ChromeURLRequestContextGetter*
|
| +ChromeURLRequestContextGetter::CreateOriginalForMedia(
|
| + Profile* profile, const FilePath& disk_cache_path, int cache_size) {
|
| DCHECK(!profile->IsOffTheRecord());
|
| return CreateRequestContextForMedia(profile, disk_cache_path, cache_size,
|
| - false, appcache_service);
|
| + false);
|
| }
|
|
|
| +// Factory that creates the ChromeURLRequestContext for extensions.
|
| +class FactoryForExtensions : public ChromeURLRequestContextFactory {
|
| + public:
|
| + FactoryForExtensions(Profile* profile, const FilePath& cookie_store_path)
|
| + : ChromeURLRequestContextFactory(profile),
|
| + cookie_store_path_(cookie_store_path) {
|
| + }
|
| +
|
| + virtual ChromeURLRequestContext* Create();
|
| +
|
| + private:
|
| + FilePath cookie_store_path_;
|
| +};
|
| +
|
| // static
|
| -ChromeURLRequestContext* ChromeURLRequestContext::CreateOriginalForExtensions(
|
| +ChromeURLRequestContextGetter*
|
| +ChromeURLRequestContextGetter::CreateOriginalForExtensions(
|
| Profile* profile, const FilePath& cookie_store_path) {
|
| DCHECK(!profile->IsOffTheRecord());
|
| - ChromeURLRequestContext* context = new ChromeURLRequestContext(
|
| - profile, NULL);
|
| + return new ChromeURLRequestContextGetter(
|
| + profile,
|
| + new FactoryForExtensions(profile, cookie_store_path));
|
| +}
|
|
|
| +ChromeURLRequestContext* FactoryForExtensions::Create() {
|
| + ChromeURLRequestContext* context = new ChromeURLRequestContext;
|
| + ApplyProfileParametersToContext(context);
|
| +
|
| // All we care about for extensions is the cookie store.
|
| - DCHECK(!cookie_store_path.empty());
|
| + DCHECK(!cookie_store_path_.empty());
|
|
|
| scoped_refptr<SQLitePersistentCookieStore> cookie_db =
|
| - new SQLitePersistentCookieStore(
|
| - cookie_store_path,
|
| - g_browser_process->db_thread()->message_loop());
|
| + new SQLitePersistentCookieStore(cookie_store_path_, db_loop_);
|
| net::CookieMonster* cookie_monster = new net::CookieMonster(cookie_db.get());
|
|
|
| // Enable cookies for extension URLs only.
|
| const char* schemes[] = {chrome::kExtensionScheme};
|
| cookie_monster->SetCookieableSchemes(schemes, 1);
|
| - context->cookie_store_ = cookie_monster;
|
| + context->set_cookie_store(cookie_monster);
|
|
|
| return context;
|
| }
|
|
|
| +// Factory that creates the ChromeURLRequestContext for incognito profile.
|
| +class FactoryForOffTheRecord : public ChromeURLRequestContextFactory {
|
| + public:
|
| + FactoryForOffTheRecord(Profile* profile)
|
| + : ChromeURLRequestContextFactory(profile),
|
| + original_context_getter_(
|
| + static_cast<ChromeURLRequestContextGetter*>(
|
| + profile->GetOriginalProfile()->GetRequestContext())) {
|
| + }
|
| +
|
| + virtual ChromeURLRequestContext* Create();
|
| +
|
| + private:
|
| + scoped_refptr<ChromeURLRequestContextGetter> original_context_getter_;
|
| +};
|
| +
|
| // static
|
| -ChromeURLRequestContext* ChromeURLRequestContext::CreateOffTheRecord(
|
| - Profile* profile, ChromeAppCacheService* appcache_service) {
|
| +ChromeURLRequestContextGetter* ChromeURLRequestContextGetter::CreateOffTheRecord(
|
| + Profile* profile) {
|
| DCHECK(profile->IsOffTheRecord());
|
| - ChromeURLRequestContext* context = new ChromeURLRequestContext(
|
| - profile, appcache_service);
|
| + return new ChromeURLRequestContextGetter(
|
| + profile, new FactoryForOffTheRecord(profile));
|
| +}
|
|
|
| - // The appcache service uses the profile's original context for UpdateJobs.
|
| - DCHECK(!appcache_service->request_context());
|
| - appcache_service->set_request_context(context);
|
| +ChromeURLRequestContext* FactoryForOffTheRecord::Create() {
|
| + ChromeURLRequestContext* context = new ChromeURLRequestContext;
|
| + ApplyProfileParametersToContext(context);
|
|
|
| + ChromeURLRequestContext* original_context =
|
| + original_context_getter_->GetIOContext();
|
| +
|
| // Share the same proxy service and host resolver as the original profile.
|
| // TODO(eroman): although ProxyService is reference counted, this sharing
|
| // still has a subtle dependency on the lifespan of the original profile --
|
| // ProxyService holds a (non referencing) pointer to the URLRequestContext
|
| // it uses to download PAC scripts, which in this case is the original
|
| // profile...
|
| - context->host_resolver_ =
|
| - profile->GetOriginalProfile()->GetRequestContext()->host_resolver();
|
| - context->proxy_service_ =
|
| - profile->GetOriginalProfile()->GetRequestContext()->proxy_service();
|
| + context->set_host_resolver(original_context->host_resolver());
|
| + context->set_proxy_service(original_context->proxy_service());
|
|
|
| net::HttpCache* cache =
|
| - new net::HttpCache(context->host_resolver_, context->proxy_service_,
|
| - context->ssl_config_service_, 0);
|
| - context->cookie_store_ = new net::CookieMonster;
|
| - context->http_transaction_factory_ = cache;
|
| + new net::HttpCache(context->host_resolver(), context->proxy_service(),
|
| + context->ssl_config_service(), 0);
|
| + context->set_cookie_store(new net::CookieMonster);
|
| + context->set_http_transaction_factory(cache);
|
|
|
| if (CommandLine::ForCurrentProcess()->HasSwitch(
|
| switches::kDisableByteRangeSupport))
|
| @@ -242,69 +383,129 @@
|
| // implementations on Windows.
|
| #if defined(OS_WIN)
|
| if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kWininetFtp))
|
| - context->ftp_transaction_factory_ =
|
| - new net::FtpNetworkLayer(context->host_resolver_);
|
| + context->set_ftp_transaction_factory(
|
| + new net::FtpNetworkLayer(context->host_resolver()));
|
| #else
|
| - context->ftp_transaction_factory_ =
|
| - new net::FtpNetworkLayer(context->host_resolver_);
|
| + context->set_ftp_transaction_factory(
|
| + new net::FtpNetworkLayer(context->host_resolver()));
|
| #endif
|
|
|
| + // Create a separate AppCacheService for OTR mode.
|
| + context->set_appcache_service(
|
| + new ChromeAppCacheService(profile_dir_path_, true));
|
| + context->appcache_service()->set_request_context(context);
|
| +
|
| return context;
|
| }
|
|
|
| +// Factory that creates the ChromeURLRequestContext for extensions in incognito
|
| +// mode.
|
| +class FactoryForOffTheRecordExtensions
|
| + : public ChromeURLRequestContextFactory {
|
| + public:
|
| + FactoryForOffTheRecordExtensions(Profile* profile)
|
| + : ChromeURLRequestContextFactory(profile) {}
|
| +
|
| + virtual ChromeURLRequestContext* Create();
|
| +};
|
| +
|
| // static
|
| -ChromeURLRequestContext*
|
| -ChromeURLRequestContext::CreateOffTheRecordForExtensions(Profile* profile) {
|
| +ChromeURLRequestContextGetter*
|
| +ChromeURLRequestContextGetter::CreateOffTheRecordForExtensions(Profile* profile) {
|
| DCHECK(profile->IsOffTheRecord());
|
| - ChromeURLRequestContext* context =
|
| - new ChromeURLRequestContext(profile, NULL);
|
| + return new ChromeURLRequestContextGetter(
|
| + profile,
|
| + new FactoryForOffTheRecordExtensions(profile));
|
| +}
|
| +
|
| +ChromeURLRequestContext* FactoryForOffTheRecordExtensions::Create() {
|
| + ChromeURLRequestContext* context = new ChromeURLRequestContext;
|
| + ApplyProfileParametersToContext(context);
|
| +
|
| net::CookieMonster* cookie_monster = new net::CookieMonster;
|
|
|
| // Enable cookies for extension URLs only.
|
| const char* schemes[] = {chrome::kExtensionScheme};
|
| cookie_monster->SetCookieableSchemes(schemes, 1);
|
| - context->cookie_store_ = cookie_monster;
|
| + context->set_cookie_store(cookie_monster);
|
|
|
| return context;
|
| }
|
|
|
| +// Factory that creates the ChromeURLRequestContext for media.
|
| +class FactoryForMedia : public ChromeURLRequestContextFactory {
|
| + public:
|
| + FactoryForMedia(Profile* profile,
|
| + const FilePath& disk_cache_path,
|
| + int cache_size,
|
| + bool off_the_record)
|
| + : ChromeURLRequestContextFactory(profile),
|
| + main_context_getter_(
|
| + static_cast<ChromeURLRequestContextGetter*>(
|
| + profile->GetRequestContext())) {
|
| + is_media_ = true;
|
| + is_off_the_record_ = off_the_record;
|
| + }
|
| +
|
| + virtual ChromeURLRequestContext* Create();
|
| +
|
| + private:
|
| + scoped_refptr<ChromeURLRequestContextGetter> main_context_getter_;
|
| +
|
| + FilePath disk_cache_path_;
|
| + int cache_size_;
|
| +};
|
| +
|
| // static
|
| -ChromeURLRequestContext* ChromeURLRequestContext::CreateRequestContextForMedia(
|
| +ChromeURLRequestContextGetter*
|
| +ChromeURLRequestContextGetter::CreateRequestContextForMedia(
|
| Profile* profile, const FilePath& disk_cache_path, int cache_size,
|
| - bool off_the_record, ChromeAppCacheService* appcache_service) {
|
| - URLRequestContext* original_context =
|
| - profile->GetOriginalProfile()->GetRequestContext();
|
| - ChromeURLRequestContext* context =
|
| - new ChromeURLRequestContext(profile, appcache_service);
|
| - context->is_media_ = true;
|
| + bool off_the_record) {
|
| + return new ChromeURLRequestContextGetter(
|
| + profile,
|
| + new FactoryForMedia(profile,
|
| + disk_cache_path,
|
| + cache_size,
|
| + off_the_record));
|
| +}
|
|
|
| +ChromeURLRequestContext* FactoryForMedia::Create() {
|
| + ChromeURLRequestContext* context = new ChromeURLRequestContext;
|
| + ApplyProfileParametersToContext(context);
|
| +
|
| + ChromeURLRequestContext* main_context =
|
| + main_context_getter_->GetIOContext();
|
| +
|
| // Share the same proxy service of the common profile.
|
| - context->proxy_service_ = original_context->proxy_service();
|
| + context->set_proxy_service(main_context->proxy_service());
|
| // Also share the cookie store of the common profile.
|
| - context->cookie_store_ = original_context->cookie_store();
|
| + context->set_cookie_store(main_context->cookie_store());
|
|
|
| // Create a media cache with default size.
|
| // TODO(hclam): make the maximum size of media cache configurable.
|
| - net::HttpCache* original_cache =
|
| - original_context->http_transaction_factory()->GetCache();
|
| + net::HttpCache* main_cache =
|
| + main_context->http_transaction_factory()->GetCache();
|
| net::HttpCache* cache;
|
| - if (original_cache) {
|
| - // Try to reuse HttpNetworkSession in the original context, assuming that
|
| + if (main_cache) {
|
| + // Try to reuse HttpNetworkSession in the main context, assuming that
|
| // HttpTransactionFactory (network_layer()) of HttpCache is implemented
|
| // by HttpNetworkLayer so we can reuse HttpNetworkSession within it. This
|
| // assumption will be invalid if the original HttpCache is constructed with
|
| // HttpCache(HttpTransactionFactory*, disk_cache::Backend*) constructor.
|
| - net::HttpNetworkLayer* original_network_layer =
|
| - static_cast<net::HttpNetworkLayer*>(original_cache->network_layer());
|
| - cache = new net::HttpCache(original_network_layer->GetSession(),
|
| - disk_cache_path, cache_size);
|
| + net::HttpNetworkLayer* main_network_layer =
|
| + static_cast<net::HttpNetworkLayer*>(main_cache->network_layer());
|
| + cache = new net::HttpCache(main_network_layer->GetSession(),
|
| + disk_cache_path_, cache_size_);
|
| + // TODO(eroman): Since this is poaching the session from the main
|
| + // context, it should hold a reference to that context preventing the
|
| + // session from getting deleted.
|
| } else {
|
| // If original HttpCache doesn't exist, simply construct one with a whole
|
| // new set of network stack.
|
| - cache = new net::HttpCache(original_context->host_resolver(),
|
| - original_context->proxy_service(),
|
| - original_context->ssl_config_service(),
|
| - disk_cache_path, cache_size);
|
| + cache = new net::HttpCache(main_context->host_resolver(),
|
| + main_context->proxy_service(),
|
| + main_context->ssl_config_service(),
|
| + disk_cache_path_, cache_size_);
|
| }
|
|
|
| if (CommandLine::ForCurrentProcess()->HasSwitch(
|
| @@ -312,21 +513,42 @@
|
| cache->set_enable_range_support(false);
|
|
|
| cache->set_type(net::MEDIA_CACHE);
|
| - context->http_transaction_factory_ = cache;
|
| + context->set_http_transaction_factory(cache);
|
| +
|
| + // Use the same appcache service as the profile's main context.
|
| + context->set_appcache_service(main_context->appcache_service());
|
| +
|
| return context;
|
| }
|
|
|
| -ChromeURLRequestContext::ChromeURLRequestContext(
|
| - Profile* profile, ChromeAppCacheService* appcache_service)
|
| - : appcache_service_(appcache_service),
|
| - prefs_(profile->GetPrefs()),
|
| - is_media_(false),
|
| +ChromeURLRequestContextGetter::ChromeURLRequestContextGetter(
|
| + Profile* profile,
|
| + ChromeURLRequestContextFactory* factory)
|
| + : prefs_(NULL),
|
| + factory_(factory),
|
| + url_request_context_(NULL) {
|
| + DCHECK(factory);
|
| +
|
| + // If a base profile was specified, listen for changes to the preferences.
|
| + if (profile)
|
| + RegisterPrefsObserver(profile);
|
| +}
|
| +
|
| +// 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_media_(false),
|
| is_off_the_record_(profile->IsOffTheRecord()) {
|
| + CheckCurrentlyOnMainThread();
|
| + PrefService* prefs = profile->GetPrefs();
|
| +
|
| // Set up Accept-Language and Accept-Charset header values
|
| accept_language_ = net::HttpUtil::GenerateAcceptLanguageHeader(
|
| - WideToASCII(prefs_->GetString(prefs::kAcceptLanguages)));
|
| + WideToASCII(prefs->GetString(prefs::kAcceptLanguages)));
|
| std::string default_charset =
|
| - WideToASCII(prefs_->GetString(prefs::kDefaultCharset));
|
| + WideToASCII(prefs->GetString(prefs::kDefaultCharset));
|
| accept_charset_ =
|
| net::HttpUtil::GenerateAcceptCharsetHeader(default_charset);
|
|
|
| @@ -344,11 +566,13 @@
|
| // net_util::GetSuggestedFilename is unlikely to be taken.
|
| referrer_charset_ = default_charset;
|
|
|
| - cookie_policy_.set_type(net::CookiePolicy::FromInt(
|
| - prefs_->GetInteger(prefs::kCookieBehavior)));
|
| + cookie_policy_type_ = net::CookiePolicy::FromInt(
|
| + prefs->GetInteger(prefs::kCookieBehavior));
|
|
|
| + // TODO(eroman): this doesn't look safe; sharing between IO and UI threads!
|
| blacklist_ = profile->GetBlacklist();
|
|
|
| + // TODO(eroman): this doesn't look safe; sharing between IO and UI threads!
|
| strict_transport_security_state_ = profile->GetStrictTransportSecurityState();
|
|
|
| if (profile->GetExtensionsService()) {
|
| @@ -363,15 +587,51 @@
|
| if (profile->GetUserScriptMaster())
|
| user_script_dir_path_ = profile->GetUserScriptMaster()->user_script_dir();
|
|
|
| + // TODO(eroman): this doesn't look safe; sharing between IO and UI threads!
|
| + ssl_config_service_ = profile->GetSSLConfigService();
|
| +
|
| + profile_dir_path_ = profile->GetPath();
|
| +
|
| + // Get references to the database and file threads.
|
| + db_loop_ = g_browser_process->db_thread()->message_loop();
|
| +}
|
| +
|
| +ChromeURLRequestContextFactory::~ChromeURLRequestContextFactory() {
|
| + CheckCurrentlyOnIOThread();
|
| +}
|
| +
|
| +void ChromeURLRequestContextFactory::ApplyProfileParametersToContext(
|
| + ChromeURLRequestContext* context) {
|
| + // Apply all the parameters. NOTE: keep this in sync with
|
| + // ChromeURLRequestContextFactory(Profile*).
|
| + context->set_is_media(is_media_);
|
| + 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_cookie_policy_type(cookie_policy_type_);
|
| + context->set_extension_paths(extension_paths_);
|
| + context->set_user_script_dir_path(user_script_dir_path_);
|
| + context->set_blacklist(blacklist_);
|
| + context->set_strict_transport_security_state(
|
| + strict_transport_security_state_);
|
| + context->set_ssl_config_service(ssl_config_service_);
|
| +}
|
| +
|
| +void ChromeURLRequestContextGetter::RegisterPrefsObserver(Profile* profile) {
|
| + CheckCurrentlyOnMainThread();
|
| +
|
| + prefs_ = profile->GetPrefs();
|
| +
|
| prefs_->AddPrefObserver(prefs::kAcceptLanguages, this);
|
| prefs_->AddPrefObserver(prefs::kCookieBehavior, this);
|
| prefs_->AddPrefObserver(prefs::kDefaultCharset, this);
|
| -
|
| - ssl_config_service_ = profile->GetSSLConfigService();
|
| }
|
|
|
| ChromeURLRequestContext::ChromeURLRequestContext(
|
| ChromeURLRequestContext* other) {
|
| + CheckCurrentlyOnIOThread();
|
| +
|
| // Set URLRequestContext members
|
| host_resolver_ = other->host_resolver_;
|
| proxy_service_ = other->proxy_service_;
|
| @@ -389,16 +649,17 @@
|
| appcache_service_ = other->appcache_service_;
|
| extension_paths_ = other->extension_paths_;
|
| user_script_dir_path_ = other->user_script_dir_path_;
|
| - prefs_ = other->prefs_;
|
| blacklist_ = other->blacklist_;
|
| is_media_ = other->is_media_;
|
| is_off_the_record_ = other->is_off_the_record_;
|
| }
|
|
|
| // NotificationObserver implementation.
|
| -void ChromeURLRequestContext::Observe(NotificationType type,
|
| - const NotificationSource& source,
|
| - const NotificationDetails& details) {
|
| +void ChromeURLRequestContextGetter::Observe(NotificationType type,
|
| + const NotificationSource& source,
|
| + const NotificationDetails& details) {
|
| + CheckCurrentlyOnMainThread();
|
| +
|
| if (NotificationType::PREF_CHANGED == type) {
|
| std::wstring* pref_name_in = Details<std::wstring>(details).ptr();
|
| PrefService* prefs = Source<PrefService>(source).ptr();
|
| @@ -407,39 +668,91 @@
|
| std::string accept_language =
|
| WideToASCII(prefs->GetString(prefs::kAcceptLanguages));
|
| g_browser_process->io_thread()->message_loop()->PostTask(FROM_HERE,
|
| - NewRunnableMethod(this,
|
| - &ChromeURLRequestContext::OnAcceptLanguageChange,
|
| - accept_language));
|
| + NewRunnableMethod(
|
| + this,
|
| + &ChromeURLRequestContextGetter::OnAcceptLanguageChange,
|
| + accept_language));
|
| } else if (*pref_name_in == prefs::kCookieBehavior) {
|
| net::CookiePolicy::Type policy_type = net::CookiePolicy::FromInt(
|
| prefs_->GetInteger(prefs::kCookieBehavior));
|
| g_browser_process->io_thread()->message_loop()->PostTask(FROM_HERE,
|
| - NewRunnableMethod(this,
|
| - &ChromeURLRequestContext::OnCookiePolicyChange,
|
| - policy_type));
|
| + NewRunnableMethod(
|
| + this,
|
| + &ChromeURLRequestContextGetter::OnCookiePolicyChange,
|
| + policy_type));
|
| } else if (*pref_name_in == prefs::kDefaultCharset) {
|
| std::string default_charset =
|
| WideToASCII(prefs->GetString(prefs::kDefaultCharset));
|
| g_browser_process->io_thread()->message_loop()->PostTask(FROM_HERE,
|
| - NewRunnableMethod(this,
|
| - &ChromeURLRequestContext::OnDefaultCharsetChange,
|
| - default_charset));
|
| + NewRunnableMethod(
|
| + this,
|
| + &ChromeURLRequestContextGetter::OnDefaultCharsetChange,
|
| + default_charset));
|
| }
|
| } else {
|
| NOTREACHED();
|
| }
|
| }
|
|
|
| -void ChromeURLRequestContext::CleanupOnUIThread() {
|
| - // Unregister for pref notifications.
|
| - prefs_->RemovePrefObserver(prefs::kAcceptLanguages, this);
|
| - prefs_->RemovePrefObserver(prefs::kCookieBehavior, this);
|
| - prefs_->RemovePrefObserver(prefs::kDefaultCharset, this);
|
| - prefs_ = NULL;
|
| +void ChromeURLRequestContextGetter::OnAcceptLanguageChange(
|
| + const std::string& accept_language) {
|
| + GetIOContext()->OnAcceptLanguageChange(accept_language);
|
| +}
|
|
|
| +void ChromeURLRequestContextGetter::OnCookiePolicyChange(
|
| + net::CookiePolicy::Type type) {
|
| + GetIOContext()->OnCookiePolicyChange(type);
|
| +}
|
| +
|
| +void ChromeURLRequestContextGetter::OnDefaultCharsetChange(
|
| + const std::string& default_charset) {
|
| + GetIOContext()->OnDefaultCharsetChange(default_charset);
|
| +}
|
| +
|
| +void ChromeURLRequestContextGetter::OnNewExtensions(const std::string& id,
|
| + const FilePath& path) {
|
| + GetIOContext()->OnNewExtensions(id, path);
|
| +}
|
| +
|
| +void ChromeURLRequestContextGetter::OnUnloadedExtension(
|
| + const std::string& id) {
|
| + GetIOContext()->OnUnloadedExtension(id);
|
| +}
|
| +
|
| +void ChromeURLRequestContextGetter::CleanupOnUIThread() {
|
| + CheckCurrentlyOnMainThread();
|
| +
|
| + if (prefs_) {
|
| + // Unregister for pref notifications.
|
| + prefs_->RemovePrefObserver(prefs::kAcceptLanguages, this);
|
| + prefs_->RemovePrefObserver(prefs::kCookieBehavior, this);
|
| + prefs_->RemovePrefObserver(prefs::kDefaultCharset, this);
|
| + prefs_ = NULL;
|
| + }
|
| +
|
| + // TODO(eroman): Doesn't look like this member is even used...
|
| + // can probably be deleted.
|
| registrar_.RemoveAll();
|
| }
|
|
|
| +ChromeURLRequestContextGetter::~ChromeURLRequestContextGetter() {
|
| + CheckCurrentlyOnIOThread();
|
| +
|
| + DCHECK(!prefs_) << "Probably didn't call CleanupOnUIThread";
|
| +
|
| + // Either we already transformed the factory into a URLRequestContext, or
|
| + // we still have a pending factory.
|
| + DCHECK((factory_.get() && !url_request_context_.get()) ||
|
| + (!factory_.get() && url_request_context_.get()));
|
| +
|
| + // The scoped_refptr / scoped_ptr destructors take care of releasing
|
| + // |factory_| and |url_request_context_| now.
|
| +}
|
| +
|
| +ChromeURLRequestContext::ChromeURLRequestContext() {
|
| + CheckCurrentlyOnIOThread();
|
| +}
|
| +
|
| FilePath ChromeURLRequestContext::GetPathForExtension(const std::string& id) {
|
| ExtensionPaths::iterator iter = extension_paths_.find(id);
|
| if (iter != extension_paths_.end()) {
|
| @@ -496,23 +809,20 @@
|
|
|
| void ChromeURLRequestContext::OnAcceptLanguageChange(
|
| const std::string& accept_language) {
|
| - DCHECK(MessageLoop::current() ==
|
| - ChromeThread::GetMessageLoop(ChromeThread::IO));
|
| + CheckCurrentlyOnIOThread();
|
| accept_language_ =
|
| net::HttpUtil::GenerateAcceptLanguageHeader(accept_language);
|
| }
|
|
|
| void ChromeURLRequestContext::OnCookiePolicyChange(
|
| net::CookiePolicy::Type type) {
|
| - DCHECK(MessageLoop::current() ==
|
| - ChromeThread::GetMessageLoop(ChromeThread::IO));
|
| + CheckCurrentlyOnIOThread();
|
| cookie_policy_.set_type(type);
|
| }
|
|
|
| void ChromeURLRequestContext::OnDefaultCharsetChange(
|
| const std::string& default_charset) {
|
| - DCHECK(MessageLoop::current() ==
|
| - ChromeThread::GetMessageLoop(ChromeThread::IO));
|
| + CheckCurrentlyOnIOThread();
|
| referrer_charset_ = default_charset;
|
| accept_charset_ =
|
| net::HttpUtil::GenerateAcceptCharsetHeader(default_charset);
|
| @@ -525,6 +835,7 @@
|
| }
|
|
|
| void ChromeURLRequestContext::OnUnloadedExtension(const std::string& id) {
|
| + CheckCurrentlyOnIOThread();
|
| if (is_off_the_record_)
|
| return;
|
| ExtensionPaths::iterator iter = extension_paths_.find(id);
|
| @@ -533,8 +844,7 @@
|
| }
|
|
|
| ChromeURLRequestContext::~ChromeURLRequestContext() {
|
| - DCHECK(NULL == prefs_);
|
| -
|
| + CheckCurrentlyOnIOThread();
|
| if (appcache_service_.get() && appcache_service_->request_context() == this)
|
| appcache_service_->set_request_context(NULL);
|
|
|
| @@ -546,3 +856,35 @@
|
| delete ftp_transaction_factory_;
|
| delete http_transaction_factory_;
|
| }
|
| +
|
| +net::CookieStore* ChromeURLRequestContextGetter::GetCookieStore() {
|
| + // If we are running on the IO thread this is real easy.
|
| + if (ChromeThread::CurrentlyOn(ChromeThread::IO))
|
| + return GetURLRequestContext()->cookie_store();
|
| +
|
| + // If we aren't running on the IO thread, we cannot call
|
| + // GetURLRequestContext(). Instead we will post a task to the IO loop
|
| + // and wait for it to complete.
|
| +
|
| + base::WaitableEvent completion(false, false);
|
| + net::CookieStore* result = NULL;
|
| +
|
| + g_browser_process->io_thread()->message_loop()->PostTask(
|
| + FROM_HERE,
|
| + NewRunnableMethod(this,
|
| + &ChromeURLRequestContextGetter::GetCookieStoreAsyncHelper,
|
| + &completion,
|
| + &result));
|
| +
|
| + completion.Wait();
|
| + DCHECK(result);
|
| + return result;
|
| +}
|
| +
|
| +void ChromeURLRequestContextGetter::GetCookieStoreAsyncHelper(
|
| + base::WaitableEvent* completion,
|
| + net::CookieStore** result) {
|
| + // Note that CookieStore is refcounted, yet we do not add a reference.
|
| + *result = GetURLRequestContext()->cookie_store();
|
| + completion->Signal();
|
| +}
|
|
|