Changeset 91253 in webkit


Ignore:
Timestamp:
Jul 19, 2011 7:49:38 AM (13 years ago)
Author:
kov@webkit.org
Message:

[GTK] Google Calendar thinks we're mobile
https://bugs.webkit.org/show_bug.cgi?id=63994

Patch by Gustavo Noronha Silva <Gustavo Noronha Silva> 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:
Location:
trunk/Source/WebKit/gtk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/gtk/ChangeLog

    r91097 r91253  
     12011-07-11  Gustavo Noronha Silva  <gns@gnome.org>
     2
     3        [GTK] Google Calendar thinks we're mobile
     4        https://bugs.webkit.org/show_bug.cgi?id=63994
     5
     6        Reviewed by Xan Lopez.
     7
     8        Further special-case Google Calendar, for it thinks WebKit+Linux
     9        means mobile, so we also have to spoof the OS.
     10
     11        * WebCoreSupport/FrameLoaderClientGtk.cpp:
     12        (WebKit::FrameLoaderClient::userAgent): use the new WebKitGTK+
     13        private API that centralizes the logic now.
     14        * tests/testwebsettings.c: Add tests to make sure the Google
     15        special-cases only apply for the expected domains and when quirks
     16        special-casing is enabled.
     17        (test_non_quirky_user_agents):
     18        (test_webkit_web_settings_user_agent):
     19        * webkit/webkitwebsettings.cpp:
     20        (webkitUserAgent): make it static.
     21        (safariUserAgent): returns a fake Safari in Mac OS X User-Agent.
     22        (initializeDomainsList): moved from FrameLoaderClientGtk.
     23        (isGoogleDomain):ditto.
     24        (isGoogleCalendar): ditto.
     25        (userAgentForURL): ditto.
     26        (webkitWebSettingsUserAgentForUri): centralize the whole
     27        user agent spoofing logic in this new private API that can be used
     28        by the browser to know what's going to happen for a specific URI
     29        and also allows our API testing.
     30        * webkit/webkitwebsettingsprivate.h:
     31
    1322011-07-15  Dan Bernstein  <mitz@apple.com>
    233
  • trunk/Source/WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.cpp

    r88628 r91253  
    115115}
    116116
    117 static void initializeDomainsList(HashSet<String>& googleDomains)
    118 {
    119     // Google search domains.
    120     googleDomains.add("biz");
    121     googleDomains.add("com");
    122     googleDomains.add("net");
    123     googleDomains.add("org");
    124     googleDomains.add("ae");
    125     googleDomains.add("ag");
    126     googleDomains.add("am");
    127     googleDomains.add("at");
    128     googleDomains.add("az");
    129     googleDomains.add("be");
    130     googleDomains.add("bi");
    131     googleDomains.add("ca");
    132     googleDomains.add("cc");
    133     googleDomains.add("cd");
    134     googleDomains.add("cg");
    135     googleDomains.add("ch");
    136     googleDomains.add("cl");
    137     googleDomains.add("com.br");
    138     googleDomains.add("co.uk");
    139     googleDomains.add("co.kr");
    140     googleDomains.add("co.jp");
    141     googleDomains.add("de");
    142     googleDomains.add("dj");
    143     googleDomains.add("dk");
    144     googleDomains.add("es");
    145     googleDomains.add("fi");
    146     googleDomains.add("fm");
    147     googleDomains.add("fr");
    148     googleDomains.add("gg");
    149     googleDomains.add("gl");
    150     googleDomains.add("gm");
    151     googleDomains.add("gs");
    152     googleDomains.add("hn");
    153     googleDomains.add("hu");
    154     googleDomains.add("ie");
    155     googleDomains.add("it");
    156     googleDomains.add("je");
    157     googleDomains.add("kz");
    158     googleDomains.add("li");
    159     googleDomains.add("lt");
    160     googleDomains.add("lu");
    161     googleDomains.add("lv");
    162     googleDomains.add("ma");
    163     googleDomains.add("ms");
    164     googleDomains.add("mu");
    165     googleDomains.add("mw");
    166     googleDomains.add("nl");
    167     googleDomains.add("no");
    168     googleDomains.add("nu");
    169     googleDomains.add("pl");
    170     googleDomains.add("pn");
    171     googleDomains.add("pt");
    172     googleDomains.add("ru");
    173     googleDomains.add("rw");
    174     googleDomains.add("sh");
    175     googleDomains.add("sk");
    176     googleDomains.add("sm");
    177     googleDomains.add("st");
    178     googleDomains.add("td");
    179     googleDomains.add("tk");
    180     googleDomains.add("tp");
    181     googleDomains.add("tv");
    182     googleDomains.add("us");
    183     googleDomains.add("uz");
    184     googleDomains.add("ws");
    185 }
    186 
    187 static bool isGoogleDomain(String host)
    188 {
    189     DEFINE_STATIC_LOCAL(HashSet<String>, googleDomains, ());
    190     DEFINE_STATIC_LOCAL(Vector<String>, otherGoogleDomains, ());
    191 
    192     if (googleDomains.isEmpty()) {
    193         otherGoogleDomains.append("gmail.com");
    194         otherGoogleDomains.append("youtube.com");
    195         otherGoogleDomains.append("gstatic.com");
    196         otherGoogleDomains.append("ytimg.com");
    197 
    198         initializeDomainsList(googleDomains);
    199     }
    200 
    201     // First check if this is one of the various google.com international domains.
    202     int position = host.find(".google.");
    203     if (position > 0 && googleDomains.contains(host.substring(position + sizeof(".google."))))
    204         return true;
    205 
    206     // Then we check the possibility of it being one of the other, .com-only google domains.
    207     for (unsigned int i = 0; i < otherGoogleDomains.size(); i++) {
    208         if (host.endsWith(otherGoogleDomains.at(i)))
    209             return true;
    210     }
    211 
    212     return false;
    213 }
    214117
    215118String FrameLoaderClient::userAgent(const KURL& url)
    216119{
    217120    WebKitWebSettings* settings = webkit_web_view_get_settings(getViewFromFrame(m_frame));
    218 
    219     gboolean useQuirks;
    220     g_object_get(settings, "enable-site-specific-quirks", &useQuirks, NULL);
    221 
    222     // For Google domains, drop the browser's custom User Agent string, and use the standard
    223     // WebKit/Safari one, so they don't give us a broken experience.
    224     if (useQuirks && isGoogleDomain(url.host()))
    225         return webkitUserAgent();
    226 
    227     return String::fromUTF8(webkit_web_settings_get_user_agent(settings));
     121    GOwnPtr<gchar> userAgentString(webkitWebSettingsUserAgentForURI(settings, url.string().utf8().data()));
     122    return String::fromUTF8(userAgentString.get());
    228123}
    229124
  • trunk/Source/WebKit/gtk/tests/testwebsettings.c

    r89288 r91253  
    2424#if GTK_CHECK_VERSION(2, 14, 0)
    2525
     26/* Private API */
     27char* webkitWebSettingsUserAgentForURI(WebKitWebSettings *settings, const char *uri);
     28
    2629static void test_webkit_web_settings_copy(void)
    2730{
    28     WebKitWebSettings* settings = webkit_web_settings_new();
     31    WebKitWebSettings *settings = webkit_web_settings_new();
    2932
    3033    // Set some non-default settings to verify that settings are properly copied.
     
    3538                 "default-encoding", "utf-8", NULL);
    3639
    37     WebKitWebSettings* copy = webkit_web_settings_copy(settings);
     40    WebKitWebSettings *copy = webkit_web_settings_copy(settings);
    3841
    3942    gboolean enableWebGL = FALSE;
    4043    gboolean enableFullscreen = FALSE;
    4144    gboolean autoLoadImages = FALSE;
    42     char* defaultEncoding = NULL;
     45    char *defaultEncoding = 0;
    4346    g_object_get(copy,
    4447                 "enable-fullscreen", &enableFullscreen,
     
    5457}
    5558
     59static void test_non_quirky_user_agents(WebKitWebSettings *settings, const char *defaultUserAgent)
     60{
     61    char *userAgent = 0;
     62
     63    // test a custom UA string
     64    userAgent = 0;
     65    g_object_set(settings, "user-agent", "testwebsettings/0.1", NULL);
     66    g_object_get(settings,"user-agent", &userAgent, NULL);
     67    g_assert_cmpstr(userAgent, ==, "testwebsettings/0.1");
     68    g_free(userAgent);
     69
     70    // setting it to NULL or an empty value should give us the default UA string
     71    userAgent = 0;
     72    g_object_set(settings, "user-agent", 0, NULL);
     73    g_object_get(settings,"user-agent", &userAgent, NULL);
     74    g_assert_cmpstr(userAgent, ==, defaultUserAgent);
     75    g_free(userAgent);
     76
     77    userAgent = 0;
     78    g_object_set(settings, "user-agent", "", NULL);
     79    g_object_get(settings,"user-agent", &userAgent, NULL);
     80    g_assert_cmpstr(userAgent, ==, defaultUserAgent);
     81    g_free(userAgent);
     82}
     83
    5684static void test_webkit_web_settings_user_agent(void)
    5785{
    58     WebKitWebSettings* settings;
    59     GtkWidget* webView;
    60     gchar* defaultUserAgent;
    61     gchar* userAgent;
     86    WebKitWebSettings *settings;
     87    GtkWidget *webView;
     88    char *defaultUserAgent;
     89    char *userAgent = 0;
    6290    g_test_bug("17375");
    6391
     
    6896    defaultUserAgent = g_strdup(webkit_web_settings_get_user_agent(settings));
    6997
    70     // test a custom UA string
    71     userAgent = NULL;
    72     g_object_set(G_OBJECT(settings), "user-agent", "testwebsettings/0.1", NULL);
    73     g_object_get(G_OBJECT(settings),"user-agent", &userAgent, NULL);
     98    test_non_quirky_user_agents(settings, defaultUserAgent);
     99
     100    /* Test quirky google domains */
     101    g_object_set(settings, "user-agent", "testwebsettings/0.1", NULL);
     102
     103    userAgent = webkitWebSettingsUserAgentForURI(settings, "http://www.google.com/");
    74104    g_assert_cmpstr(userAgent, ==, "testwebsettings/0.1");
    75105    g_free(userAgent);
    76106
    77     // setting it to NULL or an empty value should give us the default UA string
    78     userAgent = NULL;
    79     g_object_set(G_OBJECT(settings), "user-agent", NULL, NULL);
    80     g_object_get(G_OBJECT(settings),"user-agent", &userAgent, NULL);
     107    userAgent = webkitWebSettingsUserAgentForURI(settings, "http://gmail.com/");
     108    g_assert_cmpstr(userAgent, ==, "testwebsettings/0.1");
     109    g_free(userAgent);
     110
     111    userAgent = webkitWebSettingsUserAgentForURI(settings, "http://www.google.com.br/");
     112    g_assert_cmpstr(userAgent, ==, "testwebsettings/0.1");
     113    g_free(userAgent);
     114
     115    userAgent = webkitWebSettingsUserAgentForURI(settings, "http://calendar.google.com/");
     116    g_assert_cmpstr(userAgent, ==, "testwebsettings/0.1");
     117    g_free(userAgent);
     118
     119    /* Now enable quirks handling */
     120    g_object_set(settings, "enable-site-specific-quirks", TRUE, NULL);
     121
     122    test_non_quirky_user_agents(settings, defaultUserAgent);
     123
     124    g_object_set(settings, "user-agent", "testwebsettings/0.1", NULL);
     125
     126    userAgent = webkitWebSettingsUserAgentForURI(settings, "http://www.google.com/");
    81127    g_assert_cmpstr(userAgent, ==, defaultUserAgent);
    82128    g_free(userAgent);
    83129
    84     userAgent = NULL;
    85     g_object_set(G_OBJECT(settings), "user-agent", "", NULL);
    86     g_object_get(G_OBJECT(settings),"user-agent", &userAgent, NULL);
     130    userAgent = webkitWebSettingsUserAgentForURI(settings, "http://gmail.com/");
    87131    g_assert_cmpstr(userAgent, ==, defaultUserAgent);
     132    g_free(userAgent);
     133
     134    userAgent = webkitWebSettingsUserAgentForURI(settings, "http://www.google.com.br/");
     135    g_assert_cmpstr(userAgent, ==, defaultUserAgent);
     136    g_free(userAgent);
     137
     138    userAgent = webkitWebSettingsUserAgentForURI(settings, "http://www.google.uk.not.com.br/");
     139    g_assert_cmpstr(userAgent, ==, "testwebsettings/0.1");
     140    g_free(userAgent);
     141
     142    userAgent = webkitWebSettingsUserAgentForURI(settings, "http://calendar.google.com/");
     143    g_assert(g_str_has_prefix(userAgent, "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; en_US) AppleWebKit/"));
    88144    g_free(userAgent);
    89145
     
    92148}
    93149
    94 int main(int argc, char** argv)
     150int main(int argc, char **argv)
    95151{
    96152    g_thread_init(NULL);
     
    104160
    105161#else
    106 int main(int argc, char** argv)
     162int main(int argc, char **argv)
    107163{
    108164    g_critical("You will need gtk-2.14.0 to run the unit tests. Doing nothing now.");
  • trunk/Source/WebKit/gtk/webkit/webkitwebsettings.cpp

    r90776 r91253  
    3030#include "FileSystem.h"
    3131#include "GOwnPtr.h"
     32#include "KURL.h"
    3233#include "PluginDatabase.h"
    3334#include "webkitenumtypes.h"
     
    172173}
    173174
    174 String webkitUserAgent()
     175static String webkitUserAgent()
    175176{
    176177    // We mention Safari since many broken sites check for it (OmniWeb does this too)
     
    180181    DEFINE_STATIC_LOCAL(const String, staticUA, (makeString("Mozilla/5.0 (", webkitPlatform(), webkitOSVersion(), ") AppleWebKit/", uaVersion) +
    181182                                                 makeString(" (KHTML, like Gecko) Version/5.0 Safari/", uaVersion)));
     183
     184    return staticUA;
     185}
     186
     187static String safariUserAgent()
     188{
     189    // We mention Safari since many broken sites check for it (OmniWeb does this too)
     190    // We re-use the WebKit version, though it doesn't seem to matter much in practice
     191
     192    DEFINE_STATIC_LOCAL(const String, uaVersion, (makeString(String::number(WEBKIT_USER_AGENT_MAJOR_VERSION), '.', String::number(WEBKIT_USER_AGENT_MINOR_VERSION), '+')));
     193    DEFINE_STATIC_LOCAL(const String, staticUA, (makeString("Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; en_US) AppleWebKit/", uaVersion) +
     194                                                 makeString(" (KHTML, like Gecko) Version/5.0.5 Safari/", uaVersion)));
    182195
    183196    return staticUA;
     
    13201333}
    13211334
     1335static void initializeDomainsList(HashSet<String>& googleDomains)
     1336{
     1337    // Google search domains.
     1338    googleDomains.add("biz");
     1339    googleDomains.add("com");
     1340    googleDomains.add("net");
     1341    googleDomains.add("org");
     1342    googleDomains.add("ae");
     1343    googleDomains.add("ag");
     1344    googleDomains.add("am");
     1345    googleDomains.add("at");
     1346    googleDomains.add("az");
     1347    googleDomains.add("be");
     1348    googleDomains.add("bi");
     1349    googleDomains.add("ca");
     1350    googleDomains.add("cc");
     1351    googleDomains.add("cd");
     1352    googleDomains.add("cg");
     1353    googleDomains.add("ch");
     1354    googleDomains.add("cl");
     1355    googleDomains.add("com.br");
     1356    googleDomains.add("com.do");
     1357    googleDomains.add("co.uk");
     1358    googleDomains.add("co.kr");
     1359    googleDomains.add("co.jp");
     1360    googleDomains.add("de");
     1361    googleDomains.add("dj");
     1362    googleDomains.add("dk");
     1363    googleDomains.add("ee");
     1364    googleDomains.add("es");
     1365    googleDomains.add("fi");
     1366    googleDomains.add("fm");
     1367    googleDomains.add("fr");
     1368    googleDomains.add("gg");
     1369    googleDomains.add("gl");
     1370    googleDomains.add("gm");
     1371    googleDomains.add("gs");
     1372    googleDomains.add("hn");
     1373    googleDomains.add("hu");
     1374    googleDomains.add("ie");
     1375    googleDomains.add("it");
     1376    googleDomains.add("je");
     1377    googleDomains.add("kz");
     1378    googleDomains.add("li");
     1379    googleDomains.add("lt");
     1380    googleDomains.add("lu");
     1381    googleDomains.add("lv");
     1382    googleDomains.add("ma");
     1383    googleDomains.add("ms");
     1384    googleDomains.add("mu");
     1385    googleDomains.add("mw");
     1386    googleDomains.add("nl");
     1387    googleDomains.add("no");
     1388    googleDomains.add("nu");
     1389    googleDomains.add("pl");
     1390    googleDomains.add("pn");
     1391    googleDomains.add("pt");
     1392    googleDomains.add("ru");
     1393    googleDomains.add("rw");
     1394    googleDomains.add("sh");
     1395    googleDomains.add("sk");
     1396    googleDomains.add("sm");
     1397    googleDomains.add("st");
     1398    googleDomains.add("td");
     1399    googleDomains.add("tk");
     1400    googleDomains.add("tp");
     1401    googleDomains.add("tv");
     1402    googleDomains.add("us");
     1403    googleDomains.add("uz");
     1404    googleDomains.add("ws");
     1405}
     1406
     1407static void initializeOtherGoogleDomains(Vector<String>& otherGoogleDomains)
     1408{
     1409    otherGoogleDomains.append("gmail.com");
     1410    otherGoogleDomains.append("youtube.com");
     1411    otherGoogleDomains.append("gstatic.com");
     1412    otherGoogleDomains.append("ytimg.com");
     1413}
     1414
     1415static bool isGoogleDomain(String host)
     1416{
     1417    DEFINE_STATIC_LOCAL(HashSet<String>, googleDomains, ());
     1418    DEFINE_STATIC_LOCAL(Vector<String>, otherGoogleDomains, ());
     1419
     1420    if (googleDomains.isEmpty())
     1421        initializeDomainsList(googleDomains);
     1422
     1423    if (otherGoogleDomains.isEmpty())
     1424        initializeOtherGoogleDomains(otherGoogleDomains);
     1425
     1426    // First check if this is one of the various google.com international domains.
     1427    int position = host.find(".google.");
     1428    if (position > 0 && googleDomains.contains(host.substring(position + sizeof(".google.") - 1)))
     1429        return true;
     1430
     1431    // Then we check the possibility of it being one of the other, .com-only google domains.
     1432    for (unsigned int i = 0; i < otherGoogleDomains.size(); i++) {
     1433        if (host.endsWith(otherGoogleDomains.at(i)))
     1434            return true;
     1435    }
     1436
     1437    return false;
     1438}
     1439
     1440static bool isGoogleCalendar(const KURL& url)
     1441{
     1442    if (url.host().find("calendar.google.") == 0
     1443        || (url.host().find("google.com") && url.path().startsWith("/calendar")))
     1444        return true;
     1445
     1446    return false;
     1447}
     1448
     1449static String userAgentForURL(const KURL& url)
     1450{
     1451    // For Google domains, drop the browser's custom User Agent string, and use the
     1452    // standard WebKit/Safari one, so they don't give us a broken experience. Calendar
     1453    // thinks "Linux WebKit" means mobile.
     1454    if (isGoogleCalendar(url))
     1455        return safariUserAgent();
     1456
     1457    if (isGoogleDomain(url.host()))
     1458        return webkitUserAgent();
     1459
     1460    return String();
     1461}
     1462
     1463/*
     1464 * Private usage only.
     1465 * webkitWebSettingsUserAgentForURI:
     1466 * @web_settings: the #WebKitWebSettings object to query
     1467 * @uri: the URI we want to know the User-Agent for
     1468 *
     1469 * Some web sites have been using User-Agent parsing heavily to decide
     1470 * the kind of content that is sent to the browser. When
     1471 * WebKitWebSettings:enable-site-specific-quirks is enabled WebKitGTK+
     1472 * will use its knowledge of sites doing bad things and lie to them by
     1473 * sending either the default User-Agent, i.e. not using the one
     1474 * specified by the browser in WebKitWebSettings:user-agent, or the
     1475 * Safari one (including lying about the underlying operating system).
     1476 *
     1477 * This function allows the browser to figure out what User-Agent is
     1478 * going to be sent to a particular URI.
     1479 *
     1480 * Please note that if WebKitWebSettings:use-site-specific-quirks is
     1481 * turned off calling this function is the same as calling
     1482 * webkit_web_settings_get_user_agent(), except you have to free the
     1483 * result.
     1484 *
     1485 * Returns: (transfer full): a newly allocated string containing the
     1486 * User-Agent that will be sent for the given URI.
     1487 */
     1488char* webkitWebSettingsUserAgentForURI(WebKitWebSettings* webSettings, const char* uri)
     1489{
     1490    if (webSettings->priv->enableSiteSpecificQuirks) {
     1491        String userAgentString = userAgentForURL(WebCore::KURL(WebCore::KURL(), String::fromUTF8(uri)));
     1492        if (!userAgentString.isEmpty())
     1493            return g_strdup(userAgentString.utf8().data());
     1494    }
     1495
     1496    return g_strdup(webkit_web_settings_get_user_agent(webSettings));
     1497}
     1498
    13221499namespace WebKit {
    13231500
  • trunk/Source/WebKit/gtk/webkit/webkitwebsettingsprivate.h

    r90776 r91253  
    8383WEBKIT_API void webkit_web_settings_add_extra_plugin_directory(WebKitWebView*, const gchar* directory);
    8484
     85WEBKIT_API char* webkitWebSettingsUserAgentForURI(WebKitWebSettings*, const gchar* uri);
     86
    8587GSList* webkitWebViewGetEnchantDicts(WebKitWebView*);
    86 
    87 WTF::String webkitUserAgent();
    8888
    8989}
Note: See TracChangeset for help on using the changeset viewer.