Use NeverDestroyed instead of DEPRECATED_DEFINE_STATIC_LOCAL
[WebKit-https.git] / Source / WebCore / platform / SchemeRegistry.cpp
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 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 "SchemeRegistry.h"
28 #include <wtf/MainThread.h>
29 #include <wtf/NeverDestroyed.h>
30
31 #if USE(QUICK_LOOK)
32 #include "QuickLook.h"
33 #endif
34
35 namespace WebCore {
36
37 static URLSchemesMap& localURLSchemes()
38 {
39     static NeverDestroyed<URLSchemesMap> localSchemes;
40
41     if (localSchemes.get().isEmpty()) {
42         localSchemes.get().add("file");
43 #if PLATFORM(COCOA)
44         localSchemes.get().add("applewebdata");
45 #endif
46     }
47
48     return localSchemes;
49 }
50
51 static URLSchemesMap& displayIsolatedURLSchemes()
52 {
53     static NeverDestroyed<URLSchemesMap> displayIsolatedSchemes;
54     return displayIsolatedSchemes;
55 }
56
57 static URLSchemesMap& secureSchemes()
58 {
59     static NeverDestroyed<URLSchemesMap> secureSchemes;
60
61     if (secureSchemes.get().isEmpty()) {
62         secureSchemes.get().add("https");
63         secureSchemes.get().add("about");
64         secureSchemes.get().add("data");
65         secureSchemes.get().add("wss");
66 #if USE(QUICK_LOOK)
67         secureSchemes.get().add(QLPreviewProtocol());
68 #endif
69     }
70
71     return secureSchemes;
72 }
73
74 static URLSchemesMap& schemesWithUniqueOrigins()
75 {
76     static NeverDestroyed<URLSchemesMap> schemesWithUniqueOrigins;
77
78     if (schemesWithUniqueOrigins.get().isEmpty()) {
79         schemesWithUniqueOrigins.get().add("about");
80         schemesWithUniqueOrigins.get().add("javascript");
81         // This is a willful violation of HTML5.
82         // See https://bugs.webkit.org/show_bug.cgi?id=11885
83         schemesWithUniqueOrigins.get().add("data");
84     }
85
86     return schemesWithUniqueOrigins;
87 }
88
89 static URLSchemesMap& emptyDocumentSchemes()
90 {
91     static NeverDestroyed<URLSchemesMap> emptyDocumentSchemes;
92
93     if (emptyDocumentSchemes.get().isEmpty())
94         emptyDocumentSchemes.get().add("about");
95
96     return emptyDocumentSchemes;
97 }
98
99 static HashSet<String>& schemesForbiddenFromDomainRelaxation()
100 {
101     static NeverDestroyed<HashSet<String>> schemes;
102     return schemes;
103 }
104
105 static URLSchemesMap& canDisplayOnlyIfCanRequestSchemes()
106 {
107     static NeverDestroyed<URLSchemesMap> canDisplayOnlyIfCanRequestSchemes;
108
109     if (canDisplayOnlyIfCanRequestSchemes.get().isEmpty()) {
110         canDisplayOnlyIfCanRequestSchemes.get().add("blob");
111     }
112
113     return canDisplayOnlyIfCanRequestSchemes;
114 }
115
116 static URLSchemesMap& notAllowingJavascriptURLsSchemes()
117 {
118     static NeverDestroyed<URLSchemesMap> notAllowingJavascriptURLsSchemes;
119     return notAllowingJavascriptURLsSchemes;
120 }
121
122 void SchemeRegistry::registerURLSchemeAsLocal(const String& scheme)
123 {
124     localURLSchemes().add(scheme);
125 }
126
127 void SchemeRegistry::removeURLSchemeRegisteredAsLocal(const String& scheme)
128 {
129     if (scheme == "file")
130         return;
131 #if PLATFORM(COCOA)
132     if (scheme == "applewebdata")
133         return;
134 #endif
135     localURLSchemes().remove(scheme);
136 }
137
138 const URLSchemesMap& SchemeRegistry::localSchemes()
139 {
140     return localURLSchemes();
141 }
142
143 static URLSchemesMap& schemesAllowingLocalStorageAccessInPrivateBrowsing()
144 {
145     static NeverDestroyed<URLSchemesMap> schemesAllowingLocalStorageAccessInPrivateBrowsing;
146     return schemesAllowingLocalStorageAccessInPrivateBrowsing;
147 }
148
149 static URLSchemesMap& schemesAllowingDatabaseAccessInPrivateBrowsing()
150 {
151     static NeverDestroyed<URLSchemesMap> schemesAllowingDatabaseAccessInPrivateBrowsing;
152     return schemesAllowingDatabaseAccessInPrivateBrowsing;
153 }
154
155 static URLSchemesMap& CORSEnabledSchemes()
156 {
157     // FIXME: http://bugs.webkit.org/show_bug.cgi?id=77160
158     static NeverDestroyed<URLSchemesMap> CORSEnabledSchemes;
159
160     if (CORSEnabledSchemes.get().isEmpty()) {
161         CORSEnabledSchemes.get().add("http");
162         CORSEnabledSchemes.get().add("https");
163     }
164
165     return CORSEnabledSchemes;
166 }
167
168 static URLSchemesMap& ContentSecurityPolicyBypassingSchemes()
169 {
170     static NeverDestroyed<URLSchemesMap> schemes;
171     return schemes;
172 }
173
174 #if ENABLE(CACHE_PARTITIONING)
175 static URLSchemesMap& cachePartitioningSchemes()
176 {
177     static NeverDestroyed<URLSchemesMap> schemes;
178     return schemes;
179 }
180 #endif
181
182 bool SchemeRegistry::shouldTreatURLSchemeAsLocal(const String& scheme)
183 {
184     if (scheme.isEmpty())
185         return false;
186     return localURLSchemes().contains(scheme);
187 }
188
189 void SchemeRegistry::registerURLSchemeAsNoAccess(const String& scheme)
190 {
191     schemesWithUniqueOrigins().add(scheme);
192 }
193
194 bool SchemeRegistry::shouldTreatURLSchemeAsNoAccess(const String& scheme)
195 {
196     if (scheme.isEmpty())
197         return false;
198     return schemesWithUniqueOrigins().contains(scheme);
199 }
200
201 void SchemeRegistry::registerURLSchemeAsDisplayIsolated(const String& scheme)
202 {
203     displayIsolatedURLSchemes().add(scheme);
204 }
205
206 bool SchemeRegistry::shouldTreatURLSchemeAsDisplayIsolated(const String& scheme)
207 {
208     if (scheme.isEmpty())
209         return false;
210     return displayIsolatedURLSchemes().contains(scheme);
211 }
212
213 void SchemeRegistry::registerURLSchemeAsSecure(const String& scheme)
214 {
215     secureSchemes().add(scheme);
216 }
217
218 bool SchemeRegistry::shouldTreatURLSchemeAsSecure(const String& scheme)
219 {
220     if (scheme.isEmpty())
221         return false;
222     return secureSchemes().contains(scheme);
223 }
224
225 void SchemeRegistry::registerURLSchemeAsEmptyDocument(const String& scheme)
226 {
227     emptyDocumentSchemes().add(scheme);
228 }
229
230 bool SchemeRegistry::shouldLoadURLSchemeAsEmptyDocument(const String& scheme)
231 {
232     if (scheme.isEmpty())
233         return false;
234     return emptyDocumentSchemes().contains(scheme);
235 }
236
237 void SchemeRegistry::setDomainRelaxationForbiddenForURLScheme(bool forbidden, const String& scheme)
238 {
239     if (scheme.isEmpty())
240         return;
241
242     if (forbidden)
243         schemesForbiddenFromDomainRelaxation().add(scheme);
244     else
245         schemesForbiddenFromDomainRelaxation().remove(scheme);
246 }
247
248 bool SchemeRegistry::isDomainRelaxationForbiddenForURLScheme(const String& scheme)
249 {
250     if (scheme.isEmpty())
251         return false;
252     return schemesForbiddenFromDomainRelaxation().contains(scheme);
253 }
254
255 bool SchemeRegistry::canDisplayOnlyIfCanRequest(const String& scheme)
256 {
257     if (scheme.isEmpty())
258         return false;
259     return canDisplayOnlyIfCanRequestSchemes().contains(scheme);
260 }
261
262 void SchemeRegistry::registerAsCanDisplayOnlyIfCanRequest(const String& scheme)
263 {
264     canDisplayOnlyIfCanRequestSchemes().add(scheme);
265 }
266
267 void SchemeRegistry::registerURLSchemeAsNotAllowingJavascriptURLs(const String& scheme)
268 {
269     notAllowingJavascriptURLsSchemes().add(scheme);
270 }
271
272 bool SchemeRegistry::shouldTreatURLSchemeAsNotAllowingJavascriptURLs(const String& scheme)
273 {
274     if (scheme.isEmpty())
275         return false;
276     return notAllowingJavascriptURLsSchemes().contains(scheme);
277 }
278
279 void SchemeRegistry::registerURLSchemeAsAllowingLocalStorageAccessInPrivateBrowsing(const String& scheme)
280 {
281     schemesAllowingLocalStorageAccessInPrivateBrowsing().add(scheme);
282 }
283
284 bool SchemeRegistry::allowsLocalStorageAccessInPrivateBrowsing(const String& scheme)
285 {
286     if (scheme.isEmpty())
287         return false;
288     return schemesAllowingLocalStorageAccessInPrivateBrowsing().contains(scheme);
289 }
290
291 void SchemeRegistry::registerURLSchemeAsAllowingDatabaseAccessInPrivateBrowsing(const String& scheme)
292 {
293     schemesAllowingDatabaseAccessInPrivateBrowsing().add(scheme);
294 }
295
296 bool SchemeRegistry::allowsDatabaseAccessInPrivateBrowsing(const String& scheme)
297 {
298     if (scheme.isEmpty())
299         return false;
300     return schemesAllowingDatabaseAccessInPrivateBrowsing().contains(scheme);
301 }
302
303 void SchemeRegistry::registerURLSchemeAsCORSEnabled(const String& scheme)
304 {
305     CORSEnabledSchemes().add(scheme);
306 }
307
308 bool SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(const String& scheme)
309 {
310     if (scheme.isEmpty())
311         return false;
312     return CORSEnabledSchemes().contains(scheme);
313 }
314
315 void SchemeRegistry::registerURLSchemeAsBypassingContentSecurityPolicy(const String& scheme)
316 {
317     ContentSecurityPolicyBypassingSchemes().add(scheme);
318 }
319
320 void SchemeRegistry::removeURLSchemeRegisteredAsBypassingContentSecurityPolicy(const String& scheme)
321 {
322     ContentSecurityPolicyBypassingSchemes().remove(scheme);
323 }
324
325 bool SchemeRegistry::schemeShouldBypassContentSecurityPolicy(const String& scheme)
326 {
327     if (scheme.isEmpty())
328         return false;
329     return ContentSecurityPolicyBypassingSchemes().contains(scheme);
330 }
331
332 bool SchemeRegistry::shouldCacheResponsesFromURLSchemeIndefinitely(const String& scheme)
333 {
334 #if PLATFORM(COCOA)
335     if (equalIgnoringCase(scheme, "applewebdata"))
336         return true;
337 #endif
338     return equalIgnoringCase(scheme, "data");
339 }
340
341 #if ENABLE(CACHE_PARTITIONING)
342 void SchemeRegistry::registerURLSchemeAsCachePartitioned(const String& scheme)
343 {
344     cachePartitioningSchemes().add(scheme);
345 }
346
347 bool SchemeRegistry::shouldPartitionCacheForURLScheme(const String& scheme)
348 {
349     if (scheme.isEmpty())
350         return false;
351     return cachePartitioningSchemes().contains(scheme);
352 }
353 #endif
354
355 } // namespace WebCore