summaryrefslogtreecommitdiffstats
path: root/chrome/browser/net
diff options
context:
space:
mode:
authorwillchan@chromium.org <willchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-02-14 20:35:15 +0000
committerwillchan@chromium.org <willchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-02-14 20:35:15 +0000
commit182fe2f459b174b9c1de6520776ceb23f7d0f0de (patch)
tree8d8592387f02940866515447134ed83674b7834e /chrome/browser/net
parent6c2f7320e7767f71385134b184c2e0652600b5c0 (diff)
downloadchromium_src-182fe2f459b174b9c1de6520776ceb23f7d0f0de.zip
chromium_src-182fe2f459b174b9c1de6520776ceb23f7d0f0de.tar.gz
chromium_src-182fe2f459b174b9c1de6520776ceb23f7d0f0de.tar.bz2
Revert 74842 - It seems to have broken the ChromeOS "PFQ bot"?
r74561 added a DCHECK to make sure users didn't try to access the ChromeURLRequestContextGetter from the Profile, since the Profile should only be read on the UI thread. ChromeOS apparently tried to access it from another thread, and therefore hit the new DCHECK. I'm relanding without the DCHECK. I'm also eagerly initializing the off the record context getter to prevent the ChromeOS race. ChromeOS should fix that code so the eager initialization isn't necessary. BUG=none TEST=none Review URL: http://codereview.chromium.org/6484041 TBR=willchan@chromium.org Review URL: http://codereview.chromium.org/6517021 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@74848 0039d316-1c4b-4281-b951-d872f2087c98
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: