• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 Apple Inc. All Rights Reserved.
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 COMPUTER, 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 
27 #include "config.h"
28 #include "platform/weborigin/SchemeRegistry.h"
29 
30 #include "wtf/MainThread.h"
31 #include "wtf/text/StringBuilder.h"
32 
33 namespace blink {
34 
localURLSchemes()35 static URLSchemesMap& localURLSchemes()
36 {
37     DEFINE_STATIC_LOCAL(URLSchemesMap, localSchemes, ());
38 
39     if (localSchemes.isEmpty())
40         localSchemes.add("file");
41 
42     return localSchemes;
43 }
44 
displayIsolatedURLSchemes()45 static URLSchemesMap& displayIsolatedURLSchemes()
46 {
47     DEFINE_STATIC_LOCAL(URLSchemesMap, displayIsolatedSchemes, ());
48     return displayIsolatedSchemes;
49 }
50 
secureSchemes()51 static URLSchemesMap& secureSchemes()
52 {
53     DEFINE_STATIC_LOCAL(URLSchemesMap, secureSchemes, ());
54 
55     if (secureSchemes.isEmpty()) {
56         secureSchemes.add("https");
57         secureSchemes.add("about");
58         secureSchemes.add("data");
59         secureSchemes.add("wss");
60     }
61 
62     return secureSchemes;
63 }
64 
schemesWithUniqueOrigins()65 static URLSchemesMap& schemesWithUniqueOrigins()
66 {
67     DEFINE_STATIC_LOCAL(URLSchemesMap, schemesWithUniqueOrigins, ());
68 
69     if (schemesWithUniqueOrigins.isEmpty()) {
70         schemesWithUniqueOrigins.add("about");
71         schemesWithUniqueOrigins.add("javascript");
72         // This is a willful violation of HTML5.
73         // See https://bugs.webkit.org/show_bug.cgi?id=11885
74         schemesWithUniqueOrigins.add("data");
75     }
76 
77     return schemesWithUniqueOrigins;
78 }
79 
emptyDocumentSchemes()80 static URLSchemesMap& emptyDocumentSchemes()
81 {
82     DEFINE_STATIC_LOCAL(URLSchemesMap, emptyDocumentSchemes, ());
83 
84     if (emptyDocumentSchemes.isEmpty())
85         emptyDocumentSchemes.add("about");
86 
87     return emptyDocumentSchemes;
88 }
89 
schemesForbiddenFromDomainRelaxation()90 static HashSet<String>& schemesForbiddenFromDomainRelaxation()
91 {
92     DEFINE_STATIC_LOCAL(HashSet<String>, schemes, ());
93     return schemes;
94 }
95 
canDisplayOnlyIfCanRequestSchemes()96 static URLSchemesMap& canDisplayOnlyIfCanRequestSchemes()
97 {
98     DEFINE_STATIC_LOCAL(URLSchemesMap, canDisplayOnlyIfCanRequestSchemes, ());
99 
100     if (canDisplayOnlyIfCanRequestSchemes.isEmpty()) {
101         canDisplayOnlyIfCanRequestSchemes.add("blob");
102         canDisplayOnlyIfCanRequestSchemes.add("filesystem");
103     }
104 
105     return canDisplayOnlyIfCanRequestSchemes;
106 }
107 
notAllowingJavascriptURLsSchemes()108 static URLSchemesMap& notAllowingJavascriptURLsSchemes()
109 {
110     DEFINE_STATIC_LOCAL(URLSchemesMap, notAllowingJavascriptURLsSchemes, ());
111     return notAllowingJavascriptURLsSchemes;
112 }
113 
registerURLSchemeAsLocal(const String & scheme)114 void SchemeRegistry::registerURLSchemeAsLocal(const String& scheme)
115 {
116     localURLSchemes().add(scheme);
117 }
118 
removeURLSchemeRegisteredAsLocal(const String & scheme)119 void SchemeRegistry::removeURLSchemeRegisteredAsLocal(const String& scheme)
120 {
121     if (scheme == "file")
122         return;
123     localURLSchemes().remove(scheme);
124 }
125 
localSchemes()126 const URLSchemesMap& SchemeRegistry::localSchemes()
127 {
128     return localURLSchemes();
129 }
130 
CORSEnabledSchemes()131 static URLSchemesMap& CORSEnabledSchemes()
132 {
133     // FIXME: http://bugs.webkit.org/show_bug.cgi?id=77160
134     DEFINE_STATIC_LOCAL(URLSchemesMap, CORSEnabledSchemes, ());
135 
136     if (CORSEnabledSchemes.isEmpty()) {
137         CORSEnabledSchemes.add("http");
138         CORSEnabledSchemes.add("https");
139         CORSEnabledSchemes.add("data");
140     }
141 
142     return CORSEnabledSchemes;
143 }
144 
LegacySchemes()145 static URLSchemesMap& LegacySchemes()
146 {
147     DEFINE_STATIC_LOCAL(URLSchemesMap, LegacySchemes, ());
148 
149     if (LegacySchemes.isEmpty()) {
150         LegacySchemes.add("ftp");
151         LegacySchemes.add("gopher");
152     }
153 
154     return LegacySchemes;
155 }
156 
ContentSecurityPolicyBypassingSchemes()157 static URLSchemesMap& ContentSecurityPolicyBypassingSchemes()
158 {
159     DEFINE_STATIC_LOCAL(URLSchemesMap, schemes, ());
160     return schemes;
161 }
162 
shouldTreatURLSchemeAsLocal(const String & scheme)163 bool SchemeRegistry::shouldTreatURLSchemeAsLocal(const String& scheme)
164 {
165     if (scheme.isEmpty())
166         return false;
167     return localURLSchemes().contains(scheme);
168 }
169 
registerURLSchemeAsNoAccess(const String & scheme)170 void SchemeRegistry::registerURLSchemeAsNoAccess(const String& scheme)
171 {
172     schemesWithUniqueOrigins().add(scheme);
173 }
174 
shouldTreatURLSchemeAsNoAccess(const String & scheme)175 bool SchemeRegistry::shouldTreatURLSchemeAsNoAccess(const String& scheme)
176 {
177     if (scheme.isEmpty())
178         return false;
179     return schemesWithUniqueOrigins().contains(scheme);
180 }
181 
registerURLSchemeAsDisplayIsolated(const String & scheme)182 void SchemeRegistry::registerURLSchemeAsDisplayIsolated(const String& scheme)
183 {
184     displayIsolatedURLSchemes().add(scheme);
185 }
186 
shouldTreatURLSchemeAsDisplayIsolated(const String & scheme)187 bool SchemeRegistry::shouldTreatURLSchemeAsDisplayIsolated(const String& scheme)
188 {
189     if (scheme.isEmpty())
190         return false;
191     return displayIsolatedURLSchemes().contains(scheme);
192 }
193 
registerURLSchemeAsSecure(const String & scheme)194 void SchemeRegistry::registerURLSchemeAsSecure(const String& scheme)
195 {
196     secureSchemes().add(scheme);
197 }
198 
shouldTreatURLSchemeAsSecure(const String & scheme)199 bool SchemeRegistry::shouldTreatURLSchemeAsSecure(const String& scheme)
200 {
201     if (scheme.isEmpty())
202         return false;
203     return secureSchemes().contains(scheme);
204 }
205 
registerURLSchemeAsEmptyDocument(const String & scheme)206 void SchemeRegistry::registerURLSchemeAsEmptyDocument(const String& scheme)
207 {
208     emptyDocumentSchemes().add(scheme);
209 }
210 
shouldLoadURLSchemeAsEmptyDocument(const String & scheme)211 bool SchemeRegistry::shouldLoadURLSchemeAsEmptyDocument(const String& scheme)
212 {
213     if (scheme.isEmpty())
214         return false;
215     return emptyDocumentSchemes().contains(scheme);
216 }
217 
setDomainRelaxationForbiddenForURLScheme(bool forbidden,const String & scheme)218 void SchemeRegistry::setDomainRelaxationForbiddenForURLScheme(bool forbidden, const String& scheme)
219 {
220     if (scheme.isEmpty())
221         return;
222 
223     if (forbidden)
224         schemesForbiddenFromDomainRelaxation().add(scheme);
225     else
226         schemesForbiddenFromDomainRelaxation().remove(scheme);
227 }
228 
isDomainRelaxationForbiddenForURLScheme(const String & scheme)229 bool SchemeRegistry::isDomainRelaxationForbiddenForURLScheme(const String& scheme)
230 {
231     if (scheme.isEmpty())
232         return false;
233     return schemesForbiddenFromDomainRelaxation().contains(scheme);
234 }
235 
canDisplayOnlyIfCanRequest(const String & scheme)236 bool SchemeRegistry::canDisplayOnlyIfCanRequest(const String& scheme)
237 {
238     if (scheme.isEmpty())
239         return false;
240     return canDisplayOnlyIfCanRequestSchemes().contains(scheme);
241 }
242 
registerAsCanDisplayOnlyIfCanRequest(const String & scheme)243 void SchemeRegistry::registerAsCanDisplayOnlyIfCanRequest(const String& scheme)
244 {
245     canDisplayOnlyIfCanRequestSchemes().add(scheme);
246 }
247 
registerURLSchemeAsNotAllowingJavascriptURLs(const String & scheme)248 void SchemeRegistry::registerURLSchemeAsNotAllowingJavascriptURLs(const String& scheme)
249 {
250     notAllowingJavascriptURLsSchemes().add(scheme);
251 }
252 
shouldTreatURLSchemeAsNotAllowingJavascriptURLs(const String & scheme)253 bool SchemeRegistry::shouldTreatURLSchemeAsNotAllowingJavascriptURLs(const String& scheme)
254 {
255     if (scheme.isEmpty())
256         return false;
257     return notAllowingJavascriptURLsSchemes().contains(scheme);
258 }
259 
registerURLSchemeAsCORSEnabled(const String & scheme)260 void SchemeRegistry::registerURLSchemeAsCORSEnabled(const String& scheme)
261 {
262     CORSEnabledSchemes().add(scheme);
263 }
264 
shouldTreatURLSchemeAsCORSEnabled(const String & scheme)265 bool SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(const String& scheme)
266 {
267     if (scheme.isEmpty())
268         return false;
269     return CORSEnabledSchemes().contains(scheme);
270 }
271 
listOfCORSEnabledURLSchemes()272 String SchemeRegistry::listOfCORSEnabledURLSchemes()
273 {
274     StringBuilder builder;
275     const URLSchemesMap& corsEnabledSchemes = CORSEnabledSchemes();
276 
277     bool addSeparator = false;
278     for (URLSchemesMap::const_iterator it = corsEnabledSchemes.begin(); it != corsEnabledSchemes.end(); ++it) {
279         if (addSeparator)
280             builder.appendLiteral(", ");
281         else
282             addSeparator = true;
283 
284         builder.append(*it);
285     }
286     return builder.toString();
287 }
288 
registerURLSchemeAsLegacy(const String & scheme)289 void SchemeRegistry::registerURLSchemeAsLegacy(const String& scheme)
290 {
291     LegacySchemes().add(scheme);
292 }
293 
shouldTreatURLSchemeAsLegacy(const String & scheme)294 bool SchemeRegistry::shouldTreatURLSchemeAsLegacy(const String& scheme)
295 {
296     if (scheme.isEmpty())
297         return false;
298     return LegacySchemes().contains(scheme);
299 }
300 
registerURLSchemeAsBypassingContentSecurityPolicy(const String & scheme)301 void SchemeRegistry::registerURLSchemeAsBypassingContentSecurityPolicy(const String& scheme)
302 {
303     ContentSecurityPolicyBypassingSchemes().add(scheme);
304 }
305 
removeURLSchemeRegisteredAsBypassingContentSecurityPolicy(const String & scheme)306 void SchemeRegistry::removeURLSchemeRegisteredAsBypassingContentSecurityPolicy(const String& scheme)
307 {
308     ContentSecurityPolicyBypassingSchemes().remove(scheme);
309 }
310 
schemeShouldBypassContentSecurityPolicy(const String & scheme)311 bool SchemeRegistry::schemeShouldBypassContentSecurityPolicy(const String& scheme)
312 {
313     if (scheme.isEmpty())
314         return false;
315     return ContentSecurityPolicyBypassingSchemes().contains(scheme);
316 }
317 
318 } // namespace blink
319