Update ANGLE
[WebKit-https.git] / Source / WebKit / NetworkProcess / cache / NetworkCache.h
1 /*
2  * Copyright (C) 2014-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. 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 #pragma once
27
28 #include "NetworkCacheEntry.h"
29 #include "NetworkCacheStorage.h"
30 #include "ShareableResource.h"
31 #include "WebPageProxyIdentifier.h"
32 #include <WebCore/FrameIdentifier.h>
33 #include <WebCore/PageIdentifier.h>
34 #include <WebCore/ResourceResponse.h>
35 #include <wtf/CompletionHandler.h>
36 #include <wtf/OptionSet.h>
37 #include <wtf/Seconds.h>
38 #include <wtf/text/WTFString.h>
39
40 namespace WebCore {
41 class LowPowerModeNotifier;
42 class ResourceRequest;
43 class SharedBuffer;
44 }
45
46 namespace WebKit {
47
48 class NetworkProcess;
49
50 namespace NetworkCache {
51
52 class Cache;
53 class SpeculativeLoadManager;
54
55 struct MappedBody {
56 #if ENABLE(SHAREABLE_RESOURCE)
57     RefPtr<ShareableResource> shareableResource;
58     ShareableResource::Handle shareableResourceHandle;
59 #endif
60 };
61
62 enum class RetrieveDecision {
63     Yes,
64     NoDueToHTTPMethod,
65     NoDueToConditionalRequest,
66     NoDueToReloadIgnoringCache,
67     NoDueToStreamingMedia,
68 };
69
70 enum class StoreDecision {
71     Yes,
72     NoDueToProtocol,
73     NoDueToHTTPMethod,
74     NoDueToNoStoreResponse,
75     NoDueToHTTPStatusCode,
76     NoDueToNoStoreRequest,
77     NoDueToUnlikelyToReuse,
78     NoDueToStreamingMedia,
79 };
80
81 enum class UseDecision {
82     Use,
83     Validate,
84     NoDueToVaryingHeaderMismatch,
85     NoDueToMissingValidatorFields,
86     NoDueToDecodeFailure,
87     NoDueToExpiredRedirect
88 };
89
90 struct GlobalFrameID {
91     WebPageProxyIdentifier webPageProxyID;
92     WebCore::PageIdentifier webPageID;
93     WebCore::FrameIdentifier frameID;
94     
95     unsigned hash() const;
96 };
97
98 inline unsigned GlobalFrameID::hash() const
99 {
100     unsigned hashes[2];
101     hashes[0] = WTF::intHash(webPageID.toUInt64());
102     hashes[1] = WTF::intHash(frameID.toUInt64());
103
104     return StringHasher::hashMemory(hashes, sizeof(hashes));
105 }
106
107 inline bool operator==(const GlobalFrameID& a, const GlobalFrameID& b)
108 {
109     // No need to check webPageProxyID since webPageIDs are globally unique and a given WebPage is always
110     // associated with the same WebPageProxy.
111     return a.webPageID == b.webPageID &&  a.frameID == b.frameID;
112 }
113
114 enum class CacheOption : uint8_t {
115     // In testing mode we try to eliminate sources of randomness. Cache does not shrink and there are no read timeouts.
116     TestingMode = 1 << 0,
117     RegisterNotify = 1 << 1,
118 #if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
119     SpeculativeRevalidation = 1 << 2,
120 #endif
121 };
122
123 class Cache : public RefCounted<Cache> {
124 public:
125     static RefPtr<Cache> open(NetworkProcess&, const String& cachePath, OptionSet<CacheOption>, PAL::SessionID);
126
127     void setCapacity(size_t);
128
129     // Completion handler may get called back synchronously on failure.
130     struct RetrieveInfo {
131         MonotonicTime startTime;
132         MonotonicTime completionTime;
133         unsigned priority;
134         Storage::Timings storageTimings;
135         bool wasSpeculativeLoad { false };
136
137         WTF_MAKE_FAST_ALLOCATED;
138     };
139     using RetrieveCompletionHandler = Function<void(std::unique_ptr<Entry>, const RetrieveInfo&)>;
140     void retrieve(const WebCore::ResourceRequest&, const GlobalFrameID&, RetrieveCompletionHandler&&);
141     std::unique_ptr<Entry> store(const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, RefPtr<WebCore::SharedBuffer>&&, Function<void(MappedBody&)>&& = nullptr);
142     std::unique_ptr<Entry> storeRedirect(const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, const WebCore::ResourceRequest& redirectRequest, Optional<Seconds> maxAgeCap);
143     std::unique_ptr<Entry> update(const WebCore::ResourceRequest&, const GlobalFrameID&, const Entry&, const WebCore::ResourceResponse& validatingResponse);
144
145     struct TraversalEntry {
146         const Entry& entry;
147         const Storage::RecordInfo& recordInfo;
148     };
149     void traverse(Function<void(const TraversalEntry*)>&&);
150     void remove(const Key&);
151     void remove(const WebCore::ResourceRequest&);
152     void remove(const Vector<Key>&, Function<void()>&&);
153
154     void clear();
155     void clear(WallTime modifiedSince, Function<void()>&&);
156
157     void retrieveData(const DataKey&, Function<void(const uint8_t*, size_t)>);
158     void storeData(const DataKey&,  const uint8_t* data, size_t);
159     
160     std::unique_ptr<Entry> makeEntry(const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, RefPtr<WebCore::SharedBuffer>&&);
161     std::unique_ptr<Entry> makeRedirectEntry(const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, const WebCore::ResourceRequest& redirectRequest);
162
163     void dumpContentsToFile();
164
165     String recordsPathIsolatedCopy() const;
166
167 #if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
168     SpeculativeLoadManager* speculativeLoadManager() { return m_speculativeLoadManager.get(); }
169 #endif
170
171     NetworkProcess& networkProcess() { return m_networkProcess.get(); }
172     const PAL::SessionID& sessionID() const { return m_sessionID; }
173
174     ~Cache();
175
176 private:
177     Cache(NetworkProcess&, Ref<Storage>&&, OptionSet<CacheOption>, PAL::SessionID);
178
179     Key makeCacheKey(const WebCore::ResourceRequest&);
180
181     static void completeRetrieve(RetrieveCompletionHandler&&, std::unique_ptr<Entry>, RetrieveInfo&);
182
183     String dumpFilePath() const;
184     void deleteDumpFile();
185
186     Optional<Seconds> maxAgeCap(Entry&, const WebCore::ResourceRequest&, PAL::SessionID);
187
188     Ref<Storage> m_storage;
189     Ref<NetworkProcess> m_networkProcess;
190
191 #if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
192     std::unique_ptr<WebCore::LowPowerModeNotifier> m_lowPowerModeNotifier;
193     std::unique_ptr<SpeculativeLoadManager> m_speculativeLoadManager;
194 #endif
195
196     unsigned m_traverseCount { 0 };
197     PAL::SessionID m_sessionID;
198 };
199
200 } // namespace NetworkCache
201 } // namespace WebKit
202
203 namespace WTF {
204
205 struct GlobalFrameIDHash {
206     static unsigned hash(const WebKit::NetworkCache::GlobalFrameID& key) { return key.hash(); }
207     static bool equal(const WebKit::NetworkCache::GlobalFrameID& a, const WebKit::NetworkCache::GlobalFrameID& b) { return a == b; }
208     static const bool safeToCompareToEmptyOrDeleted = true;
209 };
210
211 template<> struct HashTraits<WebKit::NetworkCache::GlobalFrameID> : GenericHashTraits<WebKit::NetworkCache::GlobalFrameID> {
212     static WebKit::NetworkCache::GlobalFrameID emptyValue() { return { }; }
213
214     static void constructDeletedValue(WebKit::NetworkCache::GlobalFrameID& slot) { slot.webPageID = makeObjectIdentifier<WebCore::PageIdentifierType>(std::numeric_limits<uint64_t>::max()); }
215
216     static bool isDeletedValue(const WebKit::NetworkCache::GlobalFrameID& slot) { return slot.webPageID.toUInt64() == std::numeric_limits<uint64_t>::max(); }
217 };
218
219 template<> struct DefaultHash<WebKit::NetworkCache::GlobalFrameID> {
220     typedef GlobalFrameIDHash Hash;
221 };
222
223 }