Move URL from WebCore to WTF
[WebKit-https.git] / Source / WebCore / platform / UserAgentQuirks.cpp
1 /*
2  * Copyright (C) 2012, 2014, 2016 Igalia S.L.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "UserAgentQuirks.h"
28
29 #include "PublicSuffix.h"
30 #include <wtf/URL.h>
31
32 namespace WebCore {
33
34 // When editing the quirks in this file, be sure to update
35 // Tools/TestWebKitAPI/Tests/WebCore/UserAgentQuirks.cpp.
36
37 static bool isGoogle(const URL& url)
38 {
39     String baseDomain = topPrivatelyControlledDomain(url.host().toString());
40
41     // Our Google UA is *very* complicated to get right. Read
42     // https://webkit.org/b/142074 carefully before changing. Test that Earth
43     // view is available in Google Maps. Test Google Calendar. Test downloading
44     // the Hangouts browser plugin. Test logging out and logging in to a Google
45     // account. Change platformVersionForUAString() to return "FreeBSD amd64"
46     // and test everything again.
47     if (baseDomain.startsWith("google."))
48         return true;
49     if (baseDomain == "gstatic.com")
50         return true;
51     if (baseDomain == "googleapis.com")
52         return true;
53     if (baseDomain == "googleusercontent.com")
54         return true;
55
56     return false;
57 }
58
59 // Be careful with this quirk: it's an invitation for sites to use JavaScript
60 // that works in Chrome that WebKit cannot handle. Prefer other quirks instead.
61 static bool urlRequiresChromeBrowser(const URL& url)
62 {
63     String baseDomain = topPrivatelyControlledDomain(url.host().toString());
64
65     // Needed for fonts on many sites to work with WebKit.
66     // https://bugs.webkit.org/show_bug.cgi?id=147296
67     if (baseDomain == "typekit.net" || baseDomain == "typekit.com")
68         return true;
69
70     // Washington Post decides the image type based on the user agent,
71     // giving image/jp2 with WebKitGTK+'s standard user agent.
72     // https://bugs.webkit.org/show_bug.cgi?id=181421
73     if (baseDomain == "washingtonpost.com")
74         return true;
75
76     return false;
77 }
78
79 static bool urlRequiresMacintoshPlatform(const URL& url)
80 {
81     String domain = url.host().toString();
82     String baseDomain = topPrivatelyControlledDomain(domain);
83
84     // At least finance.yahoo.com displays a mobile version with WebKitGTK+'s standard user agent.
85     if (baseDomain == "yahoo.com")
86         return true;
87
88     // taobao.com displays a mobile version with WebKitGTK+'s standard user agent.
89     if (baseDomain == "taobao.com")
90         return true;
91
92     // web.whatsapp.com completely blocks users with WebKitGTK+'s standard user agent.
93     if (baseDomain == "whatsapp.com")
94         return true;
95
96     // paypal.com completely blocks users with WebKitGTK+'s standard user agent.
97     if (baseDomain == "paypal.com")
98         return true;
99
100     // chase.com displays a huge "please update your browser" warning with
101     // WebKitGTK+'s standard user agent.
102     if (baseDomain == "chase.com")
103         return true;
104
105     // Microsoft Outlook Web App forces users with WebKitGTK+'s standard user
106     // agent to use the light version. Earlier versions even blocks users from
107     // accessing the calendar.
108     if (domain == "mail.ntu.edu.tw")
109         return true;
110
111     // Google Docs shows a scary unsupported browser warning with WebKitGTK+'s
112     // standard user agent.
113     if (domain == "docs.google.com")
114         return true;
115
116     return false;
117 }
118
119 static bool urlRequiresLinuxDesktopPlatform(const URL& url)
120 {
121     // docs.google.com requires the macOS platform quirk.
122     return isGoogle(url) && url.host() != "docs.google.com";
123 }
124
125 UserAgentQuirks UserAgentQuirks::quirksForURL(const URL& url)
126 {
127     ASSERT(!url.isNull());
128
129     UserAgentQuirks quirks;
130
131     if (urlRequiresChromeBrowser(url))
132         quirks.add(UserAgentQuirks::NeedsChromeBrowser);
133
134     if (urlRequiresMacintoshPlatform(url))
135         quirks.add(UserAgentQuirks::NeedsMacintoshPlatform);
136     else if (urlRequiresLinuxDesktopPlatform(url))
137         quirks.add(UserAgentQuirks::NeedsLinuxDesktopPlatform);
138
139     return quirks;
140 }
141
142 String UserAgentQuirks::stringForQuirk(UserAgentQuirk quirk)
143 {
144     switch (quirk) {
145     case NeedsChromeBrowser:
146         // Get versions from https://chromium.googlesource.com/chromium/src.git
147         return "Chrome/58.0.3029.81"_s;
148     case NeedsMacintoshPlatform:
149         return "Macintosh; Intel Mac OS X 10_13_4"_s;
150     case NeedsLinuxDesktopPlatform:
151         return "X11; Linux x86_64"_s;
152     case NumUserAgentQuirks:
153     default:
154         ASSERT_NOT_REACHED();
155     }
156     return ""_s;
157 }
158
159 }