e92fc3c2545a57c913a75a65723099d243019b4e
[WebKit-https.git] / Source / WebKit / UIProcess / API / Cocoa / APIWebsiteDataStoreCocoa.mm
1 /*
2  * Copyright (C) 2014, 2016 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. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "APIWebsiteDataStore.h"
28
29 #include "SandboxExtension.h"
30 #include "SandboxUtilities.h"
31
32 #if PLATFORM(IOS)
33 #import <WebCore/RuntimeApplicationChecks.h>
34 #endif
35
36 namespace API {
37
38 String WebsiteDataStore::defaultApplicationCacheDirectory()
39 {
40 #if PLATFORM(IOS)
41     // This quirk used to make these apps share application cache storage, but doesn't accomplish that any more.
42     // Preserving it avoids the need to migrate data when upgrading.
43     // FIXME: Ideally we should just have Safari, WebApp, and webbookmarksd create a data store with
44     // this application cache path, but that's not supported as of right now.
45     if (WebCore::IOSApplication::isMobileSafari() || WebCore::IOSApplication::isWebApp() || WebCore::IOSApplication::isWebBookmarksD()) {
46         NSString *cachePath = [NSHomeDirectory() stringByAppendingPathComponent:@"Library/Caches/com.apple.WebAppCache"];
47
48         return WebKit::stringByResolvingSymlinksInPath(cachePath.stringByStandardizingPath);
49     }
50 #endif
51
52     return cacheDirectoryFileSystemRepresentation("OfflineWebApplicationCache");
53 }
54
55 String WebsiteDataStore::defaultCacheStorageDirectory()
56 {
57     return cacheDirectoryFileSystemRepresentation("CacheStorage");
58 }
59
60 String WebsiteDataStore::defaultNetworkCacheDirectory()
61 {
62     return cacheDirectoryFileSystemRepresentation("NetworkCache");
63 }
64
65 String WebsiteDataStore::defaultMediaCacheDirectory()
66 {
67     return tempDirectoryFileSystemRepresentation("MediaCache");
68 }
69
70 String WebsiteDataStore::defaultIndexedDBDatabaseDirectory()
71 {
72     return websiteDataDirectoryFileSystemRepresentation("IndexedDB");
73 }
74
75 String WebsiteDataStore::defaultServiceWorkerRegistrationDirectory()
76 {
77     return websiteDataDirectoryFileSystemRepresentation("ServiceWorkers");
78 }
79
80 String WebsiteDataStore::defaultLocalStorageDirectory()
81 {
82     return websiteDataDirectoryFileSystemRepresentation("LocalStorage");
83 }
84
85 String WebsiteDataStore::defaultMediaKeysStorageDirectory()
86 {
87     return websiteDataDirectoryFileSystemRepresentation("MediaKeys");
88 }
89
90 String WebsiteDataStore::defaultWebSQLDatabaseDirectory()
91 {
92     return websiteDataDirectoryFileSystemRepresentation("WebSQL");
93 }
94
95 String WebsiteDataStore::defaultResourceLoadStatisticsDirectory()
96 {
97     return websiteDataDirectoryFileSystemRepresentation("ResourceLoadStatistics");
98 }
99
100 String WebsiteDataStore::defaultJavaScriptConfigurationDirectory()
101 {
102     return tempDirectoryFileSystemRepresentation("JavaScriptCoreDebug", DontCreateDirectory);
103 }
104
105 String WebsiteDataStore::tempDirectoryFileSystemRepresentation(const String& directoryName, ShouldCreateDirectory shouldCreateDirectory)
106 {
107     static dispatch_once_t onceToken;
108     static NSURL *tempURL;
109     
110     dispatch_once(&onceToken, ^{
111         NSURL *url = [NSURL fileURLWithPath:NSTemporaryDirectory()];
112         if (!url)
113             RELEASE_ASSERT_NOT_REACHED();
114         
115         if (!WebKit::processHasContainer()) {
116             NSString *bundleIdentifier = [NSBundle mainBundle].bundleIdentifier;
117             if (!bundleIdentifier)
118                 bundleIdentifier = [NSProcessInfo processInfo].processName;
119             url = [url URLByAppendingPathComponent:bundleIdentifier isDirectory:YES];
120         }
121         
122         tempURL = [[url URLByAppendingPathComponent:@"WebKit" isDirectory:YES] retain];
123     });
124     
125     NSURL *url = [tempURL URLByAppendingPathComponent:directoryName isDirectory:YES];
126
127     if (shouldCreateDirectory == CreateDirectory
128         && (![[NSFileManager defaultManager] createDirectoryAtURL:url withIntermediateDirectories:YES attributes:nil error:nullptr]))
129         LOG_ERROR("Failed to create directory %@", url);
130     
131     return url.absoluteURL.path.fileSystemRepresentation;
132 }
133
134 String WebsiteDataStore::cacheDirectoryFileSystemRepresentation(const String& directoryName)
135 {
136     static dispatch_once_t onceToken;
137     static NSURL *cacheURL;
138
139     dispatch_once(&onceToken, ^{
140         NSURL *url = [[NSFileManager defaultManager] URLForDirectory:NSCachesDirectory inDomain:NSUserDomainMask appropriateForURL:nullptr create:NO error:nullptr];
141         if (!url)
142             RELEASE_ASSERT_NOT_REACHED();
143
144         if (!WebKit::processHasContainer()) {
145             NSString *bundleIdentifier = [NSBundle mainBundle].bundleIdentifier;
146             if (!bundleIdentifier)
147                 bundleIdentifier = [NSProcessInfo processInfo].processName;
148             url = [url URLByAppendingPathComponent:bundleIdentifier isDirectory:YES];
149         }
150
151         cacheURL = [[url URLByAppendingPathComponent:@"WebKit" isDirectory:YES] retain];
152     });
153
154     NSURL *url = [cacheURL URLByAppendingPathComponent:directoryName isDirectory:YES];
155     if (![[NSFileManager defaultManager] createDirectoryAtURL:url withIntermediateDirectories:YES attributes:nil error:nullptr])
156         LOG_ERROR("Failed to create directory %@", url);
157
158     return url.absoluteURL.path.fileSystemRepresentation;
159 }
160
161 String WebsiteDataStore::websiteDataDirectoryFileSystemRepresentation(const String& directoryName)
162 {
163     static dispatch_once_t onceToken;
164     static NSURL *websiteDataURL;
165
166     dispatch_once(&onceToken, ^{
167         NSURL *url = [[NSFileManager defaultManager] URLForDirectory:NSLibraryDirectory inDomain:NSUserDomainMask appropriateForURL:nullptr create:NO error:nullptr];
168         if (!url)
169             RELEASE_ASSERT_NOT_REACHED();
170
171         url = [url URLByAppendingPathComponent:@"WebKit" isDirectory:YES];
172
173         if (!WebKit::processHasContainer()) {
174             NSString *bundleIdentifier = [NSBundle mainBundle].bundleIdentifier;
175             if (!bundleIdentifier)
176                 bundleIdentifier = [NSProcessInfo processInfo].processName;
177             url = [url URLByAppendingPathComponent:bundleIdentifier isDirectory:YES];
178         }
179
180         websiteDataURL = [[url URLByAppendingPathComponent:@"WebsiteData" isDirectory:YES] retain];
181     });
182
183     NSURL *url = [websiteDataURL URLByAppendingPathComponent:directoryName isDirectory:YES];
184     if (![[NSFileManager defaultManager] createDirectoryAtURL:url withIntermediateDirectories:YES attributes:nil error:nullptr])
185         LOG_ERROR("Failed to create directory %@", url);
186
187     return url.absoluteURL.path.fileSystemRepresentation;
188 }
189
190 WebKit::WebsiteDataStore::Configuration WebsiteDataStore::defaultDataStoreConfiguration()
191 {
192     WebKit::WebsiteDataStore::Configuration configuration;
193
194     configuration.applicationCacheDirectory = defaultApplicationCacheDirectory();
195     configuration.applicationCacheFlatFileSubdirectoryName = "Files";
196     configuration.cacheStorageDirectory = defaultCacheStorageDirectory();
197     configuration.networkCacheDirectory = defaultNetworkCacheDirectory();
198     configuration.mediaCacheDirectory = defaultMediaCacheDirectory();
199
200     configuration.webSQLDatabaseDirectory = defaultWebSQLDatabaseDirectory();
201     configuration.localStorageDirectory = defaultLocalStorageDirectory();
202     configuration.mediaKeysStorageDirectory = defaultMediaKeysStorageDirectory();
203     configuration.resourceLoadStatisticsDirectory = defaultResourceLoadStatisticsDirectory();
204     
205     configuration.javaScriptConfigurationDirectory = defaultJavaScriptConfigurationDirectory();
206
207     return configuration;
208 }
209
210 }