diff options
author | dfalcantara@chromium.org <dfalcantara@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-08-28 23:25:58 +0000 |
---|---|---|
committer | dfalcantara@chromium.org <dfalcantara@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-08-28 23:25:58 +0000 |
commit | 3e807c44d68c58cf8ea60884fe5c5fae60dbbc7d (patch) | |
tree | bd8f98cf515645a36cbf69157ecb08e7182405da | |
parent | 1562344da803bfee522b0a8d12c942ea51094fd4 (diff) | |
download | chromium_src-3e807c44d68c58cf8ea60884fe5c5fae60dbbc7d.zip chromium_src-3e807c44d68c58cf8ea60884fe5c5fae60dbbc7d.tar.gz chromium_src-3e807c44d68c58cf8ea60884fe5c5fae60dbbc7d.tar.bz2 |
Allow the creation of partially spoofed user agents
Refactors user agent generation so that we can create partially spoofed user
agents for other platforms.
BUG=128570
Review URL: https://chromiumcodereview.appspot.com/10854251
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@153783 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/chrome_tests.gypi | 1 | ||||
-rw-r--r-- | chrome/common/chrome_content_client.cc | 10 | ||||
-rw-r--r-- | chrome/common/chrome_content_client.h | 1 | ||||
-rw-r--r-- | chrome/common/chrome_content_client_unittest.cc | 82 | ||||
-rw-r--r-- | content/browser/android/content_view_core_impl.cc | 12 | ||||
-rw-r--r-- | content/public/common/content_client.cc | 4 | ||||
-rw-r--r-- | content/public/common/content_client.h | 4 | ||||
-rw-r--r-- | webkit/glue/user_agent.cc | 18 | ||||
-rw-r--r-- | webkit/glue/user_agent.h | 5 |
9 files changed, 127 insertions, 10 deletions
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index e0952f0..9049ea9 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -1920,6 +1920,7 @@ 'common/child_process_logging_mac_unittest.mm', 'common/chrome_paths_unittest.cc', 'common/common_param_traits_unittest.cc', + 'common/chrome_content_client_unittest.cc', 'common/content_settings_helper_unittest.cc', 'common/content_settings_pattern_parser_unittest.cc', 'common/content_settings_pattern_unittest.cc', diff --git a/chrome/common/chrome_content_client.cc b/chrome/common/chrome_content_client.cc index 1828652..1142b19 100644 --- a/chrome/common/chrome_content_client.cc +++ b/chrome/common/chrome_content_client.cc @@ -430,15 +430,19 @@ bool ChromeContentClient::CanHandleWhileSwappedOut( return false; } -std::string ChromeContentClient::GetUserAgent() const { +std::string ChromeContentClient::GetProduct() const { chrome::VersionInfo version_info; std::string product("Chrome/"); product += version_info.is_valid() ? version_info.Version() : "0.0.0.0"; + return product; +} + +std::string ChromeContentClient::GetUserAgent() const { + std::string product = GetProduct(); #if defined(OS_ANDROID) CommandLine* command_line = CommandLine::ForCurrentProcess(); - if (command_line->HasSwitch(switches::kUseMobileUserAgent)) { + if (command_line->HasSwitch(switches::kUseMobileUserAgent)) product += " Mobile"; - } #endif return webkit_glue::BuildUserAgentFromProduct(product); } diff --git a/chrome/common/chrome_content_client.h b/chrome/common/chrome_content_client.h index 63648d6..c8763acb78 100644 --- a/chrome/common/chrome_content_client.h +++ b/chrome/common/chrome_content_client.h @@ -30,6 +30,7 @@ class ChromeContentClient : public content::ContentClient { std::vector<std::string>* saveable_shemes) OVERRIDE; virtual bool HasWebUIScheme(const GURL& url) const OVERRIDE; virtual bool CanHandleWhileSwappedOut(const IPC::Message& msg) OVERRIDE; + virtual std::string GetProduct() const OVERRIDE; virtual std::string GetUserAgent() const OVERRIDE; virtual string16 GetLocalizedString(int message_id) const OVERRIDE; virtual base::StringPiece GetDataResource( diff --git a/chrome/common/chrome_content_client_unittest.cc b/chrome/common/chrome_content_client_unittest.cc new file mode 100644 index 0000000..67f4d6e --- /dev/null +++ b/chrome/common/chrome_content_client_unittest.cc @@ -0,0 +1,82 @@ +// 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/common/chrome_content_client.h" + +#include "base/command_line.h" +#include "base/string_split.h" +#include "content/public/common/content_switches.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +void CheckUserAgentStringOrdering(bool mobile_device) { + std::vector<std::string> pieces; + + // Check if the pieces of the user agent string come in the correct order. + chrome::ChromeContentClient content_client; + std::string buffer = content_client.GetUserAgent(); + + base::SplitStringUsingSubstr(buffer, "Mozilla/5.0 (", &pieces); + ASSERT_EQ(2u, pieces.size()); + buffer = pieces[1]; + EXPECT_EQ("", pieces[0]); + + base::SplitStringUsingSubstr(buffer, ") AppleWebKit/", &pieces); + ASSERT_EQ(2u, pieces.size()); + buffer = pieces[1]; + std::string os_str = pieces[0]; + + base::SplitStringUsingSubstr(buffer, " (KHTML, like Gecko) ", &pieces); + ASSERT_EQ(2u, pieces.size()); + buffer = pieces[1]; + std::string webkit_version_str = pieces[0]; + + base::SplitStringUsingSubstr(buffer, " Safari/", &pieces); + ASSERT_EQ(2u, pieces.size()); + std::string product_str = pieces[0]; + std::string safari_version_str = pieces[1]; + + // Not sure what can be done to better check the OS string, since it's highly + // platform-dependent. + EXPECT_TRUE(os_str.size() > 0); + + // Check that the version numbers match. + EXPECT_TRUE(webkit_version_str.size() > 0); + EXPECT_TRUE(safari_version_str.size() > 0); + EXPECT_EQ(webkit_version_str, safari_version_str); + + EXPECT_EQ(0u, product_str.find("Chrome/")); + if (mobile_device) { + // "Mobile" gets tacked on to the end for mobile devices, like phones. + const std::string kMobileStr = " Mobile"; + EXPECT_EQ(kMobileStr, + product_str.substr(product_str.size() - kMobileStr.size())); + } +} + +} // namespace + + +namespace chrome_common { + +TEST(ChromeContentClientTest, Basic) { +#if !defined(OS_ANDROID) + CheckUserAgentStringOrdering(false); +#else + // Do it once for mobile devices and once for other devices. + const char* kArguments[] = {"chrome"}; + CommandLine* command_line = CommandLine::ForCurrentProcess(); + command_line->Reset(); + command_line->Init(1, kArguments); + ASSERT_FALSE(command_line->HasSwitch(switches::kUseMobileUserAgent)); + CheckUserAgentStringOrdering(false); + + command_line->AppendSwitch(switches::kUseMobileUserAgent); + ASSERT_TRUE(command_line->HasSwitch(switches::kUseMobileUserAgent)); + CheckUserAgentStringOrdering(true); +#endif +} + +} // namespace chrome_common diff --git a/content/browser/android/content_view_core_impl.cc b/content/browser/android/content_view_core_impl.cc index 6db73e83..65bc98c 100644 --- a/content/browser/android/content_view_core_impl.cc +++ b/content/browser/android/content_view_core_impl.cc @@ -27,12 +27,14 @@ #include "content/public/browser/notification_source.h" #include "content/public/browser/notification_types.h" #include "content/public/browser/web_contents.h" +#include "content/public/common/content_client.h" #include "content/public/common/page_transition_types.h" #include "jni/ContentViewCore_jni.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebBindings.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h" #include "third_party/WebKit/Source/WebKit/chromium/public/android/WebInputEventFactory.h" #include "ui/gfx/android/java_bitmap.h" +#include "webkit/glue/user_agent.h" #include "webkit/glue/webmenuitem.h" using base::android::AttachCurrentThread; @@ -95,6 +97,16 @@ ContentViewCoreImpl::ContentViewCoreImpl(JNIEnv* env, jobject obj, notification_registrar_.Add(this, NOTIFICATION_EXECUTE_JAVASCRIPT_RESULT, NotificationService::AllSources()); + + // Currently, the only use case we have for overriding a user agent involves + // spoofing a desktop Linux user agent for "Request desktop site". + // Automatically set it for all WebContents so that it is available when a + // NavigationEntry requires the user agent to be overridden. + const char kLinuxInfoStr[] = "X11; Linux x86_64"; + std::string product = content::GetContentClient()->GetProduct(); + std::string spoofed_ua = + webkit_glue::BuildUserAgentFromOSAndProduct(kLinuxInfoStr, product); + web_contents->SetUserAgentOverride(spoofed_ua); } ContentViewCoreImpl::~ContentViewCoreImpl() { diff --git a/content/public/common/content_client.cc b/content/public/common/content_client.cc index 5f8f2bb..e71241c 100644 --- a/content/public/common/content_client.cc +++ b/content/public/common/content_client.cc @@ -53,6 +53,10 @@ bool ContentClient::CanHandleWhileSwappedOut(const IPC::Message& message) { return false; } +std::string ContentClient::GetProduct() const { + return std::string(); +} + std::string ContentClient::GetUserAgent() const { return std::string(); } diff --git a/content/public/common/content_client.h b/content/public/common/content_client.h index a1850ff..745a721 100644 --- a/content/public/common/content_client.h +++ b/content/public/common/content_client.h @@ -108,6 +108,10 @@ class CONTENT_EXPORT ContentClient { // behalf of a swapped out renderer. virtual bool CanHandleWhileSwappedOut(const IPC::Message& message); + // Returns a string describing the embedder version. Used as part of the + // user agent string. + virtual std::string GetProduct() const; + // Returns the user agent. virtual std::string GetUserAgent() const; diff --git a/webkit/glue/user_agent.cc b/webkit/glue/user_agent.cc index bfd1ff4..cc03719 100644 --- a/webkit/glue/user_agent.cc +++ b/webkit/glue/user_agent.cc @@ -155,18 +155,22 @@ std::string BuildUserAgentFromProduct(const std::string& product) { "Unknown; "; #endif - std::string user_agent; + std::string os_info; + base::StringAppendF(&os_info, "%s%s", kUserAgentPlatform, + webkit_glue::BuildOSCpuInfo().c_str()); + return BuildUserAgentFromOSAndProduct(os_info, product); +} +std::string BuildUserAgentFromOSAndProduct(const std::string& os_info, + const std::string& product) { + // Derived from Safari's UA string. // This is done to expose our product name in a manner that is maximally // compatible with Safari, we hope!! - - // Derived from Safari's UA string. + std::string user_agent; base::StringAppendF( &user_agent, - "Mozilla/5.0 (%s%s) AppleWebKit/%d.%d" - " (KHTML, like Gecko) %s Safari/%d.%d", - kUserAgentPlatform, - webkit_glue::BuildOSCpuInfo().c_str(), + "Mozilla/5.0 (%s) AppleWebKit/%d.%d (KHTML, like Gecko) %s Safari/%d.%d", + os_info.c_str(), WEBKIT_VERSION_MAJOR, WEBKIT_VERSION_MINOR, product.c_str(), diff --git a/webkit/glue/user_agent.h b/webkit/glue/user_agent.h index 5d2594a..c82571f 100644 --- a/webkit/glue/user_agent.h +++ b/webkit/glue/user_agent.h @@ -25,6 +25,11 @@ int GetWebKitMinorVersion(); // product name. std::string BuildUserAgentFromProduct(const std::string& product); +// Builds a full user agent string given a string describing the OS and a +// product name. +std::string BuildUserAgentFromOSAndProduct(const std::string& os_info, + const std::string& product); + } // namespace webkit_glue #endif // WEBKIT_GLUE_USER_AGENT_H_ |