2 * Copyright (C) 2014, 2016 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
27 #include "APIWebsiteDataStore.h"
29 #include "SandboxExtension.h"
30 #include "SandboxUtilities.h"
33 #import <WebCore/RuntimeApplicationChecks.h>
38 String WebsiteDataStore::defaultApplicationCacheDirectory()
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"];
48 return WebKit::stringByResolvingSymlinksInPath(cachePath.stringByStandardizingPath);
52 return cacheDirectoryFileSystemRepresentation("OfflineWebApplicationCache");
55 String WebsiteDataStore::defaultCacheStorageDirectory()
57 return cacheDirectoryFileSystemRepresentation("CacheStorage");
60 String WebsiteDataStore::defaultNetworkCacheDirectory()
62 return cacheDirectoryFileSystemRepresentation("NetworkCache");
65 String WebsiteDataStore::defaultMediaCacheDirectory()
67 return tempDirectoryFileSystemRepresentation("MediaCache");
70 String WebsiteDataStore::defaultIndexedDBDatabaseDirectory()
72 return websiteDataDirectoryFileSystemRepresentation("IndexedDB");
75 String WebsiteDataStore::defaultServiceWorkerRegistrationDirectory()
77 return websiteDataDirectoryFileSystemRepresentation("ServiceWorkers");
80 String WebsiteDataStore::defaultLocalStorageDirectory()
82 return websiteDataDirectoryFileSystemRepresentation("LocalStorage");
85 String WebsiteDataStore::defaultMediaKeysStorageDirectory()
87 return websiteDataDirectoryFileSystemRepresentation("MediaKeys");
90 String WebsiteDataStore::defaultWebSQLDatabaseDirectory()
92 return websiteDataDirectoryFileSystemRepresentation("WebSQL");
95 String WebsiteDataStore::defaultResourceLoadStatisticsDirectory()
97 return websiteDataDirectoryFileSystemRepresentation("ResourceLoadStatistics");
100 String WebsiteDataStore::defaultJavaScriptConfigurationDirectory()
102 return tempDirectoryFileSystemRepresentation("JavaScriptCoreDebug", DontCreateDirectory);
105 String WebsiteDataStore::tempDirectoryFileSystemRepresentation(const String& directoryName, ShouldCreateDirectory shouldCreateDirectory)
107 static dispatch_once_t onceToken;
108 static NSURL *tempURL;
110 dispatch_once(&onceToken, ^{
111 NSURL *url = [NSURL fileURLWithPath:NSTemporaryDirectory()];
113 RELEASE_ASSERT_NOT_REACHED();
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];
122 tempURL = [[url URLByAppendingPathComponent:@"WebKit" isDirectory:YES] retain];
125 NSURL *url = [tempURL URLByAppendingPathComponent:directoryName isDirectory:YES];
127 if (shouldCreateDirectory == CreateDirectory
128 && (![[NSFileManager defaultManager] createDirectoryAtURL:url withIntermediateDirectories:YES attributes:nil error:nullptr]))
129 LOG_ERROR("Failed to create directory %@", url);
131 return url.absoluteURL.path.fileSystemRepresentation;
134 String WebsiteDataStore::cacheDirectoryFileSystemRepresentation(const String& directoryName)
136 static dispatch_once_t onceToken;
137 static NSURL *cacheURL;
139 dispatch_once(&onceToken, ^{
140 NSURL *url = [[NSFileManager defaultManager] URLForDirectory:NSCachesDirectory inDomain:NSUserDomainMask appropriateForURL:nullptr create:NO error:nullptr];
142 RELEASE_ASSERT_NOT_REACHED();
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];
151 cacheURL = [[url URLByAppendingPathComponent:@"WebKit" isDirectory:YES] retain];
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);
158 return url.absoluteURL.path.fileSystemRepresentation;
161 String WebsiteDataStore::websiteDataDirectoryFileSystemRepresentation(const String& directoryName)
163 static dispatch_once_t onceToken;
164 static NSURL *websiteDataURL;
166 dispatch_once(&onceToken, ^{
167 NSURL *url = [[NSFileManager defaultManager] URLForDirectory:NSLibraryDirectory inDomain:NSUserDomainMask appropriateForURL:nullptr create:NO error:nullptr];
169 RELEASE_ASSERT_NOT_REACHED();
171 url = [url URLByAppendingPathComponent:@"WebKit" isDirectory:YES];
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];
180 websiteDataURL = [[url URLByAppendingPathComponent:@"WebsiteData" isDirectory:YES] retain];
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);
187 return url.absoluteURL.path.fileSystemRepresentation;
190 WebKit::WebsiteDataStore::Configuration WebsiteDataStore::defaultDataStoreConfiguration()
192 WebKit::WebsiteDataStore::Configuration configuration;
194 configuration.applicationCacheDirectory = defaultApplicationCacheDirectory();
195 configuration.applicationCacheFlatFileSubdirectoryName = "Files";
196 configuration.cacheStorageDirectory = defaultCacheStorageDirectory();
197 configuration.networkCacheDirectory = defaultNetworkCacheDirectory();
198 configuration.mediaCacheDirectory = defaultMediaCacheDirectory();
200 configuration.indexedDBDatabaseDirectory = defaultIndexedDBDatabaseDirectory();
201 configuration.serviceWorkerRegistrationDirectory = defaultServiceWorkerRegistrationDirectory();
202 configuration.webSQLDatabaseDirectory = defaultWebSQLDatabaseDirectory();
203 configuration.localStorageDirectory = defaultLocalStorageDirectory();
204 configuration.mediaKeysStorageDirectory = defaultMediaKeysStorageDirectory();
205 configuration.resourceLoadStatisticsDirectory = defaultResourceLoadStatisticsDirectory();
207 configuration.javaScriptConfigurationDirectory = defaultJavaScriptConfigurationDirectory();
209 return configuration;