summaryrefslogtreecommitdiffstats
path: root/chrome/browser/net
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/net')
-rw-r--r--chrome/browser/net/chrome_url_request_context.cc617
-rw-r--r--chrome/browser/net/chrome_url_request_context.h117
-rw-r--r--chrome/browser/net/connection_tester.cc50
3 files changed, 682 insertions, 102 deletions
diff --git a/chrome/browser/net/chrome_url_request_context.cc b/chrome/browser/net/chrome_url_request_context.cc
index eead9cd..573ffdc 100644
--- a/chrome/browser/net/chrome_url_request_context.cc
+++ b/chrome/browser/net/chrome_url_request_context.cc
@@ -4,21 +4,40 @@
#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_policy.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/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 "net/base/cookie_store.h"
-#include "net/ftp/ftp_transaction_factory.h"
-#include "net/http/http_transaction_factory.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/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)
@@ -31,67 +50,457 @@
#include "chrome/browser/chromeos/proxy_config_service.h"
#endif // defined(OS_CHROMEOS)
-class ChromeURLRequestContextFactory {
+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 {
public:
- ChromeURLRequestContextFactory() {}
- virtual ~ChromeURLRequestContextFactory() {}
+ explicit ChromeCookieMonsterDelegate(Profile* profile) {
+ CheckCurrentlyOnMainThread();
+ profile_getter_ = new ProfileGetter(profile);
+ }
- // Called to create a new instance (will only be called once).
- virtual scoped_refptr<ChromeURLRequestContext> Create() = 0;
+ // 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));
+ }
- protected:
- DISALLOW_COPY_AND_ASSIGN(ChromeURLRequestContextFactory);
-};
+ 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_));
+ }
-namespace {
+ // 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>;
+
+ 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));
+ }
+ }
+
+ scoped_refptr<ProfileGetter> profile_getter_;
+};
// ----------------------------------------------------------------------------
// Helper factories
// ----------------------------------------------------------------------------
// Factory that creates the main ChromeURLRequestContext.
-class FactoryForMain : public ChromeURLRequestContextFactory {
+class FactoryForOriginal : public ChromeURLRequestContextFactory {
public:
- explicit FactoryForMain(const ProfileIOData* profile_io_data)
- : profile_io_data_(profile_io_data) {}
-
- virtual scoped_refptr<ChromeURLRequestContext> Create() {
- return profile_io_data_->GetMainRequestContext();
+ 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)) {
}
+ virtual scoped_refptr<ChromeURLRequestContext> Create();
+
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:
- explicit FactoryForExtensions(const ProfileIOData* profile_io_data)
- : profile_io_data_(profile_io_data) {}
-
- virtual scoped_refptr<ChromeURLRequestContext> Create() {
- return profile_io_data_->GetExtensionsRequestContext();
+ 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_;
};
+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);
+ }
+
+ 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_;
+};
+
+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:
- explicit FactoryForMedia(const ProfileIOData* profile_io_data)
- : profile_io_data_(profile_io_data) {
+ FactoryForMedia(Profile* profile,
+ const ProfileIOData* profile_io_data)
+ : ChromeURLRequestContextFactory(profile),
+ main_context_getter_(
+ static_cast<ChromeURLRequestContextGetter*>(
+ profile->GetRequestContext())),
+ profile_io_data_(profile_io_data) {
}
- virtual scoped_refptr<ChromeURLRequestContext> Create() {
- return profile_io_data_->GetMediaRequestContext();
- }
+ virtual scoped_refptr<ChromeURLRequestContext> Create();
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
// ----------------------------------------------------------------------------
@@ -105,12 +514,14 @@ ChromeURLRequestContextGetter::ChromeURLRequestContextGetter(
factory_(factory),
url_request_context_(NULL) {
DCHECK(factory);
- DCHECK(profile);
- RegisterPrefsObserver(profile);
+
+ // If a base profile was specified, listen for changes to the preferences.
+ if (profile)
+ RegisterPrefsObserver(profile);
}
ChromeURLRequestContextGetter::~ChromeURLRequestContextGetter() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ CheckCurrentlyOnIOThread();
DCHECK(registrar_.IsEmpty()) << "Probably didn't call CleanupOnUIThread";
@@ -128,7 +539,7 @@ ChromeURLRequestContextGetter::~ChromeURLRequestContextGetter() {
// Lazily create a ChromeURLRequestContext using our factory.
net::URLRequestContext* ChromeURLRequestContextGetter::GetURLRequestContext() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ CheckCurrentlyOnIOThread();
if (!url_request_context_) {
DCHECK(factory_.get());
@@ -190,7 +601,7 @@ ChromeURLRequestContextGetter* ChromeURLRequestContextGetter::CreateOriginal(
DCHECK(!profile->IsOffTheRecord());
return new ChromeURLRequestContextGetter(
profile,
- new FactoryForMain(profile_io_data));
+ new FactoryForOriginal(profile, profile_io_data));
}
// static
@@ -200,7 +611,7 @@ ChromeURLRequestContextGetter::CreateOriginalForMedia(
DCHECK(!profile->IsOffTheRecord());
return new ChromeURLRequestContextGetter(
profile,
- new FactoryForMedia(profile_io_data));
+ new FactoryForMedia(profile, profile_io_data));
}
// static
@@ -210,31 +621,29 @@ ChromeURLRequestContextGetter::CreateOriginalForExtensions(
DCHECK(!profile->IsOffTheRecord());
return new ChromeURLRequestContextGetter(
profile,
- new FactoryForExtensions(profile_io_data));
+ new FactoryForExtensions(profile, profile_io_data, false));
}
// static
ChromeURLRequestContextGetter*
-ChromeURLRequestContextGetter::CreateOffTheRecord(
- Profile* profile, const ProfileIOData* profile_io_data) {
+ChromeURLRequestContextGetter::CreateOffTheRecord(Profile* profile) {
DCHECK(profile->IsOffTheRecord());
return new ChromeURLRequestContextGetter(
- profile, new FactoryForMain(profile_io_data));
+ profile, new FactoryForOffTheRecord(profile));
}
// static
ChromeURLRequestContextGetter*
ChromeURLRequestContextGetter::CreateOffTheRecordForExtensions(
- Profile* profile, const ProfileIOData* profile_io_data) {
+ Profile* profile) {
DCHECK(profile->IsOffTheRecord());
return new ChromeURLRequestContextGetter(
- profile, new FactoryForExtensions(profile_io_data));
+ profile, new FactoryForExtensions(profile, NULL, true));
}
void ChromeURLRequestContextGetter::CleanupOnUIThread() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ CheckCurrentlyOnMainThread();
// Unregister for pref notifications.
- DCHECK(!registrar_.IsEmpty()) << "Called more than once!";
registrar_.RemoveAll();
}
@@ -243,7 +652,7 @@ void ChromeURLRequestContextGetter::Observe(
NotificationType type,
const NotificationSource& source,
const NotificationDetails& details) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ CheckCurrentlyOnMainThread();
if (NotificationType::PREF_CHANGED == type) {
std::string* pref_name_in = Details<std::string>(details).ptr();
@@ -283,7 +692,7 @@ void ChromeURLRequestContextGetter::Observe(
}
void ChromeURLRequestContextGetter::RegisterPrefsObserver(Profile* profile) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ CheckCurrentlyOnMainThread();
registrar_.Init(profile->GetPrefs());
registrar_.Add(prefs::kAcceptLanguages, this);
@@ -321,13 +730,7 @@ void ChromeURLRequestContextGetter::GetCookieStoreAsyncHelper(
ChromeURLRequestContext::ChromeURLRequestContext()
: is_off_the_record_(false) {
- 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);
+ CheckCurrentlyOnIOThread();
}
ChromeURLDataManagerBackend*
@@ -338,11 +741,18 @@ ChromeURLDataManagerBackend*
}
ChromeURLRequestContext::~ChromeURLRequestContext() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ CheckCurrentlyOnIOThread();
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();
@@ -359,10 +769,13 @@ 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.
- set_cookie_policy(NULL);
+ cookie_policy_ = NULL;
}
const std::string& ChromeURLRequestContext::GetUserAgent(
@@ -372,15 +785,97 @@ const std::string& ChromeURLRequestContext::GetUserAgent(
void ChromeURLRequestContext::OnAcceptLanguageChange(
const std::string& accept_language) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- set_accept_language(
- net::HttpUtil::GenerateAcceptLanguageHeader(accept_language));
+ CheckCurrentlyOnIOThread();
+ accept_language_ =
+ net::HttpUtil::GenerateAcceptLanguageHeader(accept_language);
}
void ChromeURLRequestContext::OnDefaultCharsetChange(
const std::string& default_charset) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- set_referrer_charset(default_charset);
- set_accept_charset(
- net::HttpUtil::GenerateAcceptCharsetHeader(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_);
}
diff --git a/chrome/browser/net/chrome_url_request_context.h b/chrome/browser/net/chrome_url_request_context.h
index f64eb74..494bf50 100644
--- a/chrome/browser/net/chrome_url_request_context.h
+++ b/chrome/browser/net/chrome_url_request_context.h
@@ -17,27 +17,32 @@
#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 ChromeCookiePolicy;
-class ChromeURLDataManagerBackend;
-class ChromeURLRequestContextFactory;
-class IOThread;
+class CommandLine;
+class PrefService;
+class Profile;
+class ProfileIOData;
+
namespace net {
class DnsCertProvenanceChecker;
class NetworkDelegate;
}
-class PrefService;
-class Profile;
-class ProfileIOData;
+
+class ChromeURLDataManagerBackend;
+class ChromeURLRequestContext;
+class ChromeURLRequestContextFactory;
// Subclass of net::URLRequestContext which can be used to store extra
// information for requests.
@@ -100,9 +105,38 @@ 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;
}
@@ -145,9 +179,6 @@ 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_;
@@ -167,6 +198,7 @@ class ChromeURLRequestContext : public net::URLRequestContext {
bool is_off_the_record_;
+ private:
DISALLOW_COPY_AND_ASSIGN(ChromeURLRequestContext);
};
@@ -224,13 +256,12 @@ 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, const ProfileIOData* profile_io_data);
+ static ChromeURLRequestContextGetter* CreateOffTheRecord(Profile* profile);
// Create an instance for an OTR profile for extensions. This is expected
// to get called on UI thread.
static ChromeURLRequestContextGetter* CreateOffTheRecordForExtensions(
- Profile* profile, const ProfileIOData* profile_io_data);
+ Profile* profile);
// Clean up UI thread resources. This is expected to get called on the UI
// thread before the instance is deleted on the IO thread.
@@ -277,4 +308,62 @@ 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<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 a83c885..d0a7c95 100644
--- a/chrome/browser/net/connection_tester.cc
+++ b/chrome/browser/net/connection_tester.cc
@@ -49,56 +49,52 @@ 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_tmp);
+ &host_resolver_);
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_tmp);
+ &proxy_service_);
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.
- 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));
+ 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_);
net::HttpNetworkSession::Params session_params;
- 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();
+ 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_;
scoped_refptr<net::HttpNetworkSession> network_session(
new net::HttpNetworkSession(session_params));
- set_http_transaction_factory(new net::HttpCache(
+ http_transaction_factory_ = new net::HttpCache(
network_session,
- net::HttpCache::DefaultBackend::InMemory(0)));
+ net::HttpCache::DefaultBackend::InMemory(0));
// In-memory cookie store.
- set_cookie_store(new net::CookieMonster(NULL, NULL));
+ 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: