diff options
author | pauljensen@chromium.org <pauljensen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-11-07 15:08:43 +0000 |
---|---|---|
committer | pauljensen@chromium.org <pauljensen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-11-07 15:08:43 +0000 |
commit | ee4c30d8c5fca53a990da472de17314de366341b (patch) | |
tree | bc52b41397e143b46d0673991a13052edb1c9c66 | |
parent | 91d4f2541624923604d54fdf280483a08a393464 (diff) | |
download | chromium_src-ee4c30d8c5fca53a990da472de17314de366341b.zip chromium_src-ee4c30d8c5fca53a990da472de17314de366341b.tar.gz chromium_src-ee4c30d8c5fca53a990da472de17314de366341b.tar.bz2 |
Provide mutable members of UrlRequestContext via pure-virtual interface. Create a pure-virtual interface called HttpUserAgentSettings that provides access to the Accept-Language, Accept-Charset, and User-Agent HTTP headers. Each UrlRequestContext should have a HttpUserAgentSettings implementation attached via set_http_user_agent_settings().
BUG=146596
Review URL: https://chromiumcodereview.appspot.com/10918279
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@166425 0039d316-1c4b-4281-b951-d872f2087c98
43 files changed, 581 insertions, 351 deletions
diff --git a/android_webview/browser/net/aw_url_request_context_getter.cc b/android_webview/browser/net/aw_url_request_context_getter.cc index 8fbe53c..9b51826 100644 --- a/android_webview/browser/net/aw_url_request_context_getter.cc +++ b/android_webview/browser/net/aw_url_request_context_getter.cc @@ -84,6 +84,13 @@ void AwURLRequestContextGetter::Init() { builder.set_network_delegate(new AwNetworkDelegate()); builder.set_ftp_enabled(false); // Android WebView does not support ftp yet. builder.set_proxy_config_service(proxy_config_service_.release()); + builder.set_accept_language(net::HttpUtil::GenerateAcceptLanguageHeader( + content::GetContentClient()->browser()->GetAcceptLangs( + browser_context_))); + + // TODO(boliu): Values from chrome/app/resources/locale_settings_en-GB.xtb + builder.set_accept_charset( + net::HttpUtil::GenerateAcceptCharsetHeader("ISO-8859-1")); net::URLRequestContextBuilder::HttpCacheParams cache_params; cache_params.type = net::URLRequestContextBuilder::HttpCacheParams::DISK; @@ -94,15 +101,6 @@ void AwURLRequestContextGetter::Init() { url_request_context_.reset(builder.Build()); - url_request_context_->set_accept_language( - net::HttpUtil::GenerateAcceptLanguageHeader( - content::GetContentClient()->browser()->GetAcceptLangs( - browser_context_))); - - // TODO(boliu): Values from chrome/app/resources/locale_settings_en-GB.xtb - url_request_context_->set_accept_charset( - net::HttpUtil::GenerateAcceptCharsetHeader("ISO-8859-1")); - job_factory_.reset(new AwURLRequestJobFactory); bool set_protocol = job_factory_->SetProtocolHandler( chrome::kFileScheme, new net::FileProtocolHandler()); diff --git a/chrome/browser/automation/url_request_automation_job.cc b/chrome/browser/automation/url_request_automation_job.cc index a5c790d..44b7b51 100644 --- a/chrome/browser/automation/url_request_automation_job.cc +++ b/chrome/browser/automation/url_request_automation_job.cc @@ -20,6 +20,7 @@ #include "net/http/http_request_headers.h" #include "net/http/http_response_headers.h" #include "net/http/http_util.h" +#include "net/url_request/http_user_agent_settings.h" #include "net/url_request/url_request.h" #include "net/url_request/url_request_context.h" @@ -53,11 +54,13 @@ net::URLRequest::ProtocolFactory* URLRequestAutomationJob::old_https_factory_ URLRequestAutomationJob::URLRequestAutomationJob( net::URLRequest* request, net::NetworkDelegate* network_delegate, + const net::HttpUserAgentSettings* http_user_agent_settings, int tab, int request_id, AutomationResourceMessageFilter* filter, bool is_pending) : net::URLRequestJob(request, network_delegate), + http_user_agent_settings_(http_user_agent_settings), id_(0), tab_(tab), message_filter_(filter), @@ -113,6 +116,7 @@ net::URLRequestJob* URLRequestAutomationJob::Factory( child_id, route_id, &details)) { URLRequestAutomationJob* job = new URLRequestAutomationJob( request, network_delegate, + request->context()->http_user_agent_settings(), details.tab_handle, info->GetRequestID(), details.filter, details.is_pending_render_view); return job; @@ -423,15 +427,22 @@ void URLRequestAutomationJob::StartAsync() { // didn't have them specified. if (!new_request_headers.HasHeader( net::HttpRequestHeaders::kAcceptLanguage) && - !request_->context()->accept_language().empty()) { - new_request_headers.SetHeader(net::HttpRequestHeaders::kAcceptLanguage, - request_->context()->accept_language()); + http_user_agent_settings_) { + std::string accept_language = + http_user_agent_settings_->GetAcceptLanguage(); + if (!accept_language.empty()) { + new_request_headers.SetHeader(net::HttpRequestHeaders::kAcceptLanguage, + accept_language); + } } if (!new_request_headers.HasHeader( net::HttpRequestHeaders::kAcceptCharset) && - !request_->context()->accept_charset().empty()) { - new_request_headers.SetHeader(net::HttpRequestHeaders::kAcceptCharset, - request_->context()->accept_charset()); + http_user_agent_settings_) { + std::string accept_charset = http_user_agent_settings_->GetAcceptCharset(); + if (!accept_charset.empty()) { + new_request_headers.SetHeader(net::HttpRequestHeaders::kAcceptCharset, + accept_charset); + } } // Ensure that we do not send username and password fields in the referrer. diff --git a/chrome/browser/automation/url_request_automation_job.h b/chrome/browser/automation/url_request_automation_job.h index 9c12f59..ee806b0 100644 --- a/chrome/browser/automation/url_request_automation_job.h +++ b/chrome/browser/automation/url_request_automation_job.h @@ -17,6 +17,7 @@ struct AutomationURLResponse; namespace net { class HttpResponseHeaders; class HttpResponseInfo; +class HttpUserAgentSettings; class HostPortPair; } @@ -28,12 +29,14 @@ class Message; // automation. class URLRequestAutomationJob : public net::URLRequestJob { public: - URLRequestAutomationJob(net::URLRequest* request, - net::NetworkDelegate* network_delegate, - int tab, - int request_id, - AutomationResourceMessageFilter* filter, - bool is_pending); + URLRequestAutomationJob( + net::URLRequest* request, + net::NetworkDelegate* network_delegate, + const net::HttpUserAgentSettings* http_user_agent_settings, + int tab, + int request_id, + AutomationResourceMessageFilter* filter, + bool is_pending); // Register our factory for HTTP/HTTPs requests. static void EnsureProtocolFactoryRegistered(); @@ -97,6 +100,7 @@ class URLRequestAutomationJob : public net::URLRequestJob { // function, which completes the job. void NotifyJobCompletionTask(); + const net::HttpUserAgentSettings* http_user_agent_settings_; int id_; int tab_; scoped_refptr<AutomationResourceMessageFilter> message_filter_; diff --git a/chrome/browser/io_thread.cc b/chrome/browser/io_thread.cc index 2a774fc..df0d73e 100644 --- a/chrome/browser/io_thread.cc +++ b/chrome/browser/io_thread.cc @@ -22,6 +22,7 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/extensions/event_router_forwarder.h" #include "chrome/browser/net/async_dns_field_trial.h" +#include "chrome/browser/net/basic_http_user_agent_settings.h" #include "chrome/browser/net/chrome_net_log.h" #include "chrome/browser/net/chrome_network_delegate.h" #include "chrome/browser/net/chrome_url_request_context.h" @@ -36,7 +37,6 @@ #include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" #include "content/public/browser/browser_thread.h" -#include "content/public/common/content_client.h" #include "net/base/cert_verifier.h" #include "net/base/default_server_bound_cert_store.h" #include "net/base/host_cache.h" @@ -83,24 +83,8 @@ void ObserveKeychainEvents() { } #endif -// Custom URLRequestContext used by requests which aren't associated with a -// particular profile. We need to use a subclass of URLRequestContext in order -// to provide the correct User-Agent. -class URLRequestContextWithUserAgent : public net::URLRequestContext { - public: - virtual const std::string& GetUserAgent( - const GURL& url) const OVERRIDE { - return content::GetUserAgent(url); - } - - protected: - virtual ~URLRequestContextWithUserAgent() {} -}; - -// Used for the "system" URLRequestContext. If this grows more complicated, then -// consider inheriting directly from URLRequestContext rather than using -// implementation inheritance. -class SystemURLRequestContext : public URLRequestContextWithUserAgent { +// Used for the "system" URLRequestContext. +class SystemURLRequestContext : public net::URLRequestContext { public: SystemURLRequestContext() { #if defined(USE_NSS) @@ -194,7 +178,7 @@ scoped_ptr<net::HostResolver> CreateGlobalHostResolver(net::NetLog* net_log) { net::URLRequestContext* ConstructProxyScriptFetcherContext(IOThread::Globals* globals, net::NetLog* net_log) { - net::URLRequestContext* context = new URLRequestContextWithUserAgent; + net::URLRequestContext* context = new net::URLRequestContext; context->set_net_log(net_log); context->set_host_resolver(globals->host_resolver.get()); context->set_cert_verifier(globals->cert_verifier.get()); @@ -211,6 +195,8 @@ ConstructProxyScriptFetcherContext(IOThread::Globals* globals, context->set_server_bound_cert_service( globals->system_server_bound_cert_service.get()); context->set_network_delegate(globals->system_network_delegate.get()); + context->set_http_user_agent_settings( + globals->http_user_agent_settings.get()); // TODO(rtenneti): We should probably use HttpServerPropertiesManager for the // system URLRequestContext too. There's no reason this should be tied to a // profile. @@ -238,6 +224,8 @@ ConstructSystemRequestContext(IOThread::Globals* globals, globals->system_server_bound_cert_service.get()); context->set_throttler_manager(globals->throttler_manager.get()); context->set_network_delegate(globals->system_network_delegate.get()); + context->set_http_user_agent_settings( + globals->http_user_agent_settings.get()); return context; } @@ -476,6 +464,8 @@ void IOThread::Init() { base::WorkerPool::GetTaskRunner(true))); globals_->load_time_stats.reset(new chrome_browser_net::LoadTimeStats()); globals_->host_mapping_rules.reset(new net::HostMappingRules()); + globals_->http_user_agent_settings.reset( + new BasicHttpUserAgentSettings(EmptyString(), EmptyString())); if (command_line.HasSwitch(switches::kHostRules)) { globals_->host_mapping_rules->SetRulesFromString( command_line.GetSwitchValueASCII(switches::kHostRules)); diff --git a/chrome/browser/io_thread.h b/chrome/browser/io_thread.h index 6e0699c..ae1af7d 100644 --- a/chrome/browser/io_thread.h +++ b/chrome/browser/io_thread.h @@ -41,6 +41,7 @@ class HostResolver; class HttpAuthHandlerFactory; class HttpServerProperties; class HttpTransactionFactory; +class HttpUserAgentSettings; class NetworkDelegate; class ServerBoundCertService; class ProxyConfigService; @@ -115,6 +116,7 @@ class IOThread : public content::BrowserThreadDelegate { http_pipelining_compatibility_client; scoped_ptr<chrome_browser_net::LoadTimeStats> load_time_stats; scoped_ptr<net::HostMappingRules> host_mapping_rules; + scoped_ptr<net::HttpUserAgentSettings> http_user_agent_settings; bool ignore_certificate_errors; bool http_pipelining_enabled; uint16 testing_fixed_http_port; diff --git a/chrome/browser/net/basic_http_user_agent_settings.cc b/chrome/browser/net/basic_http_user_agent_settings.cc new file mode 100644 index 0000000..093ee58 --- /dev/null +++ b/chrome/browser/net/basic_http_user_agent_settings.cc @@ -0,0 +1,29 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/net/basic_http_user_agent_settings.h" + +#include "content/public/common/content_client.h" + +BasicHttpUserAgentSettings::BasicHttpUserAgentSettings( + const std::string& accept_language, const std::string& accept_charset) + : accept_language_(accept_language), + accept_charset_(accept_charset) { +} + +BasicHttpUserAgentSettings::~BasicHttpUserAgentSettings() { +} + +std::string BasicHttpUserAgentSettings::GetAcceptLanguage() const { + return accept_language_; +} + +std::string BasicHttpUserAgentSettings::GetAcceptCharset() const { + return accept_charset_; +} + +std::string BasicHttpUserAgentSettings::GetUserAgent(const GURL& url) const { + return content::GetUserAgent(url); +} + diff --git a/chrome/browser/net/basic_http_user_agent_settings.h b/chrome/browser/net/basic_http_user_agent_settings.h new file mode 100644 index 0000000..c7a6d59 --- /dev/null +++ b/chrome/browser/net/basic_http_user_agent_settings.h @@ -0,0 +1,36 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_NET_BASIC_HTTP_USER_AGENT_SETTINGS_H_ +#define CHROME_BROWSER_NET_BASIC_HTTP_USER_AGENT_SETTINGS_H_ + +#include <string> + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "net/url_request/http_user_agent_settings.h" + +// An implementation of |HttpUserAgentSettings| that provides fixed values for +// the HTTP headers Accept-Language and Accept-Charset and uses +// |content::GetUserAgent| to provide the HTTP User-Agent header value. +class BasicHttpUserAgentSettings : public net::HttpUserAgentSettings { + public: + BasicHttpUserAgentSettings(const std::string& accept_language, + const std::string& accept_charset); + virtual ~BasicHttpUserAgentSettings(); + + // HttpUserAgentSettings implementation + virtual std::string GetAcceptLanguage() const OVERRIDE; + virtual std::string GetAcceptCharset() const OVERRIDE; + virtual std::string GetUserAgent(const GURL& url) const OVERRIDE; + + private: + const std::string accept_language_; + const std::string accept_charset_; + + DISALLOW_COPY_AND_ASSIGN(BasicHttpUserAgentSettings); +}; + +#endif // CHROME_BROWSER_NET_BASIC_HTTP_USER_AGENT_SETTINGS_H_ + diff --git a/chrome/browser/net/chrome_http_user_agent_settings.cc b/chrome/browser/net/chrome_http_user_agent_settings.cc new file mode 100644 index 0000000..5141cb04c --- /dev/null +++ b/chrome/browser/net/chrome_http_user_agent_settings.cc @@ -0,0 +1,67 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/net/chrome_http_user_agent_settings.h" + +#include "chrome/browser/prefs/pref_service.h" +#include "chrome/common/pref_names.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/common/content_client.h" +#include "net/http/http_util.h" + +ChromeHttpUserAgentSettings::ChromeHttpUserAgentSettings(PrefService* prefs) { + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); + pref_accept_language_.Init(prefs::kAcceptLanguages, prefs, NULL); + pref_accept_charset_.Init(prefs::kDefaultCharset, prefs, NULL); + last_pref_accept_language_ = *pref_accept_language_; + last_http_accept_language_ = + net::HttpUtil::GenerateAcceptLanguageHeader(last_pref_accept_language_); + last_pref_accept_charset_ = *pref_accept_charset_; + last_http_accept_charset_ = + net::HttpUtil::GenerateAcceptCharsetHeader(last_pref_accept_charset_); + pref_accept_language_.MoveToThread( + content::BrowserThread::GetMessageLoopProxyForThread( + content::BrowserThread::IO)); + pref_accept_charset_.MoveToThread( + content::BrowserThread::GetMessageLoopProxyForThread( + content::BrowserThread::IO)); +} + +ChromeHttpUserAgentSettings::~ChromeHttpUserAgentSettings() { + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); +} + +void ChromeHttpUserAgentSettings::CleanupOnUIThread() { + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); + pref_accept_language_.Destroy(); + pref_accept_charset_.Destroy(); +} + +std::string ChromeHttpUserAgentSettings::GetAcceptLanguage() const { + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); + std::string new_pref_accept_language = *pref_accept_language_; + if (new_pref_accept_language != last_pref_accept_language_) { + last_http_accept_language_ = + net::HttpUtil::GenerateAcceptLanguageHeader(new_pref_accept_language); + last_pref_accept_language_ = new_pref_accept_language; + } + return last_http_accept_language_; +} + +std::string ChromeHttpUserAgentSettings::GetAcceptCharset() const { + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); + std::string new_pref_accept_charset = *pref_accept_charset_; + if (new_pref_accept_charset != last_pref_accept_charset_) { + last_http_accept_charset_ = + net::HttpUtil::GenerateAcceptCharsetHeader(new_pref_accept_charset); + last_pref_accept_charset_ = new_pref_accept_charset; + } + return last_http_accept_charset_; +} + +std::string ChromeHttpUserAgentSettings::GetUserAgent(const GURL& url) const { + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); + return content::GetUserAgent(url); +} + diff --git a/chrome/browser/net/chrome_http_user_agent_settings.h b/chrome/browser/net/chrome_http_user_agent_settings.h new file mode 100644 index 0000000..a7d390f --- /dev/null +++ b/chrome/browser/net/chrome_http_user_agent_settings.h @@ -0,0 +1,49 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_NET_CHROME_HTTP_USER_AGENT_SETTINGS_H_ +#define CHROME_BROWSER_NET_CHROME_HTTP_USER_AGENT_SETTINGS_H_ + +#include <string> + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "chrome/browser/api/prefs/pref_member.h" +#include "net/url_request/http_user_agent_settings.h" + +class PrefService; + +// An implementation of |HttpUserAgentSettings| that provides HTTP headers +// Accept-Language and Accept-Charset values that track Pref settings and uses +// |content::GetUserAgent| to provide the HTTP User-Agent header value. +class ChromeHttpUserAgentSettings : public net::HttpUserAgentSettings { + public: + // Must be called on the UI thread. + explicit ChromeHttpUserAgentSettings(PrefService* prefs); + // Must be called on the IO thread. + virtual ~ChromeHttpUserAgentSettings(); + + void CleanupOnUIThread(); + + // net::HttpUserAgentSettings implementation + virtual std::string GetAcceptLanguage() const OVERRIDE; + virtual std::string GetAcceptCharset() const OVERRIDE; + virtual std::string GetUserAgent(const GURL& url) const OVERRIDE; + + private: + StringPrefMember pref_accept_language_; + StringPrefMember pref_accept_charset_; + + // Avoid re-processing by caching the last value from the preferences and the + // last result of processing via net::HttpUtil::GenerateAccept*Header(). + mutable std::string last_pref_accept_language_; + mutable std::string last_http_accept_language_; + mutable std::string last_pref_accept_charset_; + mutable std::string last_http_accept_charset_; + + DISALLOW_COPY_AND_ASSIGN(ChromeHttpUserAgentSettings); +}; + +#endif // CHROME_BROWSER_NET_CHROME_HTTP_USER_AGENT_SETTINGS_H_ + diff --git a/chrome/browser/net/chrome_url_request_context.cc b/chrome/browser/net/chrome_url_request_context.cc index 3130ed2..677ed0a 100644 --- a/chrome/browser/net/chrome_url_request_context.cc +++ b/chrome/browser/net/chrome_url_request_context.cc @@ -11,18 +11,11 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/io_thread.h" #include "chrome/browser/net/load_time_stats.h" -#include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_io_data.h" #include "chrome/browser/profiles/storage_partition_descriptor.h" -#include "chrome/common/chrome_notification_types.h" -#include "chrome/common/pref_names.h" #include "content/public/browser/browser_thread.h" -#include "content/public/browser/notification_details.h" -#include "content/public/browser/notification_source.h" -#include "content/public/common/content_client.h" #include "net/cookies/cookie_store.h" -#include "net/http/http_util.h" using content::BrowserThread; @@ -156,19 +149,12 @@ class FactoryForMedia : public ChromeURLRequestContextFactory { // ---------------------------------------------------------------------------- ChromeURLRequestContextGetter::ChromeURLRequestContextGetter( - Profile* profile, ChromeURLRequestContextFactory* factory) : factory_(factory) { DCHECK(factory); - DCHECK(profile); - RegisterPrefsObserver(profile); } -ChromeURLRequestContextGetter::~ChromeURLRequestContextGetter() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - - DCHECK(registrar_.IsEmpty()) << "Probably didn't call CleanupOnUIThread"; -} +ChromeURLRequestContextGetter::~ChromeURLRequestContextGetter() {} // Lazily create a ChromeURLRequestContext using our factory. net::URLRequestContext* ChromeURLRequestContextGetter::GetURLRequestContext() { @@ -198,7 +184,6 @@ ChromeURLRequestContextGetter* ChromeURLRequestContextGetter::CreateOriginal( const ProfileIOData* profile_io_data) { DCHECK(!profile->IsOffTheRecord()); return new ChromeURLRequestContextGetter( - profile, new FactoryForMain(profile_io_data)); } @@ -208,7 +193,6 @@ ChromeURLRequestContextGetter::CreateOriginalForMedia( Profile* profile, const ProfileIOData* profile_io_data) { DCHECK(!profile->IsOffTheRecord()); return new ChromeURLRequestContextGetter( - profile, new FactoryForMedia(profile_io_data)); } @@ -218,7 +202,6 @@ ChromeURLRequestContextGetter::CreateOriginalForExtensions( Profile* profile, const ProfileIOData* profile_io_data) { DCHECK(!profile->IsOffTheRecord()); return new ChromeURLRequestContextGetter( - profile, new FactoryForExtensions(profile_io_data)); } @@ -234,7 +217,6 @@ ChromeURLRequestContextGetter::CreateOriginalForIsolatedApp( ChromeURLRequestContextGetter* main_context = static_cast<ChromeURLRequestContextGetter*>(profile->GetRequestContext()); return new ChromeURLRequestContextGetter( - profile, new FactoryForIsolatedApp(profile_io_data, partition_descriptor, main_context, protocol_handler_interceptor.Pass())); } @@ -248,7 +230,6 @@ ChromeURLRequestContextGetter::CreateOriginalForIsolatedMedia( const StoragePartitionDescriptor& partition_descriptor) { DCHECK(!profile->IsOffTheRecord()); return new ChromeURLRequestContextGetter( - profile, new FactoryForIsolatedMedia( profile_io_data, partition_descriptor, app_context)); } @@ -259,7 +240,7 @@ ChromeURLRequestContextGetter::CreateOffTheRecord( Profile* profile, const ProfileIOData* profile_io_data) { DCHECK(profile->IsOffTheRecord()); return new ChromeURLRequestContextGetter( - profile, new FactoryForMain(profile_io_data)); + new FactoryForMain(profile_io_data)); } // static @@ -268,7 +249,7 @@ ChromeURLRequestContextGetter::CreateOffTheRecordForExtensions( Profile* profile, const ProfileIOData* profile_io_data) { DCHECK(profile->IsOffTheRecord()); return new ChromeURLRequestContextGetter( - profile, new FactoryForExtensions(profile_io_data)); + new FactoryForExtensions(profile_io_data)); } // static @@ -283,62 +264,10 @@ ChromeURLRequestContextGetter::CreateOffTheRecordForIsolatedApp( ChromeURLRequestContextGetter* main_context = static_cast<ChromeURLRequestContextGetter*>(profile->GetRequestContext()); return new ChromeURLRequestContextGetter( - profile, new FactoryForIsolatedApp(profile_io_data, partition_descriptor, main_context, protocol_handler_interceptor.Pass())); } -void ChromeURLRequestContextGetter::CleanupOnUIThread() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - // Unregister for pref notifications. - DCHECK(!registrar_.IsEmpty()) << "Called more than once!"; - registrar_.RemoveAll(); -} - -void ChromeURLRequestContextGetter::OnPreferenceChanged( - PrefServiceBase* prefs, - const std::string& pref_name_in) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - - DCHECK(prefs); - if (pref_name_in == prefs::kAcceptLanguages) { - std::string accept_language = - prefs->GetString(prefs::kAcceptLanguages); - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - base::Bind( - &ChromeURLRequestContextGetter::OnAcceptLanguageChange, - this, - accept_language)); - } else if (pref_name_in == prefs::kDefaultCharset) { - std::string default_charset = prefs->GetString(prefs::kDefaultCharset); - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - base::Bind( - &ChromeURLRequestContextGetter::OnDefaultCharsetChange, - this, - default_charset)); - } -} - -void ChromeURLRequestContextGetter::RegisterPrefsObserver(Profile* profile) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - - registrar_.Init(profile->GetPrefs()); - registrar_.Add(prefs::kAcceptLanguages, this); - registrar_.Add(prefs::kDefaultCharset, this); -} - -void ChromeURLRequestContextGetter::OnAcceptLanguageChange( - const std::string& accept_language) { - GetIOContext()->OnAcceptLanguageChange(accept_language); -} - -void ChromeURLRequestContextGetter::OnDefaultCharsetChange( - const std::string& default_charset) { - GetIOContext()->OnDefaultCharsetChange(default_charset); -} - // ---------------------------------------------------------------------------- // ChromeURLRequestContext // ---------------------------------------------------------------------------- @@ -379,22 +308,3 @@ void ChromeURLRequestContext::set_chrome_url_data_manager_backend( DCHECK(backend); chrome_url_data_manager_backend_ = backend; } - -const std::string& ChromeURLRequestContext::GetUserAgent( - const GURL& url) const { - return content::GetUserAgent(url); -} - -void ChromeURLRequestContext::OnAcceptLanguageChange( - const std::string& accept_language) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - set_accept_language( - net::HttpUtil::GenerateAcceptLanguageHeader(accept_language)); -} - -void ChromeURLRequestContext::OnDefaultCharsetChange( - const std::string& default_charset) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - set_accept_charset( - net::HttpUtil::GenerateAcceptCharsetHeader(default_charset)); -} diff --git a/chrome/browser/net/chrome_url_request_context.h b/chrome/browser/net/chrome_url_request_context.h index 90ee941..93ce806 100644 --- a/chrome/browser/net/chrome_url_request_context.h +++ b/chrome/browser/net/chrome_url_request_context.h @@ -8,8 +8,6 @@ #include <string> #include "base/memory/scoped_ptr.h" -#include "base/prefs/public/pref_change_registrar.h" -#include "base/prefs/public/pref_observer.h" #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context_getter.h" #include "net/url_request/url_request_job_factory.h" @@ -53,8 +51,6 @@ class ChromeURLRequestContext : public net::URLRequestContext { return is_incognito_; } - virtual const std::string& GetUserAgent(const GURL& url) const OVERRIDE; - // TODO(willchan): Get rid of the need for this accessor. Really, this should // move completely to ProfileIOData. ChromeURLDataManagerBackend* chrome_url_data_manager_backend() const; @@ -66,12 +62,6 @@ class ChromeURLRequestContext : public net::URLRequestContext { void set_chrome_url_data_manager_backend( ChromeURLDataManagerBackend* backend); - // Callback for when the accept language changes. - void OnAcceptLanguageChange(const std::string& accept_language); - - // Callback for when the default charset changes. - void OnDefaultCharsetChange(const std::string& default_charset); - private: base::WeakPtrFactory<ChromeURLRequestContext> weak_factory_; @@ -98,16 +88,12 @@ class ChromeURLRequestContext : public net::URLRequestContext { // // Most methods are expected to be called on the UI thread, except for // the destructor and GetURLRequestContext(). -class ChromeURLRequestContextGetter : public net::URLRequestContextGetter, - public PrefObserver { +class ChromeURLRequestContextGetter : public net::URLRequestContextGetter { public: // Constructs a ChromeURLRequestContextGetter that will use |factory| to - // create the ChromeURLRequestContext. If |profile| is non-NULL, then the - // ChromeURLRequestContextGetter will additionally watch the preferences for - // changes to charset/language and CleanupOnUIThread() will need to be - // called to unregister. - ChromeURLRequestContextGetter(Profile* profile, - ChromeURLRequestContextFactory* factory); + // create the ChromeURLRequestContext. + explicit ChromeURLRequestContextGetter( + ChromeURLRequestContextFactory* factory); // Note that GetURLRequestContext() can only be called from the IO // thread (it will assert otherwise). @@ -176,29 +162,9 @@ class ChromeURLRequestContextGetter : public net::URLRequestContextGetter, scoped_ptr<net::URLRequestJobFactory::Interceptor> protocol_handler_interceptor); - // Clean up UI thread resources. This is expected to get called on the UI - // thread before the instance is deleted on the IO thread. - void CleanupOnUIThread(); - - // PrefObserver implementation. - virtual void OnPreferenceChanged(PrefServiceBase* service, - const std::string& pref_name) OVERRIDE; - private: - // Must be called on the IO thread. virtual ~ChromeURLRequestContextGetter(); - // Registers an observer on |profile|'s preferences which will be used - // to update the context when the default language and charset change. - void RegisterPrefsObserver(Profile* profile); - - // These methods simply forward to the corresponding method on - // ChromeURLRequestContext. - void OnAcceptLanguageChange(const std::string& accept_language); - void OnDefaultCharsetChange(const std::string& default_charset); - - PrefChangeRegistrar registrar_; - // Deferred logic for creating a ChromeURLRequestContext. // Access only from the IO thread. scoped_ptr<ChromeURLRequestContextFactory> factory_; diff --git a/chrome/browser/policy/device_management_service.cc b/chrome/browser/policy/device_management_service.cc index bbc7a07..18245b3 100644 --- a/chrome/browser/policy/device_management_service.cc +++ b/chrome/browser/policy/device_management_service.cc @@ -13,6 +13,7 @@ #include "base/stringprintf.h" #include "base/sys_info.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/net/basic_http_user_agent_settings.h" #include "chrome/browser/net/chrome_net_log.h" #include "chrome/common/chrome_version_info.h" #include "content/public/browser/browser_thread.h" @@ -185,12 +186,13 @@ class DeviceManagementRequestContext : public net::URLRequestContext { virtual ~DeviceManagementRequestContext(); private: - // Overridden from net::URLRequestContext: - virtual const std::string& GetUserAgent(const GURL& url) const OVERRIDE; + BasicHttpUserAgentSettings basic_http_user_agent_settings_; }; DeviceManagementRequestContext::DeviceManagementRequestContext( - net::URLRequestContext* base_context) { + net::URLRequestContext* base_context) + // Use sane Accept-Language and Accept-Charset values for our purposes. + : basic_http_user_agent_settings_("*", "*") { // Share resolver, proxy service and ssl bits with the baseline context. This // is important so we don't make redundant requests (e.g. when resolving proxy // auto configuration). @@ -207,20 +209,13 @@ DeviceManagementRequestContext::DeviceManagementRequestContext( // No cookies, please. set_cookie_store(new net::CookieMonster(NULL, NULL)); - // Initialize these to sane values for our purposes. - set_accept_language("*"); - set_accept_charset("*"); + set_http_user_agent_settings(&basic_http_user_agent_settings_); } DeviceManagementRequestContext::~DeviceManagementRequestContext() { delete http_transaction_factory(); } -const std::string& DeviceManagementRequestContext::GetUserAgent( - const GURL& url) const { - return content::GetUserAgent(url); -} - // Request context holder. class DeviceManagementRequestContextGetter : public net::URLRequestContextGetter { diff --git a/chrome/browser/profiles/off_the_record_profile_io_data.cc b/chrome/browser/profiles/off_the_record_profile_io_data.cc index 88dcf1f..3be7f61 100644 --- a/chrome/browser/profiles/off_the_record_profile_io_data.cc +++ b/chrome/browser/profiles/off_the_record_profile_io_data.cc @@ -47,19 +47,6 @@ OffTheRecordProfileIOData::Handle::Handle(Profile* profile) OffTheRecordProfileIOData::Handle::~Handle() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - if (main_request_context_getter_) - main_request_context_getter_->CleanupOnUIThread(); - if (extensions_request_context_getter_) - extensions_request_context_getter_->CleanupOnUIThread(); - - // Clean up all isolated app request contexts. - for (ChromeURLRequestContextGetterMap::iterator iter = - app_request_context_getter_map_.begin(); - iter != app_request_context_getter_map_.end(); - ++iter) { - iter->second->CleanupOnUIThread(); - } - io_data_->ShutdownOnUIThread(); } diff --git a/chrome/browser/profiles/profile_impl_io_data.cc b/chrome/browser/profiles/profile_impl_io_data.cc index 2a53927..65e8822 100644 --- a/chrome/browser/profiles/profile_impl_io_data.cc +++ b/chrome/browser/profiles/profile_impl_io_data.cc @@ -51,13 +51,6 @@ ProfileImplIOData::Handle::Handle(Profile* profile) ProfileImplIOData::Handle::~Handle() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - if (main_request_context_getter_) - main_request_context_getter_->CleanupOnUIThread(); - if (media_request_context_getter_) - media_request_context_getter_->CleanupOnUIThread(); - if (extensions_request_context_getter_) - extensions_request_context_getter_->CleanupOnUIThread(); - if (io_data_->predictor_.get() != NULL) { // io_data_->predictor_ might be NULL if Init() was never called // (i.e. we shut down before ProfileImpl::DoFinalInit() got called). @@ -65,22 +58,6 @@ ProfileImplIOData::Handle::~Handle() { io_data_->predictor_->ShutdownOnUIThread(user_prefs); } - // Clean up all isolated app request contexts. - for (ChromeURLRequestContextGetterMap::iterator iter = - app_request_context_getter_map_.begin(); - iter != app_request_context_getter_map_.end(); - ++iter) { - iter->second->CleanupOnUIThread(); - } - - // Clean up all isolated media request contexts. - for (ChromeURLRequestContextGetterMap::iterator iter = - isolated_media_request_context_getter_map_.begin(); - iter != isolated_media_request_context_getter_map_.end(); - ++iter) { - iter->second->CleanupOnUIThread(); - } - if (io_data_->http_server_properties_manager()) io_data_->http_server_properties_manager()->ShutdownOnUIThread(); io_data_->ShutdownOnUIThread(); diff --git a/chrome/browser/profiles/profile_io_data.cc b/chrome/browser/profiles/profile_io_data.cc index a03ed92..dab854fb 100644 --- a/chrome/browser/profiles/profile_io_data.cc +++ b/chrome/browser/profiles/profile_io_data.cc @@ -31,6 +31,7 @@ #include "chrome/browser/io_thread.h" #include "chrome/browser/net/chrome_cookie_notification_details.h" #include "chrome/browser/net/chrome_fraudulent_certificate_reporter.h" +#include "chrome/browser/net/chrome_http_user_agent_settings.h" #include "chrome/browser/net/chrome_net_log.h" #include "chrome/browser/net/chrome_network_delegate.h" #include "chrome/browser/net/http_server_properties_manager.h" @@ -145,13 +146,6 @@ void ProfileIOData::InitializeOnUIThread(Profile* profile) { scoped_ptr<ProfileParams> params(new ProfileParams); params->path = profile->GetPath(); - // Set up Accept-Language and Accept-Charset header values - params->accept_language = net::HttpUtil::GenerateAcceptLanguageHeader( - pref_service->GetString(prefs::kAcceptLanguages)); - std::string default_charset = pref_service->GetString(prefs::kDefaultCharset); - params->accept_charset = - net::HttpUtil::GenerateAcceptCharsetHeader(default_charset); - params->io_thread = g_browser_process->io_thread(); params->cookie_settings = CookieSettings::Factory::GetForProfile(profile); @@ -204,6 +198,8 @@ void ProfileIOData::InitializeOnUIThread(Profile* profile) { printing_enabled_.MoveToThread( BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)); #endif + chrome_http_user_agent_settings_.reset( + new ChromeHttpUserAgentSettings(pref_service)); // The URLBlacklistManager has to be created on the UI thread to register // observers of |pref_service|, and it also has to clean up on @@ -583,8 +579,8 @@ void ProfileIOData::LazyInitialize() const { void ProfileIOData::ApplyProfileParamsToContext( ChromeURLRequestContext* context) const { context->set_is_incognito(is_incognito()); - context->set_accept_language(profile_params_->accept_language); - context->set_accept_charset(profile_params_->accept_charset); + context->set_http_user_agent_settings( + chrome_http_user_agent_settings_.get()); context->set_ssl_config_service(profile_params_->ssl_config_service); } @@ -668,6 +664,8 @@ void ProfileIOData::ShutdownOnUIThread() { if (url_blacklist_manager_.get()) url_blacklist_manager_->ShutdownOnUIThread(); #endif + if (chrome_http_user_agent_settings_.get()) + chrome_http_user_agent_settings_->CleanupOnUIThread(); bool posted = BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, this); if (!posted) delete this; diff --git a/chrome/browser/profiles/profile_io_data.h b/chrome/browser/profiles/profile_io_data.h index fbdd845..354c86b 100644 --- a/chrome/browser/profiles/profile_io_data.h +++ b/chrome/browser/profiles/profile_io_data.h @@ -23,6 +23,7 @@ #include "net/http/http_network_session.h" #include "net/url_request/url_request_job_factory.h" +class ChromeHttpUserAgentSettings; class CookieSettings; class DesktopNotificationService; class ExtensionInfoMap; @@ -186,8 +187,6 @@ class ProfileIOData { ~ProfileParams(); FilePath path; - std::string accept_language; - std::string accept_charset; IOThread* io_thread; scoped_refptr<CookieSettings> cookie_settings; scoped_refptr<net::SSLConfigService> ssl_config_service; @@ -428,6 +427,9 @@ class ProfileIOData { mutable scoped_ptr<chrome_browser_net::ResourcePrefetchPredictorObserver> resource_prefetch_predictor_observer_; + mutable scoped_ptr<ChromeHttpUserAgentSettings> + chrome_http_user_agent_settings_; + mutable chrome_browser_net::LoadTimeStats* load_time_stats_; // TODO(jhawkins): Remove once crbug.com/102004 is fixed. diff --git a/chrome/browser/safe_browsing/safe_browsing_service.cc b/chrome/browser/safe_browsing/safe_browsing_service.cc index 45a5a86..3b112d2 100644 --- a/chrome/browser/safe_browsing/safe_browsing_service.cc +++ b/chrome/browser/safe_browsing/safe_browsing_service.cc @@ -100,22 +100,6 @@ FilePath CookieFilePath() { } // namespace -// Custom URLRequestContext used by SafeBrowsing requests, which are not -// associated with a particular profile. We need to use a subclass of -// URLRequestContext in order to provide the correct User-Agent. -class SafeBrowsingURLRequestContext : public net::URLRequestContext { - public: - virtual const std::string& GetUserAgent( - const GURL& url) const OVERRIDE { - return content::GetUserAgent(url); - } - - private: - virtual ~SafeBrowsingURLRequestContext() {} - - base::debug::LeakTracker<SafeBrowsingURLRequestContext> leak_tracker_; -}; - class SafeBrowsingURLRequestContextGetter : public net::URLRequestContextGetter { public: @@ -624,11 +608,12 @@ void SafeBrowsingService::InitURLRequestContextOnIOThread( new SQLitePersistentCookieStore(CookieFilePath(), false, NULL), NULL); - url_request_context_.reset(new SafeBrowsingURLRequestContext); + url_request_context_.reset(new net::URLRequestContext); // |system_url_request_context_getter| may be NULL during tests. - if (system_url_request_context_getter) + if (system_url_request_context_getter) { url_request_context_->CopyFrom( system_url_request_context_getter->GetURLRequestContext()); + } url_request_context_->set_cookie_store(cookie_store); } diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index b3e8ebd..dc6f528 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -1038,9 +1038,13 @@ 'browser/net/about_protocol_handler.h', 'browser/net/async_dns_field_trial.cc', 'browser/net/async_dns_field_trial.h', + 'browser/net/basic_http_user_agent_settings.cc', + 'browser/net/basic_http_user_agent_settings.h', 'browser/net/chrome_cookie_notification_details.h', 'browser/net/chrome_fraudulent_certificate_reporter.cc', 'browser/net/chrome_fraudulent_certificate_reporter.h', + 'browser/net/chrome_http_user_agent_settings.cc', + 'browser/net/chrome_http_user_agent_settings.h', 'browser/net/chrome_net_log.cc', 'browser/net/chrome_net_log.h', 'browser/net/chrome_network_delegate.cc', diff --git a/chrome/service/net/service_url_request_context.cc b/chrome/service/net/service_url_request_context.cc index e05b7b9..3bb5565 100644 --- a/chrome/service/net/service_url_request_context.cc +++ b/chrome/service/net/service_url_request_context.cc @@ -25,6 +25,7 @@ #include "net/http/http_server_properties_impl.h" #include "net/proxy/proxy_config_service.h" #include "net/proxy/proxy_service.h" +#include "net/url_request/static_http_user_agent_settings.h" #include "net/url_request/url_request_throttler_manager.h" namespace { @@ -108,8 +109,7 @@ std::string MakeUserAgentForServiceProcess() { ServiceURLRequestContext::ServiceURLRequestContext( const std::string& user_agent, net::ProxyConfigService* net_proxy_config_service) - : user_agent_(user_agent), - ALLOW_THIS_IN_INITIALIZER_LIST(storage_(this)) { + : ALLOW_THIS_IN_INITIALIZER_LIST(storage_(this)) { storage_.set_host_resolver(net::HostResolver::CreateDefaultResolver(NULL)); storage_.set_proxy_service(net::ProxyService::CreateUsingSystemProxyResolver( net_proxy_config_service, 0u, NULL)); @@ -138,16 +138,8 @@ ServiceURLRequestContext::ServiceURLRequestContext( net::HttpCache::DefaultBackend::InMemory(0))); // In-memory cookie store. storage_.set_cookie_store(new net::CookieMonster(NULL, NULL)); - set_accept_language("en-us,fr"); - set_accept_charset("iso-8859-1,*,utf-8"); -} - -const std::string& ServiceURLRequestContext::GetUserAgent( - const GURL& url) const { - // If the user agent is set explicitly return that, otherwise call the - // base class method to return default value. - return user_agent_.empty() ? - net::URLRequestContext::GetUserAgent(url) : user_agent_; + storage_.set_http_user_agent_settings(new net::StaticHttpUserAgentSettings( + "en-us,fr", "iso-8859-1,*,utf-8", user_agent)); } ServiceURLRequestContext::~ServiceURLRequestContext() { diff --git a/chrome/service/net/service_url_request_context.h b/chrome/service/net/service_url_request_context.h index 6fa2429..aa06778 100644 --- a/chrome/service/net/service_url_request_context.h +++ b/chrome/service/net/service_url_request_context.h @@ -41,11 +41,7 @@ class ServiceURLRequestContext : public net::URLRequestContext { virtual ~ServiceURLRequestContext(); - // Overridden from net::URLRequestContext: - virtual const std::string& GetUserAgent(const GURL& url) const OVERRIDE; - private: - std::string user_agent_; net::URLRequestContextStorage storage_; }; diff --git a/chrome_frame/test/net/fake_external_tab.cc b/chrome_frame/test/net/fake_external_tab.cc index 1f6c808..87f3065 100644 --- a/chrome_frame/test/net/fake_external_tab.cc +++ b/chrome_frame/test/net/fake_external_tab.cc @@ -264,9 +264,10 @@ void FilterDisabledTests() { "URLRequestTestHTTP.ProxyTunnelRedirectTest", "URLRequestTestHTTP.UnexpectedServerAuthTest", - // This test is disabled as it expects an empty UA to be echoed back from - // the server which is not the case in ChromeFrame. + // These tests are disabled as they expect an empty UA to be echoed back + // from the server which is not the case in ChromeFrame. "URLRequestTestHTTP.DefaultUserAgent", + "URLRequestTestHTTP.EmptyHttpUserAgentSettings", // This test modifies the UploadData object after it has been marshaled to // ChromeFrame. We don't support this. "URLRequestTestHTTP.TestPostChunkedDataAfterStart", diff --git a/chrome_frame/test/net/test_automation_provider.cc b/chrome_frame/test/net/test_automation_provider.cc index 9012a19..7b94536 100644 --- a/chrome_frame/test/net/test_automation_provider.cc +++ b/chrome_frame/test/net/test_automation_provider.cc @@ -9,6 +9,7 @@ #include "base/path_service.h" #include "chrome/common/automation_messages.h" #include "chrome_frame/test/net/test_automation_resource_message_filter.h" +#include "net/url_request/url_request_context.h" namespace { @@ -93,6 +94,7 @@ net::URLRequestJob* TestAutomationProvider::Factory( static int new_id = 0x00100000; URLRequestAutomationJob* job = new URLRequestAutomationJob( request, network_delegate, + request->context()->http_user_agent_settings(), g_provider_instance_->tab_handle_, new_id++, g_provider_instance_->automation_resource_message_filter_, false); return job; diff --git a/content/browser/speech/google_one_shot_remote_engine.cc b/content/browser/speech/google_one_shot_remote_engine.cc index d713dfd..73e621e 100644 --- a/content/browser/speech/google_one_shot_remote_engine.cc +++ b/content/browser/speech/google_one_shot_remote_engine.cc @@ -171,7 +171,10 @@ void GoogleOneShotRemoteEngine::StartRecognition() { net::URLRequestContext* request_context = url_context_->GetURLRequestContext(); DCHECK(request_context); - std::string accepted_language_list = request_context->accept_language(); + // TODO(pauljensen): GoogleOneShotRemoteEngine should be constructed with + // a reference to the HttpUserAgentSettings rather than accessing the + // accept language through the URLRequestContext. + std::string accepted_language_list = request_context->GetAcceptLanguage(); size_t separator = accepted_language_list.find_first_of(",;"); lang_param = accepted_language_list.substr(0, separator); } diff --git a/content/browser/speech/google_streaming_remote_engine.cc b/content/browser/speech/google_streaming_remote_engine.cc index 2f050bd..974118f 100644 --- a/content/browser/speech/google_streaming_remote_engine.cc +++ b/content/browser/speech/google_streaming_remote_engine.cc @@ -560,7 +560,10 @@ std::string GoogleStreamingRemoteEngine::GetAcceptedLanguages() const { net::URLRequestContext* request_context = url_context_->GetURLRequestContext(); DCHECK(request_context); - std::string accepted_language_list = request_context->accept_language(); + // TODO(pauljensen): GoogleStreamingRemoteEngine should be constructed with + // a reference to the HttpUserAgentSettings rather than accessing the + // accept language through the URLRequestContext. + std::string accepted_language_list = request_context->GetAcceptLanguage(); size_t separator = accepted_language_list.find_first_of(",;"); if (separator != std::string::npos) langs = accepted_language_list.substr(0, separator); diff --git a/content/shell/shell_url_request_context_getter.cc b/content/shell/shell_url_request_context_getter.cc index 9300dc6..3c4cb12 100644 --- a/content/shell/shell_url_request_context_getter.cc +++ b/content/shell/shell_url_request_context_getter.cc @@ -8,6 +8,7 @@ #include "base/logging.h" #include "base/string_number_conversions.h" #include "base/string_split.h" +#include "base/string_util.h" #include "base/threading/worker_pool.h" #include "content/public/browser/browser_thread.h" #include "content/public/common/content_switches.h" @@ -24,6 +25,7 @@ #include "net/http/http_network_session.h" #include "net/http/http_server_properties_impl.h" #include "net/proxy/proxy_service.h" +#include "net/url_request/static_http_user_agent_settings.h" #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context_storage.h" #include "net/url_request/url_request_job_factory_impl.h" @@ -68,8 +70,9 @@ net::URLRequestContext* ShellURLRequestContextGetter::GetURLRequestContext() { storage_->set_server_bound_cert_service(new net::ServerBoundCertService( new net::DefaultServerBoundCertStore(NULL), base::WorkerPool::GetTaskRunner(true))); - url_request_context_->set_accept_language("en-us,en"); - url_request_context_->set_accept_charset("iso-8859-1,*,utf-8"); + storage_->set_http_user_agent_settings( + new net::StaticHttpUserAgentSettings( + "en-us,en", "iso-8859-1,*,utf-8", EmptyString())); scoped_ptr<net::HostResolver> host_resolver( net::HostResolver::CreateDefaultResolver(NULL)); diff --git a/net/net.gyp b/net/net.gyp index ebab562..9603be5 100644 --- a/net/net.gyp +++ b/net/net.gyp @@ -819,6 +819,9 @@ 'url_request/fraudulent_certificate_reporter.h', 'url_request/ftp_protocol_handler.cc', 'url_request/ftp_protocol_handler.h', + 'url_request/http_user_agent_settings.h', + 'url_request/static_http_user_agent_settings.cc', + 'url_request/static_http_user_agent_settings.h', 'url_request/url_fetcher.cc', 'url_request/url_fetcher.h', 'url_request/url_fetcher_core.cc', diff --git a/net/url_request/http_user_agent_settings.h b/net/url_request/http_user_agent_settings.h new file mode 100644 index 0000000..84ae9fb --- /dev/null +++ b/net/url_request/http_user_agent_settings.h @@ -0,0 +1,41 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef NET_URL_REQUEST_HTTP_USER_AGENT_SETTINGS_H_ +#define NET_URL_REQUEST_HTTP_USER_AGENT_SETTINGS_H_ + +#include <string> + +#include "base/basictypes.h" +#include "net/base/net_export.h" + +class GURL; + +namespace net { + +// The interface used by HTTP jobs to retrieve HTTP Accept-Language, +// Accept-Charset and User-Agent header values. +class NET_EXPORT HttpUserAgentSettings { + public: + HttpUserAgentSettings() {} + virtual ~HttpUserAgentSettings() {} + + // Gets the value of 'Accept-Language' header field. + virtual std::string GetAcceptLanguage() const = 0; + + // Gets the value of 'Accept-Charset' header field. + virtual std::string GetAcceptCharset() const = 0; + + // Gets the UA string to use for the given URL. Pass an empty URL to get + // the default UA string. + virtual std::string GetUserAgent(const GURL& url) const = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(HttpUserAgentSettings); +}; + +} // namespace net + +#endif // NET_URL_REQUEST_HTTP_USER_AGENT_SETTINGS_H_ + diff --git a/net/url_request/static_http_user_agent_settings.cc b/net/url_request/static_http_user_agent_settings.cc new file mode 100644 index 0000000..475aa8f --- /dev/null +++ b/net/url_request/static_http_user_agent_settings.cc @@ -0,0 +1,34 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/url_request/static_http_user_agent_settings.h" + +namespace net { + +StaticHttpUserAgentSettings::StaticHttpUserAgentSettings( + const std::string& accept_language, + const std::string& accept_charset, + const std::string& user_agent) + : accept_language_(accept_language), + accept_charset_(accept_charset), + user_agent_(user_agent) { +} + +StaticHttpUserAgentSettings::~StaticHttpUserAgentSettings() { +} + +std::string StaticHttpUserAgentSettings::GetAcceptLanguage() const { + return accept_language_; +} + +std::string StaticHttpUserAgentSettings::GetAcceptCharset() const { + return accept_charset_; +} + +std::string StaticHttpUserAgentSettings::GetUserAgent(const GURL& url) const { + return user_agent_; +} + +} // namespace net + diff --git a/net/url_request/static_http_user_agent_settings.h b/net/url_request/static_http_user_agent_settings.h new file mode 100644 index 0000000..09cabd3 --- /dev/null +++ b/net/url_request/static_http_user_agent_settings.h @@ -0,0 +1,43 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef NET_URL_REQUEST_STATIC_HTTP_USER_AGENT_SETTINGS_H_ +#define NET_URL_REQUEST_STATIC_HTTP_USER_AGENT_SETTINGS_H_ + +#include <string> + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "net/base/net_export.h" +#include "net/url_request/http_user_agent_settings.h" + +namespace net { + +// An implementation of |HttpUserAgentSettings| that always provides the +// same constant values for the HTTP Accept-Language, Accept-Charset, and +// User-Agent headers. +class NET_EXPORT StaticHttpUserAgentSettings : public HttpUserAgentSettings { + public: + StaticHttpUserAgentSettings(const std::string& accept_language, + const std::string& accept_charset, + const std::string& user_agent); + virtual ~StaticHttpUserAgentSettings(); + + // HttpUserAgentSettings implementation + virtual std::string GetAcceptLanguage() const OVERRIDE; + virtual std::string GetAcceptCharset() const OVERRIDE; + virtual std::string GetUserAgent(const GURL& url) const OVERRIDE; + + private: + const std::string accept_language_; + const std::string accept_charset_; + const std::string user_agent_; + + DISALLOW_COPY_AND_ASSIGN(StaticHttpUserAgentSettings); +}; + +} // namespace net + +#endif // NET_URL_REQUEST_STATIC_HTTP_USER_AGENT_SETTINGS_H_ + diff --git a/net/url_request/url_request_context.cc b/net/url_request/url_request_context.cc index 42a5789..94d7f22 100644 --- a/net/url_request/url_request_context.cc +++ b/net/url_request/url_request_context.cc @@ -12,6 +12,7 @@ #include "net/cookies/cookie_store.h" #include "net/ftp/ftp_transaction_factory.h" #include "net/http/http_transaction_factory.h" +#include "net/url_request/http_user_agent_settings.h" #include "net/url_request/url_request.h" namespace net { @@ -26,6 +27,7 @@ URLRequestContext::URLRequestContext() proxy_service_(NULL), network_delegate_(NULL), http_server_properties_(NULL), + http_user_agent_settings_(NULL), transport_security_state_(NULL), #if !defined(DISABLE_FTP_SUPPORT) ftp_auth_cache_(new FtpAuthCache), @@ -56,12 +58,11 @@ void URLRequestContext::CopyFrom(const URLRequestContext* other) { set_cookie_store(other->cookie_store_); set_transport_security_state(other->transport_security_state_); // FTPAuthCache is unique per context. - set_accept_language(other->accept_language_); - set_accept_charset(other->accept_charset_); set_http_transaction_factory(other->http_transaction_factory_); set_ftp_transaction_factory(other->ftp_transaction_factory_); set_job_factory(other->job_factory_); set_throttler_manager(other->throttler_manager_); + set_http_user_agent_settings(other->http_user_agent_settings_); } const HttpNetworkSession::Params* URLRequestContext::GetNetworkSessionParams( @@ -84,8 +85,19 @@ void URLRequestContext::set_cookie_store(CookieStore* cookie_store) { cookie_store_ = cookie_store; } -const std::string& URLRequestContext::GetUserAgent(const GURL& url) const { - return EmptyString(); +std::string URLRequestContext::GetAcceptCharset() const { + return http_user_agent_settings_ ? + http_user_agent_settings_->GetAcceptCharset() : EmptyString(); +} + +std::string URLRequestContext::GetAcceptLanguage() const { + return http_user_agent_settings_ ? + http_user_agent_settings_->GetAcceptLanguage() : EmptyString(); +} + +std::string URLRequestContext::GetUserAgent(const GURL& url) const { + return http_user_agent_settings_ ? + http_user_agent_settings_->GetUserAgent(url) : EmptyString(); } void URLRequestContext::AssertNoURLRequests() const { diff --git a/net/url_request/url_request_context.h b/net/url_request/url_request_context.h index fb6af73..cbafc44 100644 --- a/net/url_request/url_request_context.h +++ b/net/url_request/url_request_context.h @@ -11,6 +11,7 @@ #define NET_URL_REQUEST_URL_REQUEST_CONTEXT_H_ #include <set> +#include <string> #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" @@ -33,6 +34,7 @@ class FtpTransactionFactory; class HostResolver; class HttpAuthHandlerFactory; class HttpTransactionFactory; +class HttpUserAgentSettings; class NetworkDelegate; class ServerBoundCertService; class ProxyService; @@ -172,22 +174,18 @@ class NET_EXPORT URLRequestContext #endif } + // --------------------------------------------------------------------------- + // Legacy accessors that delegate to http_user_agent_settings_. + // TODO(pauljensen): Remove after all clients are updated to directly access + // http_user_agent_settings_. // Gets the value of 'Accept-Charset' header field. - const std::string& accept_charset() const { return accept_charset_; } - void set_accept_charset(const std::string& accept_charset) { - accept_charset_ = accept_charset; - } - + std::string GetAcceptCharset() const; // Gets the value of 'Accept-Language' header field. - const std::string& accept_language() const { return accept_language_; } - void set_accept_language(const std::string& accept_language) { - accept_language_ = accept_language; - } - + std::string GetAcceptLanguage() const; // Gets the UA string to use for the given URL. Pass an invalid URL (such as - // GURL()) to get the default UA string. Subclasses should override this - // method to provide a UA string. - virtual const std::string& GetUserAgent(const GURL& url) const; + // GURL()) to get the default UA string. + std::string GetUserAgent(const GURL& url) const; + // --------------------------------------------------------------------------- const URLRequestJobFactory* job_factory() const { return job_factory_; } void set_job_factory(const URLRequestJobFactory* job_factory) { @@ -210,6 +208,16 @@ class NET_EXPORT URLRequestContext void AssertNoURLRequests() const; + // Get the underlying |HttpUserAgentSettings| implementation that provides + // the HTTP Accept-Language, Accept-Charset and User-Agent header values. + const HttpUserAgentSettings* http_user_agent_settings() const { + return http_user_agent_settings_; + } + void set_http_user_agent_settings( + HttpUserAgentSettings* http_user_agent_settings) { + http_user_agent_settings_ = http_user_agent_settings; + } + private: // --------------------------------------------------------------------------- // Important: When adding any new members below, consider whether they need to @@ -228,13 +236,12 @@ class NET_EXPORT URLRequestContext scoped_refptr<SSLConfigService> ssl_config_service_; NetworkDelegate* network_delegate_; HttpServerProperties* http_server_properties_; + HttpUserAgentSettings* http_user_agent_settings_; scoped_refptr<CookieStore> cookie_store_; TransportSecurityState* transport_security_state_; #if !defined(DISABLE_FTP_SUPPORT) scoped_ptr<FtpAuthCache> ftp_auth_cache_; #endif - std::string accept_language_; - std::string accept_charset_; // The charset of the referrer where this request comes from. It's not // used in communication with a server but is used to construct a suggested // filename for file download. diff --git a/net/url_request/url_request_context_builder.cc b/net/url_request/url_request_context_builder.cc index 217337f..f1cf1aa 100644 --- a/net/url_request/url_request_context_builder.cc +++ b/net/url_request/url_request_context_builder.cc @@ -9,6 +9,7 @@ #include "base/basictypes.h" #include "base/compiler_specific.h" #include "base/logging.h" +#include "base/string_util.h" #include "base/threading/thread.h" #include "base/thread_task_runner_handle.h" #include "net/base/cert_verifier.h" @@ -25,6 +26,7 @@ #include "net/http/http_network_session.h" #include "net/http/http_server_properties_impl.h" #include "net/proxy/proxy_service.h" +#include "net/url_request/static_http_user_agent_settings.h" #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context_storage.h" @@ -129,10 +131,6 @@ class BasicURLRequestContext : public URLRequestContext { return &storage_; } - void set_user_agent(const std::string& user_agent) { - user_agent_ = user_agent; - } - void StartCacheThread() { cache_thread_.StartWithOptions( base::Thread::Options(MessageLoop::TYPE_IO, 0)); @@ -153,16 +151,10 @@ class BasicURLRequestContext : public URLRequestContext { return file_thread_.message_loop(); } - virtual const std::string& GetUserAgent( - const GURL& /* url */) const OVERRIDE { - return user_agent_; - } - protected: virtual ~BasicURLRequestContext() {} private: - std::string user_agent_; base::Thread cache_thread_; base::Thread file_thread_; URLRequestContextStorage storage_; @@ -203,7 +195,8 @@ URLRequestContext* URLRequestContextBuilder::Build() { BasicURLRequestContext* context = new BasicURLRequestContext; URLRequestContextStorage* storage = context->storage(); - context->set_user_agent(user_agent_); + storage->set_http_user_agent_settings(new StaticHttpUserAgentSettings( + accept_language_, accept_charset_, user_agent_)); if (!network_delegate_) network_delegate_.reset(new BasicNetworkDelegate); diff --git a/net/url_request/url_request_context_builder.h b/net/url_request/url_request_context_builder.h index 66c8e7a..fd21f8a6 100644 --- a/net/url_request/url_request_context_builder.h +++ b/net/url_request/url_request_context_builder.h @@ -72,8 +72,15 @@ class NET_EXPORT URLRequestContextBuilder { void set_proxy_config_service(ProxyConfigService* proxy_config_service); #endif // defined(OS_LINUX) || defined(OS_ANDROID) - // Call this function to specify a hard-coded User-Agent for all requests that - // don't have a User-Agent already set. + // Call these functions to specify hard-coded Accept-Language, + // Accept-Charset, or User-Agent header values for all requests that don't + // have the headers already set. + 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_user_agent(const std::string& user_agent) { user_agent_ = user_agent; } @@ -108,6 +115,8 @@ class NET_EXPORT URLRequestContextBuilder { URLRequestContext* Build(); private: + std::string accept_language_; + std::string accept_charset_; std::string user_agent_; bool ftp_enabled_; bool http_cache_enabled_; diff --git a/net/url_request/url_request_context_storage.cc b/net/url_request/url_request_context_storage.cc index 12ea031..cc57078 100644 --- a/net/url_request/url_request_context_storage.cc +++ b/net/url_request/url_request_context_storage.cc @@ -17,6 +17,7 @@ #include "net/http/http_transaction_factory.h" #include "net/proxy/proxy_service.h" #include "net/url_request/fraudulent_certificate_reporter.h" +#include "net/url_request/http_user_agent_settings.h" #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_job_factory.h" #include "net/url_request/url_request_throttler_manager.h" @@ -123,4 +124,10 @@ void URLRequestContextStorage::set_throttler_manager( throttler_manager_.reset(throttler_manager); } +void URLRequestContextStorage::set_http_user_agent_settings( + HttpUserAgentSettings* http_user_agent_settings) { + context_->set_http_user_agent_settings(http_user_agent_settings); + http_user_agent_settings_.reset(http_user_agent_settings); +} + } // namespace net diff --git a/net/url_request/url_request_context_storage.h b/net/url_request/url_request_context_storage.h index bc040b2..62f4c2a 100644 --- a/net/url_request/url_request_context_storage.h +++ b/net/url_request/url_request_context_storage.h @@ -20,6 +20,7 @@ class HostResolver; class HttpAuthHandlerFactory; class HttpServerProperties; class HttpTransactionFactory; +class HttpUserAgentSettings; class NetLog; class NetworkDelegate; class ServerBoundCertService; @@ -65,6 +66,8 @@ class NET_EXPORT URLRequestContextStorage { FtpTransactionFactory* ftp_transaction_factory); void set_job_factory(URLRequestJobFactory* job_factory); void set_throttler_manager(URLRequestThrottlerManager* throttler_manager); + void set_http_user_agent_settings( + HttpUserAgentSettings* http_user_agent_settings); private: // We use a raw pointer to prevent reference cycles, since @@ -84,6 +87,7 @@ class NET_EXPORT URLRequestContextStorage { scoped_refptr<SSLConfigService> ssl_config_service_; scoped_ptr<NetworkDelegate> network_delegate_; scoped_ptr<HttpServerProperties> http_server_properties_; + scoped_ptr<HttpUserAgentSettings> http_user_agent_settings_; scoped_refptr<CookieStore> cookie_store_; scoped_ptr<TransportSecurityState> transport_security_state_; diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc index c65c33a..c011b436 100644 --- a/net/url_request/url_request_http_job.cc +++ b/net/url_request/url_request_http_job.cc @@ -39,6 +39,7 @@ #include "net/http/http_transaction_factory.h" #include "net/http/http_util.h" #include "net/url_request/fraudulent_certificate_reporter.h" +#include "net/url_request/http_user_agent_settings.h" #include "net/url_request/url_request.h" #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_error_job.h" @@ -211,12 +212,16 @@ URLRequestJob* URLRequestHttpJob::Factory(URLRequest* request, GURL redirect_url; if (request->GetHSTSRedirect(&redirect_url)) return new URLRequestRedirectJob(request, network_delegate, redirect_url); - return new URLRequestHttpJob(request, network_delegate); + return new URLRequestHttpJob(request, + network_delegate, + request->context()->http_user_agent_settings()); } -URLRequestHttpJob::URLRequestHttpJob(URLRequest* request, - NetworkDelegate* network_delegate) +URLRequestHttpJob::URLRequestHttpJob( + URLRequest* request, + NetworkDelegate* network_delegate, + const HttpUserAgentSettings* http_user_agent_settings) : URLRequestJob(request, network_delegate), response_info_(NULL), response_cookies_save_index_(0), @@ -248,7 +253,8 @@ URLRequestHttpJob::URLRequestHttpJob(URLRequest* request, base::Bind(&URLRequestHttpJob::OnHeadersReceivedCallback, base::Unretained(this)))), awaiting_callback_(false), - http_transaction_delegate_(new HttpTransactionDelegateImpl(request)) { + http_transaction_delegate_(new HttpTransactionDelegateImpl(request)), + http_user_agent_settings_(http_user_agent_settings) { URLRequestThrottlerManager* manager = request->context()->throttler_manager(); if (manager) throttling_entry_ = manager->RegisterRequestUrl(request->url()); @@ -471,18 +477,22 @@ void URLRequestHttpJob::AddExtraHeaders() { } } - const URLRequestContext* context = request_->context(); - // Only add default Accept-Language and Accept-Charset if the request - // didn't have them specified. - if (!context->accept_language().empty()) { - request_info_.extra_headers.SetHeaderIfMissing( - HttpRequestHeaders::kAcceptLanguage, - context->accept_language()); - } - if (!context->accept_charset().empty()) { - request_info_.extra_headers.SetHeaderIfMissing( - HttpRequestHeaders::kAcceptCharset, - context->accept_charset()); + if (http_user_agent_settings_) { + // Only add default Accept-Language and Accept-Charset if the request + // didn't have them specified. + std::string accept_language = + http_user_agent_settings_->GetAcceptLanguage(); + if (!accept_language.empty()) { + request_info_.extra_headers.SetHeaderIfMissing( + HttpRequestHeaders::kAcceptLanguage, + accept_language); + } + std::string accept_charset = http_user_agent_settings_->GetAcceptCharset(); + if (!accept_charset.empty()) { + request_info_.extra_headers.SetHeaderIfMissing( + HttpRequestHeaders::kAcceptCharset, + accept_charset); + } } } @@ -921,7 +931,9 @@ void URLRequestHttpJob::Start() { request_info_.extra_headers.SetHeaderIfMissing( HttpRequestHeaders::kUserAgent, - request_->context()->GetUserAgent(request_->url())); + http_user_agent_settings_ ? + http_user_agent_settings_->GetUserAgent(request_->url()) : + EmptyString()); AddExtraHeaders(); AddCookieHeaderAndStart(); diff --git a/net/url_request/url_request_http_job.h b/net/url_request/url_request_http_job.h index 3457166..ebfbe89 100644 --- a/net/url_request/url_request_http_job.h +++ b/net/url_request/url_request_http_job.h @@ -24,6 +24,7 @@ namespace net { class HttpResponseHeaders; class HttpResponseInfo; class HttpTransaction; +class HttpUserAgentSettings; class URLRequestContext; // A URLRequestJob subclass that is built on top of HttpTransaction. It @@ -35,7 +36,9 @@ class URLRequestHttpJob : public URLRequestJob { const std::string& scheme); protected: - URLRequestHttpJob(URLRequest* request, NetworkDelegate* network_delegate); + URLRequestHttpJob(URLRequest* request, + NetworkDelegate* network_delegate, + const HttpUserAgentSettings* http_user_agent_settings); // Shadows URLRequestJob's version of this method so we can grab cookies. void NotifyHeadersComplete(); @@ -244,6 +247,8 @@ class URLRequestHttpJob : public URLRequestJob { scoped_ptr<HttpTransactionDelegateImpl> http_transaction_delegate_; + const HttpUserAgentSettings* http_user_agent_settings_; + DISALLOW_COPY_AND_ASSIGN(URLRequestHttpJob); }; diff --git a/net/url_request/url_request_test_util.cc b/net/url_request/url_request_test_util.cc index ae7d527..34335ae 100644 --- a/net/url_request/url_request_test_util.cc +++ b/net/url_request/url_request_test_util.cc @@ -16,6 +16,7 @@ #include "net/base/server_bound_cert_service.h" #include "net/http/http_network_session.h" #include "net/http/http_server_properties_impl.h" +#include "net/url_request/static_http_user_agent_settings.h" #include "net/url_request/url_request_job_factory_impl.h" #include "testing/gtest/include/gtest/gtest.h" @@ -113,10 +114,11 @@ void TestURLRequestContext::Init() { new net::DefaultServerBoundCertStore(NULL), base::WorkerPool::GetTaskRunner(true))); } - if (accept_language().empty()) - set_accept_language("en-us,fr"); - if (accept_charset().empty()) - set_accept_charset("iso-8859-1,*,utf-8"); + if (!http_user_agent_settings()) { + context_storage_.set_http_user_agent_settings( + new net::StaticHttpUserAgentSettings( + "en-us,fr", "iso-8859-1,*,utf-8", EmptyString())); + } if (!job_factory()) context_storage_.set_job_factory(new net::URLRequestJobFactoryImpl); } diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc index 181c509..2bf7f24 100644 --- a/net/url_request/url_request_unittest.cc +++ b/net/url_request/url_request_unittest.cc @@ -54,6 +54,7 @@ #include "net/socket/ssl_client_socket.h" #include "net/test/test_server.h" #include "net/url_request/ftp_protocol_handler.h" +#include "net/url_request/static_http_user_agent_settings.h" #include "net/url_request/url_request.h" #include "net/url_request/url_request_file_dir_job.h" #include "net/url_request/url_request_http_job.h" @@ -3668,10 +3669,11 @@ TEST_F(URLRequestTestHTTP, InterceptPost307RedirectPost) { TEST_F(URLRequestTestHTTP, DefaultAcceptLanguage) { ASSERT_TRUE(test_server_.Start()); + StaticHttpUserAgentSettings settings("en", EmptyString(), EmptyString()); TestNetworkDelegate network_delegate; // must outlive URLRequests TestURLRequestContext context(true); context.set_network_delegate(&network_delegate); - context.set_accept_language("en"); + context.set_http_user_agent_settings(&settings); context.Init(); TestDelegate d; @@ -3686,13 +3688,15 @@ TEST_F(URLRequestTestHTTP, DefaultAcceptLanguage) { TEST_F(URLRequestTestHTTP, EmptyAcceptLanguage) { ASSERT_TRUE(test_server_.Start()); + StaticHttpUserAgentSettings settings( + EmptyString(), EmptyString(), EmptyString()); TestNetworkDelegate network_delegate; // must outlive URLRequests TestURLRequestContext context(true); context.set_network_delegate(&network_delegate); context.Init(); // We override the language after initialization because empty entries // get overridden by Init(). - context.set_accept_language(""); + context.set_http_user_agent_settings(&settings); TestDelegate d; URLRequest req( @@ -3756,10 +3760,11 @@ TEST_F(URLRequestTestHTTP, OverrideAcceptEncoding) { TEST_F(URLRequestTestHTTP, DefaultAcceptCharset) { ASSERT_TRUE(test_server_.Start()); + StaticHttpUserAgentSettings settings(EmptyString(), "en", EmptyString()); TestNetworkDelegate network_delegate; // must outlive URLRequests TestURLRequestContext context(true); context.set_network_delegate(&network_delegate); - context.set_accept_charset("en"); + context.set_http_user_agent_settings(&settings); context.Init(); TestDelegate d; @@ -3775,13 +3780,15 @@ TEST_F(URLRequestTestHTTP, DefaultAcceptCharset) { TEST_F(URLRequestTestHTTP, EmptyAcceptCharset) { ASSERT_TRUE(test_server_.Start()); + StaticHttpUserAgentSettings settings( + EmptyString(), EmptyString(), EmptyString()); TestNetworkDelegate network_delegate; // must outlive URLRequests TestURLRequestContext context(true); context.set_network_delegate(&network_delegate); context.Init(); // We override the accepted charset after initialization because empty // entries get overridden otherwise. - context.set_accept_charset(""); + context.set_http_user_agent_settings(&settings); TestDelegate d; URLRequest req(test_server_.GetURL("echoheader?Accept-Charset"), @@ -3842,6 +3849,37 @@ TEST_F(URLRequestTestHTTP, OverrideUserAgent) { EXPECT_TRUE(StartsWithASCII(d.data_received(), "Lynx (textmode", true)); } +// Check that a NULL HttpUserAgentSettings causes the corresponding empty +// User-Agent header to be sent but does not send the Accept-Language and +// Accept-Charset headers. +TEST_F(URLRequestTestHTTP, EmptyHttpUserAgentSettings) { + ASSERT_TRUE(test_server_.Start()); + + TestNetworkDelegate network_delegate; // must outlive URLRequests + TestURLRequestContext context(true); + context.set_network_delegate(&network_delegate); + context.Init(); + // We override the HttpUserAgentSettings after initialization because empty + // entries get overridden by Init(). + context.set_http_user_agent_settings(NULL); + + struct { + const char* request; + const char* expected_response; + } tests[] = { { "echoheader?Accept-Language", "None" }, + { "echoheader?Accept-Charset", "None" }, + { "echoheader?User-Agent", "" } }; + + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); i++) { + TestDelegate d; + URLRequest req(test_server_.GetURL(tests[i].request), &d, &context); + req.Start(); + MessageLoop::current()->Run(); + EXPECT_EQ(tests[i].expected_response, d.data_received()) + << " Request = \"" << tests[i].request << "\""; + } +} + class HTTPSRequestTest : public testing::Test { public: HTTPSRequestTest() : default_context_(true) { diff --git a/sync/internal_api/http_bridge.cc b/sync/internal_api/http_bridge.cc index 96e1a58..5b38233 100644 --- a/sync/internal_api/http_bridge.cc +++ b/sync/internal_api/http_bridge.cc @@ -15,6 +15,7 @@ #include "net/http/http_network_layer.h" #include "net/http/http_response_headers.h" #include "net/proxy/proxy_service.h" +#include "net/url_request/static_http_user_agent_settings.h" #include "net/url_request/url_fetcher.h" #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_status.h" @@ -81,9 +82,8 @@ HttpBridge::RequestContext::RequestContext( network_task_runner, const std::string& user_agent) : baseline_context_(baseline_context), - network_task_runner_(network_task_runner), - user_agent_(user_agent) { - DCHECK(!user_agent_.empty()); + network_task_runner_(network_task_runner) { + DCHECK(!user_agent.empty()); // Create empty, in-memory cookie store. set_cookie_store(new net::CookieMonster(NULL, NULL)); @@ -109,8 +109,11 @@ HttpBridge::RequestContext::RequestContext( // should be tied to whatever the sync servers expect (if anything). These // fields should probably just be settable by sync backend; though we should // figure out if we need to give the user explicit control over policies etc. - set_accept_language(baseline_context->accept_language()); - set_accept_charset(baseline_context->accept_charset()); + http_user_agent_settings_.reset(new net::StaticHttpUserAgentSettings( + baseline_context->GetAcceptLanguage(), + baseline_context->GetAcceptCharset(), + user_agent)); + set_http_user_agent_settings(http_user_agent_settings_.get()); set_net_log(baseline_context->net_log()); } @@ -120,11 +123,6 @@ HttpBridge::RequestContext::~RequestContext() { delete http_transaction_factory(); } -const std::string& HttpBridge::RequestContext::GetUserAgent( - const GURL& url) const { - return user_agent_; -} - HttpBridge::URLFetchState::URLFetchState() : url_poster(NULL), aborted(false), request_completed(false), diff --git a/sync/internal_api/public/http_bridge.h b/sync/internal_api/public/http_bridge.h index 15001c2..40cf6e7 100644 --- a/sync/internal_api/public/http_bridge.h +++ b/sync/internal_api/public/http_bridge.h @@ -25,6 +25,7 @@ class HttpBridgeTest; namespace net { class HttpResponseHeaders; +class HttpUserAgentSettings; class URLFetcher; } @@ -58,12 +59,10 @@ class HttpBridge : public base::RefCountedThreadSafe<HttpBridge>, // The destructor MUST be called on the IO thread. virtual ~RequestContext(); - virtual const std::string& GetUserAgent(const GURL& url) const OVERRIDE; - private: net::URLRequestContext* const baseline_context_; const scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_; - const std::string user_agent_; + scoped_ptr<net::HttpUserAgentSettings> http_user_agent_settings_; DISALLOW_COPY_AND_ASSIGN(RequestContext); }; diff --git a/webkit/tools/test_shell/test_shell_request_context.cc b/webkit/tools/test_shell/test_shell_request_context.cc index 0ab9839..d15ea12 100644 --- a/webkit/tools/test_shell/test_shell_request_context.cc +++ b/webkit/tools/test_shell/test_shell_request_context.cc @@ -23,6 +23,7 @@ #include "net/proxy/proxy_config_service.h" #include "net/proxy/proxy_config_service_fixed.h" #include "net/proxy/proxy_service.h" +#include "net/url_request/http_user_agent_settings.h" #include "net/url_request/url_request_job_factory_impl.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebKit.h" #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebKitPlatformSupport.h" @@ -34,6 +35,27 @@ #include "webkit/tools/test_shell/simple_resource_loader_bridge.h" #include "webkit/user_agent/user_agent.h" +class TestShellHttpUserAgentSettings : public net::HttpUserAgentSettings { + public: + TestShellHttpUserAgentSettings() {} + virtual ~TestShellHttpUserAgentSettings() {} + + // hard-code A-L and A-C for test shells + virtual std::string GetAcceptLanguage() const OVERRIDE { + return "en-us,en"; + } + virtual std::string GetAcceptCharset() const OVERRIDE { + return "iso-8859-1,*,utf-8"; + } + + virtual std::string GetUserAgent(const GURL& url) const OVERRIDE { + return webkit_glue::GetUserAgent(url); + } + + private: + DISALLOW_COPY_AND_ASSIGN(TestShellHttpUserAgentSettings); +}; + TestShellRequestContext::TestShellRequestContext() : ALLOW_THIS_IN_INITIALIZER_LIST(storage_(this)) { Init(FilePath(), net::HttpCache::NORMAL, false); @@ -56,9 +78,7 @@ void TestShellRequestContext::Init( new net::DefaultServerBoundCertStore(NULL), base::WorkerPool::GetTaskRunner(true))); - // hard-code A-L and A-C for test shells - set_accept_language("en-us,en"); - set_accept_charset("iso-8859-1,*,utf-8"); + storage_.set_http_user_agent_settings(new TestShellHttpUserAgentSettings); #if defined(OS_POSIX) && !defined(OS_MACOSX) // Use no proxy to avoid ProxyConfigServiceLinux. @@ -132,8 +152,3 @@ void TestShellRequestContext::Init( TestShellRequestContext::~TestShellRequestContext() { } - -const std::string& TestShellRequestContext::GetUserAgent( - const GURL& url) const { - return webkit_glue::GetUserAgent(url); -} diff --git a/webkit/tools/test_shell/test_shell_request_context.h b/webkit/tools/test_shell/test_shell_request_context.h index 946248f..27ef6fe 100644 --- a/webkit/tools/test_shell/test_shell_request_context.h +++ b/webkit/tools/test_shell/test_shell_request_context.h @@ -34,8 +34,6 @@ class TestShellRequestContext : public net::URLRequestContext { virtual ~TestShellRequestContext(); - virtual const std::string& GetUserAgent(const GURL& url) const OVERRIDE; - webkit_blob::BlobStorageController* blob_storage_controller() const { return blob_storage_controller_.get(); } |