Commit adab7955 authored by kov@webkit.org's avatar kov@webkit.org

[GTK] Google Calendar thinks we're mobile

https://bugs.webkit.org/show_bug.cgi?id=63994

Patch by Gustavo Noronha Silva  <gns@gnome.org> on 2011-07-11
Reviewed by Xan Lopez.

Further special-case Google Calendar, for it thinks WebKit+Linux
means mobile, so we also have to spoof the OS.

* WebCoreSupport/FrameLoaderClientGtk.cpp:
(WebKit::FrameLoaderClient::userAgent): use the new WebKitGTK+
private API that centralizes the logic now.
* tests/testwebsettings.c: Add tests to make sure the Google
special-cases only apply for the expected domains and when quirks
special-casing is enabled.
(test_non_quirky_user_agents):
(test_webkit_web_settings_user_agent):
* webkit/webkitwebsettings.cpp:
(webkitUserAgent): make it static.
(safariUserAgent): returns a fake Safari in Mac OS X User-Agent.
(initializeDomainsList): moved from FrameLoaderClientGtk.
(isGoogleDomain):ditto.
(isGoogleCalendar): ditto.
(userAgentForURL): ditto.
(webkitWebSettingsUserAgentForUri): centralize the whole
user agent spoofing logic in this new private API that can be used
by the browser to know what's going to happen for a specific URI
and also allows our API testing.
* webkit/webkitwebsettingsprivate.h:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@91253 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 273992bc
2011-07-11 Gustavo Noronha Silva <gns@gnome.org>
[GTK] Google Calendar thinks we're mobile
https://bugs.webkit.org/show_bug.cgi?id=63994
Reviewed by Xan Lopez.
Further special-case Google Calendar, for it thinks WebKit+Linux
means mobile, so we also have to spoof the OS.
* WebCoreSupport/FrameLoaderClientGtk.cpp:
(WebKit::FrameLoaderClient::userAgent): use the new WebKitGTK+
private API that centralizes the logic now.
* tests/testwebsettings.c: Add tests to make sure the Google
special-cases only apply for the expected domains and when quirks
special-casing is enabled.
(test_non_quirky_user_agents):
(test_webkit_web_settings_user_agent):
* webkit/webkitwebsettings.cpp:
(webkitUserAgent): make it static.
(safariUserAgent): returns a fake Safari in Mac OS X User-Agent.
(initializeDomainsList): moved from FrameLoaderClientGtk.
(isGoogleDomain):ditto.
(isGoogleCalendar): ditto.
(userAgentForURL): ditto.
(webkitWebSettingsUserAgentForUri): centralize the whole
user agent spoofing logic in this new private API that can be used
by the browser to know what's going to happen for a specific URI
and also allows our API testing.
* webkit/webkitwebsettingsprivate.h:
2011-07-15 Dan Bernstein <mitz@apple.com>
REGRESSION: Mouse cursor doesn’t hide when full screen video HUD hides
......
......@@ -114,117 +114,12 @@ FrameLoaderClient::~FrameLoaderClient()
g_object_unref(m_policyDecision);
}
static void initializeDomainsList(HashSet<String>& googleDomains)
{
// Google search domains.
googleDomains.add("biz");
googleDomains.add("com");
googleDomains.add("net");
googleDomains.add("org");
googleDomains.add("ae");
googleDomains.add("ag");
googleDomains.add("am");
googleDomains.add("at");
googleDomains.add("az");
googleDomains.add("be");
googleDomains.add("bi");
googleDomains.add("ca");
googleDomains.add("cc");
googleDomains.add("cd");
googleDomains.add("cg");
googleDomains.add("ch");
googleDomains.add("cl");
googleDomains.add("com.br");
googleDomains.add("co.uk");
googleDomains.add("co.kr");
googleDomains.add("co.jp");
googleDomains.add("de");
googleDomains.add("dj");
googleDomains.add("dk");
googleDomains.add("es");
googleDomains.add("fi");
googleDomains.add("fm");
googleDomains.add("fr");
googleDomains.add("gg");
googleDomains.add("gl");
googleDomains.add("gm");
googleDomains.add("gs");
googleDomains.add("hn");
googleDomains.add("hu");
googleDomains.add("ie");
googleDomains.add("it");
googleDomains.add("je");
googleDomains.add("kz");
googleDomains.add("li");
googleDomains.add("lt");
googleDomains.add("lu");
googleDomains.add("lv");
googleDomains.add("ma");
googleDomains.add("ms");
googleDomains.add("mu");
googleDomains.add("mw");
googleDomains.add("nl");
googleDomains.add("no");
googleDomains.add("nu");
googleDomains.add("pl");
googleDomains.add("pn");
googleDomains.add("pt");
googleDomains.add("ru");
googleDomains.add("rw");
googleDomains.add("sh");
googleDomains.add("sk");
googleDomains.add("sm");
googleDomains.add("st");
googleDomains.add("td");
googleDomains.add("tk");
googleDomains.add("tp");
googleDomains.add("tv");
googleDomains.add("us");
googleDomains.add("uz");
googleDomains.add("ws");
}
static bool isGoogleDomain(String host)
{
DEFINE_STATIC_LOCAL(HashSet<String>, googleDomains, ());
DEFINE_STATIC_LOCAL(Vector<String>, otherGoogleDomains, ());
if (googleDomains.isEmpty()) {
otherGoogleDomains.append("gmail.com");
otherGoogleDomains.append("youtube.com");
otherGoogleDomains.append("gstatic.com");
otherGoogleDomains.append("ytimg.com");
initializeDomainsList(googleDomains);
}
// First check if this is one of the various google.com international domains.
int position = host.find(".google.");
if (position > 0 && googleDomains.contains(host.substring(position + sizeof(".google."))))
return true;
// Then we check the possibility of it being one of the other, .com-only google domains.
for (unsigned int i = 0; i < otherGoogleDomains.size(); i++) {
if (host.endsWith(otherGoogleDomains.at(i)))
return true;
}
return false;
}
String FrameLoaderClient::userAgent(const KURL& url)
{
WebKitWebSettings* settings = webkit_web_view_get_settings(getViewFromFrame(m_frame));
gboolean useQuirks;
g_object_get(settings, "enable-site-specific-quirks", &useQuirks, NULL);
// For Google domains, drop the browser's custom User Agent string, and use the standard
// WebKit/Safari one, so they don't give us a broken experience.
if (useQuirks && isGoogleDomain(url.host()))
return webkitUserAgent();
return String::fromUTF8(webkit_web_settings_get_user_agent(settings));
GOwnPtr<gchar> userAgentString(webkitWebSettingsUserAgentForURI(settings, url.string().utf8().data()));
return String::fromUTF8(userAgentString.get());
}
static void notifyAccessibilityStatus(WebKitWebFrame* frame, WebKitLoadStatus loadStatus)
......
......@@ -23,9 +23,12 @@
#if GTK_CHECK_VERSION(2, 14, 0)
/* Private API */
char* webkitWebSettingsUserAgentForURI(WebKitWebSettings *settings, const char *uri);
static void test_webkit_web_settings_copy(void)
{
WebKitWebSettings* settings = webkit_web_settings_new();
WebKitWebSettings *settings = webkit_web_settings_new();
// Set some non-default settings to verify that settings are properly copied.
g_object_set(settings,
......@@ -34,12 +37,12 @@ static void test_webkit_web_settings_copy(void)
"auto-load-images", FALSE,
"default-encoding", "utf-8", NULL);
WebKitWebSettings* copy = webkit_web_settings_copy(settings);
WebKitWebSettings *copy = webkit_web_settings_copy(settings);
gboolean enableWebGL = FALSE;
gboolean enableFullscreen = FALSE;
gboolean autoLoadImages = FALSE;
char* defaultEncoding = NULL;
char *defaultEncoding = 0;
g_object_get(copy,
"enable-fullscreen", &enableFullscreen,
"enable-webgl", &enableWebGL,
......@@ -53,12 +56,37 @@ static void test_webkit_web_settings_copy(void)
g_free(defaultEncoding);
}
static void test_non_quirky_user_agents(WebKitWebSettings *settings, const char *defaultUserAgent)
{
char *userAgent = 0;
// test a custom UA string
userAgent = 0;
g_object_set(settings, "user-agent", "testwebsettings/0.1", NULL);
g_object_get(settings,"user-agent", &userAgent, NULL);
g_assert_cmpstr(userAgent, ==, "testwebsettings/0.1");
g_free(userAgent);
// setting it to NULL or an empty value should give us the default UA string
userAgent = 0;
g_object_set(settings, "user-agent", 0, NULL);
g_object_get(settings,"user-agent", &userAgent, NULL);
g_assert_cmpstr(userAgent, ==, defaultUserAgent);
g_free(userAgent);
userAgent = 0;
g_object_set(settings, "user-agent", "", NULL);
g_object_get(settings,"user-agent", &userAgent, NULL);
g_assert_cmpstr(userAgent, ==, defaultUserAgent);
g_free(userAgent);
}
static void test_webkit_web_settings_user_agent(void)
{
WebKitWebSettings* settings;
GtkWidget* webView;
gchar* defaultUserAgent;
gchar* userAgent;
WebKitWebSettings *settings;
GtkWidget *webView;
char *defaultUserAgent;
char *userAgent = 0;
g_test_bug("17375");
webView = webkit_web_view_new();
......@@ -67,31 +95,59 @@ static void test_webkit_web_settings_user_agent(void)
settings = webkit_web_view_get_settings(WEBKIT_WEB_VIEW(webView));
defaultUserAgent = g_strdup(webkit_web_settings_get_user_agent(settings));
// test a custom UA string
userAgent = NULL;
g_object_set(G_OBJECT(settings), "user-agent", "testwebsettings/0.1", NULL);
g_object_get(G_OBJECT(settings),"user-agent", &userAgent, NULL);
test_non_quirky_user_agents(settings, defaultUserAgent);
/* Test quirky google domains */
g_object_set(settings, "user-agent", "testwebsettings/0.1", NULL);
userAgent = webkitWebSettingsUserAgentForURI(settings, "http://www.google.com/");
g_assert_cmpstr(userAgent, ==, "testwebsettings/0.1");
g_free(userAgent);
// setting it to NULL or an empty value should give us the default UA string
userAgent = NULL;
g_object_set(G_OBJECT(settings), "user-agent", NULL, NULL);
g_object_get(G_OBJECT(settings),"user-agent", &userAgent, NULL);
userAgent = webkitWebSettingsUserAgentForURI(settings, "http://gmail.com/");
g_assert_cmpstr(userAgent, ==, "testwebsettings/0.1");
g_free(userAgent);
userAgent = webkitWebSettingsUserAgentForURI(settings, "http://www.google.com.br/");
g_assert_cmpstr(userAgent, ==, "testwebsettings/0.1");
g_free(userAgent);
userAgent = webkitWebSettingsUserAgentForURI(settings, "http://calendar.google.com/");
g_assert_cmpstr(userAgent, ==, "testwebsettings/0.1");
g_free(userAgent);
/* Now enable quirks handling */
g_object_set(settings, "enable-site-specific-quirks", TRUE, NULL);
test_non_quirky_user_agents(settings, defaultUserAgent);
g_object_set(settings, "user-agent", "testwebsettings/0.1", NULL);
userAgent = webkitWebSettingsUserAgentForURI(settings, "http://www.google.com/");
g_assert_cmpstr(userAgent, ==, defaultUserAgent);
g_free(userAgent);
userAgent = NULL;
g_object_set(G_OBJECT(settings), "user-agent", "", NULL);
g_object_get(G_OBJECT(settings),"user-agent", &userAgent, NULL);
userAgent = webkitWebSettingsUserAgentForURI(settings, "http://gmail.com/");
g_assert_cmpstr(userAgent, ==, defaultUserAgent);
g_free(userAgent);
userAgent = webkitWebSettingsUserAgentForURI(settings, "http://www.google.com.br/");
g_assert_cmpstr(userAgent, ==, defaultUserAgent);
g_free(userAgent);
userAgent = webkitWebSettingsUserAgentForURI(settings, "http://www.google.uk.not.com.br/");
g_assert_cmpstr(userAgent, ==, "testwebsettings/0.1");
g_free(userAgent);
userAgent = webkitWebSettingsUserAgentForURI(settings, "http://calendar.google.com/");
g_assert(g_str_has_prefix(userAgent, "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; en_US) AppleWebKit/"));
g_free(userAgent);
g_free(defaultUserAgent);
g_object_unref(webView);
}
int main(int argc, char** argv)
int main(int argc, char **argv)
{
g_thread_init(NULL);
gtk_test_init(&argc, &argv, NULL);
......@@ -103,7 +159,7 @@ int main(int argc, char** argv)
}
#else
int main(int argc, char** argv)
int main(int argc, char **argv)
{
g_critical("You will need gtk-2.14.0 to run the unit tests. Doing nothing now.");
return 0;
......
......@@ -29,6 +29,7 @@
#include "EditingBehavior.h"
#include "FileSystem.h"
#include "GOwnPtr.h"
#include "KURL.h"
#include "PluginDatabase.h"
#include "webkitenumtypes.h"
#include "webkitglobalsprivate.h"
......@@ -171,7 +172,7 @@ static String webkitOSVersion()
return uaOSVersion;
}
String webkitUserAgent()
static String webkitUserAgent()
{
// We mention Safari since many broken sites check for it (OmniWeb does this too)
// We re-use the WebKit version, though it doesn't seem to matter much in practice
......@@ -183,6 +184,18 @@ String webkitUserAgent()
return staticUA;
}
static String safariUserAgent()
{
// We mention Safari since many broken sites check for it (OmniWeb does this too)
// We re-use the WebKit version, though it doesn't seem to matter much in practice
DEFINE_STATIC_LOCAL(const String, uaVersion, (makeString(String::number(WEBKIT_USER_AGENT_MAJOR_VERSION), '.', String::number(WEBKIT_USER_AGENT_MINOR_VERSION), '+')));
DEFINE_STATIC_LOCAL(const String, staticUA, (makeString("Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; en_US) AppleWebKit/", uaVersion) +
makeString(" (KHTML, like Gecko) Version/5.0.5 Safari/", uaVersion)));
return staticUA;
}
static void webkit_web_settings_finalize(GObject* object);
static void webkit_web_settings_set_property(GObject* object, guint prop_id, const GValue* value, GParamSpec* pspec);
......@@ -1319,6 +1332,170 @@ const gchar* webkit_web_settings_get_user_agent(WebKitWebSettings* webSettings)
return webSettings->priv->userAgent.data();
}
static void initializeDomainsList(HashSet<String>& googleDomains)
{
// Google search domains.
googleDomains.add("biz");
googleDomains.add("com");
googleDomains.add("net");
googleDomains.add("org");
googleDomains.add("ae");
googleDomains.add("ag");
googleDomains.add("am");
googleDomains.add("at");
googleDomains.add("az");
googleDomains.add("be");
googleDomains.add("bi");
googleDomains.add("ca");
googleDomains.add("cc");
googleDomains.add("cd");
googleDomains.add("cg");
googleDomains.add("ch");
googleDomains.add("cl");
googleDomains.add("com.br");
googleDomains.add("com.do");
googleDomains.add("co.uk");
googleDomains.add("co.kr");
googleDomains.add("co.jp");
googleDomains.add("de");
googleDomains.add("dj");
googleDomains.add("dk");
googleDomains.add("ee");
googleDomains.add("es");
googleDomains.add("fi");
googleDomains.add("fm");
googleDomains.add("fr");
googleDomains.add("gg");
googleDomains.add("gl");
googleDomains.add("gm");
googleDomains.add("gs");
googleDomains.add("hn");
googleDomains.add("hu");
googleDomains.add("ie");
googleDomains.add("it");
googleDomains.add("je");
googleDomains.add("kz");
googleDomains.add("li");
googleDomains.add("lt");
googleDomains.add("lu");
googleDomains.add("lv");
googleDomains.add("ma");
googleDomains.add("ms");
googleDomains.add("mu");
googleDomains.add("mw");
googleDomains.add("nl");
googleDomains.add("no");
googleDomains.add("nu");
googleDomains.add("pl");
googleDomains.add("pn");
googleDomains.add("pt");
googleDomains.add("ru");
googleDomains.add("rw");
googleDomains.add("sh");
googleDomains.add("sk");
googleDomains.add("sm");
googleDomains.add("st");
googleDomains.add("td");
googleDomains.add("tk");
googleDomains.add("tp");
googleDomains.add("tv");
googleDomains.add("us");
googleDomains.add("uz");
googleDomains.add("ws");
}
static void initializeOtherGoogleDomains(Vector<String>& otherGoogleDomains)
{
otherGoogleDomains.append("gmail.com");
otherGoogleDomains.append("youtube.com");
otherGoogleDomains.append("gstatic.com");
otherGoogleDomains.append("ytimg.com");
}
static bool isGoogleDomain(String host)
{
DEFINE_STATIC_LOCAL(HashSet<String>, googleDomains, ());
DEFINE_STATIC_LOCAL(Vector<String>, otherGoogleDomains, ());
if (googleDomains.isEmpty())
initializeDomainsList(googleDomains);
if (otherGoogleDomains.isEmpty())
initializeOtherGoogleDomains(otherGoogleDomains);
// First check if this is one of the various google.com international domains.
int position = host.find(".google.");
if (position > 0 && googleDomains.contains(host.substring(position + sizeof(".google.") - 1)))
return true;
// Then we check the possibility of it being one of the other, .com-only google domains.
for (unsigned int i = 0; i < otherGoogleDomains.size(); i++) {
if (host.endsWith(otherGoogleDomains.at(i)))
return true;
}
return false;
}
static bool isGoogleCalendar(const KURL& url)
{
if (url.host().find("calendar.google.") == 0
|| (url.host().find("google.com") && url.path().startsWith("/calendar")))
return true;
return false;
}
static String userAgentForURL(const KURL& url)
{
// For Google domains, drop the browser's custom User Agent string, and use the
// standard WebKit/Safari one, so they don't give us a broken experience. Calendar
// thinks "Linux WebKit" means mobile.
if (isGoogleCalendar(url))
return safariUserAgent();
if (isGoogleDomain(url.host()))
return webkitUserAgent();
return String();
}
/*
* Private usage only.
* webkitWebSettingsUserAgentForURI:
* @web_settings: the #WebKitWebSettings object to query
* @uri: the URI we want to know the User-Agent for
*
* Some web sites have been using User-Agent parsing heavily to decide
* the kind of content that is sent to the browser. When
* WebKitWebSettings:enable-site-specific-quirks is enabled WebKitGTK+
* will use its knowledge of sites doing bad things and lie to them by
* sending either the default User-Agent, i.e. not using the one
* specified by the browser in WebKitWebSettings:user-agent, or the
* Safari one (including lying about the underlying operating system).
*
* This function allows the browser to figure out what User-Agent is
* going to be sent to a particular URI.
*
* Please note that if WebKitWebSettings:use-site-specific-quirks is
* turned off calling this function is the same as calling
* webkit_web_settings_get_user_agent(), except you have to free the
* result.
*
* Returns: (transfer full): a newly allocated string containing the
* User-Agent that will be sent for the given URI.
*/
char* webkitWebSettingsUserAgentForURI(WebKitWebSettings* webSettings, const char* uri)
{
if (webSettings->priv->enableSiteSpecificQuirks) {
String userAgentString = userAgentForURL(WebCore::KURL(WebCore::KURL(), String::fromUTF8(uri)));
if (!userAgentString.isEmpty())
return g_strdup(userAgentString.utf8().data());
}
return g_strdup(webkit_web_settings_get_user_agent(webSettings));
}
namespace WebKit {
WebCore::EditingBehaviorType core(WebKitEditingBehavior type)
......
......@@ -82,9 +82,9 @@ struct _WebKitWebSettingsPrivate {
WEBKIT_API void webkit_web_settings_add_extra_plugin_directory(WebKitWebView*, const gchar* directory);
GSList* webkitWebViewGetEnchantDicts(WebKitWebView*);
WEBKIT_API char* webkitWebSettingsUserAgentForURI(WebKitWebSettings*, const gchar* uri);
WTF::String webkitUserAgent();
GSList* webkitWebViewGetEnchantDicts(WebKitWebView*);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment