Move URL from WebCore to WTF
[WebKit-https.git] / Source / WebCore / loader / appcache / ApplicationCacheStorage.h
1 /*
2  * Copyright (C) 2008-2017 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 #pragma once
27
28 #include "SecurityOriginHash.h"
29 #include "SQLiteDatabase.h"
30 #include <wtf/HashCountedSet.h>
31 #include <wtf/HashSet.h>
32 #include <wtf/text/StringHash.h>
33 #include <wtf/text/WTFString.h>
34
35 namespace WebCore {
36
37 class ApplicationCache;
38 class ApplicationCacheGroup;
39 class ApplicationCacheHost;
40 class ApplicationCacheResource;
41 class SecurityOrigin;
42 class SharedBuffer;
43 template<typename> class StorageIDJournal;
44
45 class ApplicationCacheStorage : public RefCounted<ApplicationCacheStorage> {
46 public:
47     enum FailureReason {
48         OriginQuotaReached,
49         TotalQuotaReached,
50         DiskOrOperationFailure
51     };
52
53     static Ref<ApplicationCacheStorage> create(const String& cacheDirectory, const String& flatFileSubdirectoryName)
54     {
55         return adoptRef(*new ApplicationCacheStorage(cacheDirectory, flatFileSubdirectoryName));
56     }
57
58
59     WEBCORE_EXPORT void setMaximumSize(int64_t size);
60     WEBCORE_EXPORT int64_t maximumSize() const;
61     bool isMaximumSizeReached() const;
62     int64_t spaceNeeded(int64_t cacheToSave);
63
64     int64_t defaultOriginQuota() const { return m_defaultOriginQuota; }
65     WEBCORE_EXPORT void setDefaultOriginQuota(int64_t quota);
66     WEBCORE_EXPORT bool calculateUsageForOrigin(const SecurityOrigin*, int64_t& usage);
67     WEBCORE_EXPORT bool calculateQuotaForOrigin(const SecurityOrigin&, int64_t& quota);
68     bool calculateRemainingSizeForOriginExcludingCache(const SecurityOrigin&, ApplicationCache*, int64_t& remainingSize);
69     WEBCORE_EXPORT bool storeUpdatedQuotaForOrigin(const SecurityOrigin*, int64_t quota);
70     bool checkOriginQuota(ApplicationCacheGroup*, ApplicationCache* oldCache, ApplicationCache* newCache, int64_t& totalSpaceNeeded);
71
72     ApplicationCacheGroup* cacheGroupForURL(const URL&); // Cache to load a main resource from.
73     ApplicationCacheGroup* fallbackCacheGroupForURL(const URL&); // Cache that has a fallback entry to load a main resource from if normal loading fails.
74
75     ApplicationCacheGroup* findOrCreateCacheGroup(const URL& manifestURL);
76     void cacheGroupDestroyed(ApplicationCacheGroup&);
77     void cacheGroupMadeObsolete(ApplicationCacheGroup&);
78
79     bool storeNewestCache(ApplicationCacheGroup&, ApplicationCache* oldCache, FailureReason&);
80     bool storeNewestCache(ApplicationCacheGroup&); // Updates the cache group, but doesn't remove old cache.
81     bool store(ApplicationCacheResource*, ApplicationCache*);
82     bool storeUpdatedType(ApplicationCacheResource*, ApplicationCache*);
83
84     // Removes the group if the cache to be removed is the newest one (so, storeNewestCache() needs to be called beforehand when updating).
85     void remove(ApplicationCache*);
86
87     WEBCORE_EXPORT void empty();
88
89     WEBCORE_EXPORT Vector<Ref<SecurityOrigin>> originsWithCache();
90     WEBCORE_EXPORT void deleteAllEntries();
91
92     // FIXME: This should be consolidated with deleteAllEntries().
93     WEBCORE_EXPORT void deleteAllCaches();
94
95     // FIXME: This should be consolidated with deleteCacheGroup().
96     WEBCORE_EXPORT void deleteCacheForOrigin(const SecurityOrigin&);
97
98     // FIXME: This should be consolidated with calculateUsageForOrigin().
99     WEBCORE_EXPORT int64_t diskUsageForOrigin(const SecurityOrigin&);
100
101     static int64_t unknownQuota() { return -1; }
102     static int64_t noQuota() { return std::numeric_limits<int64_t>::max(); }
103
104 private:
105     WEBCORE_EXPORT ApplicationCacheStorage(const String& cacheDirectory, const String& flatFileSubdirectoryName);
106
107     RefPtr<ApplicationCache> loadCache(unsigned storageID);
108     ApplicationCacheGroup* loadCacheGroup(const URL& manifestURL);
109     std::optional<Vector<URL>> manifestURLs();
110     ApplicationCacheGroup* findInMemoryCacheGroup(const URL& manifestURL) const;
111     bool deleteCacheGroup(const String& manifestURL);
112     void vacuumDatabaseFile();
113     
114     using ResourceStorageIDJournal = StorageIDJournal<ApplicationCacheResource>;
115     using GroupStorageIDJournal = StorageIDJournal<ApplicationCacheGroup>;
116
117     bool store(ApplicationCacheGroup*, GroupStorageIDJournal*);
118     bool store(ApplicationCache*, ResourceStorageIDJournal*);
119     bool store(ApplicationCacheResource*, unsigned cacheStorageID);
120     bool deleteCacheGroupRecord(const String& manifestURL);
121
122     bool ensureOriginRecord(const SecurityOrigin*);
123     static bool shouldStoreResourceAsFlatFile(ApplicationCacheResource*);
124     void deleteTables();
125     bool writeDataToUniqueFileInDirectory(SharedBuffer&, const String& directory, String& outFilename, const String& fileExtension);
126
127     void loadManifestHostHashes();
128     
129     void verifySchemaVersion();
130     
131     void openDatabase(bool createIfDoesNotExist);
132     
133     bool executeStatement(SQLiteStatement&);
134     bool executeSQLCommand(const String&);
135
136     void checkForMaxSizeReached();
137     void checkForDeletedResources();
138     long long flatFileAreaSize();
139
140     const String m_cacheDirectory;
141     const String m_flatFileSubdirectoryName;
142     String m_cacheFile;
143
144     int64_t m_maximumSize { noQuota() };
145     bool m_isMaximumSizeReached { false };
146
147     int64_t m_defaultOriginQuota { noQuota() };
148
149     SQLiteDatabase m_database;
150
151     // In order to quickly determine if a given resource exists in an application cache,
152     // we keep a hash set of the hosts of the manifest URLs of all non-obsolete cache groups.
153     HashCountedSet<unsigned, AlreadyHashed> m_cacheHostSet;
154     
155     HashMap<String, ApplicationCacheGroup*> m_cachesInMemory; // Excludes obsolete cache groups.
156
157     friend class WTF::NeverDestroyed<ApplicationCacheStorage>;
158 };
159
160 } // namespace WebCore