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 <WebCore/ResourceResponse.h>
32#include <wtf/CompletionHandler.h>
33#include <wtf/OptionSet.h>
34#include <wtf/Seconds.h>
35#include <wtf/text/WTFString.h>
36
37namespace WebCore {
38class LowPowerModeNotifier;
39class ResourceRequest;
40class SharedBuffer;
41}
42
43namespace WebKit {
44
45class NetworkProcess;
46
47namespace NetworkCache {
48
49class Cache;
50class SpeculativeLoadManager;
51
52struct MappedBody {
53#if ENABLE(SHAREABLE_RESOURCE)
54 RefPtr<ShareableResource> shareableResource;
55 ShareableResource::Handle shareableResourceHandle;
56#endif
57};
58
59enum class RetrieveDecision {
60 Yes,
61 NoDueToHTTPMethod,
62 NoDueToConditionalRequest,
63 NoDueToReloadIgnoringCache,
64 NoDueToStreamingMedia,
65};
66
67enum class StoreDecision {
68 Yes,
69 NoDueToProtocol,
70 NoDueToHTTPMethod,
71 NoDueToNoStoreResponse,
72 NoDueToHTTPStatusCode,
73 NoDueToNoStoreRequest,
74 NoDueToUnlikelyToReuse,
75 NoDueToStreamingMedia,
76};
77
78enum class UseDecision {
79 Use,
80 Validate,
81 NoDueToVaryingHeaderMismatch,
82 NoDueToMissingValidatorFields,
83 NoDueToDecodeFailure,
84 NoDueToExpiredRedirect
85};
86
87using GlobalFrameID = std::pair<uint64_t /*webPageID*/, uint64_t /*webFrameID*/>;
88
89class Cache : public RefCounted<Cache> {
90public:
91 enum class Option {
92 // In testing mode we try to eliminate sources of randomness. Cache does not shrink and there are no read timeouts.
93 TestingMode = 1 << 0,
94 RegisterNotify = 1 << 1,
95#if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
96 SpeculativeRevalidation = 1 << 2,
97#endif
98 };
99 static RefPtr<Cache> open(NetworkProcess&, const String& cachePath, OptionSet<Option>);
100
101 void setCapacity(size_t);
102
103 // Completion handler may get called back synchronously on failure.
104 struct RetrieveInfo {
105 MonotonicTime startTime;
106 MonotonicTime completionTime;
107 unsigned priority;
108 Storage::Timings storageTimings;
109 bool wasSpeculativeLoad { false };
110
111 WTF_MAKE_FAST_ALLOCATED;
112 };
113 using RetrieveCompletionHandler = Function<void(std::unique_ptr<Entry>, const RetrieveInfo&)>;
114 void retrieve(const WebCore::ResourceRequest&, const GlobalFrameID&, RetrieveCompletionHandler&&);
115 std::unique_ptr<Entry> store(const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, RefPtr<WebCore::SharedBuffer>&&, Function<void(MappedBody&)>&&);
116 std::unique_ptr<Entry> storeRedirect(const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, const WebCore::ResourceRequest& redirectRequest, Optional<Seconds> maxAgeCap);
117 std::unique_ptr<Entry> update(const WebCore::ResourceRequest&, const GlobalFrameID&, const Entry&, const WebCore::ResourceResponse& validatingResponse);
118
119 struct TraversalEntry {
120 const Entry& entry;
121 const Storage::RecordInfo& recordInfo;
122 };
123 void traverse(Function<void(const TraversalEntry*)>&&);
124 void remove(const Key&);
125 void remove(const WebCore::ResourceRequest&);
126 void remove(const Vector<Key>&, Function<void()>&&);
127
128 void clear();
129 void clear(WallTime modifiedSince, Function<void()>&&);
130
131 void retrieveData(const DataKey&, Function<void(const uint8_t*, size_t)>);
132 void storeData(const DataKey&, const uint8_t* data, size_t);
133
134 std::unique_ptr<Entry> makeEntry(const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, RefPtr<WebCore::SharedBuffer>&&);
135 std::unique_ptr<Entry> makeRedirectEntry(const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, const WebCore::ResourceRequest& redirectRequest);
136
137 void dumpContentsToFile();
138
139 String recordsPath() const;
140
141#if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
142 SpeculativeLoadManager* speculativeLoadManager() { return m_speculativeLoadManager.get(); }
143#endif
144
145 NetworkProcess& networkProcess() { return m_networkProcess.get(); }
146
147 ~Cache();
148
149private:
150 Cache(NetworkProcess&, Ref<Storage>&&, OptionSet<Option> options);
151
152 Key makeCacheKey(const WebCore::ResourceRequest&);
153
154 static void completeRetrieve(RetrieveCompletionHandler&&, std::unique_ptr<Entry>, RetrieveInfo&);
155
156 String dumpFilePath() const;
157 void deleteDumpFile();
158
159 Optional<Seconds> maxAgeCap(Entry&, const WebCore::ResourceRequest&, PAL::SessionID);
160
161 Ref<Storage> m_storage;
162 Ref<NetworkProcess> m_networkProcess;
163
164#if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
165 std::unique_ptr<WebCore::LowPowerModeNotifier> m_lowPowerModeNotifier;
166 std::unique_ptr<SpeculativeLoadManager> m_speculativeLoadManager;
167#endif
168
169 unsigned m_traverseCount { 0 };
170};
171
172} // namespace NetworkCache
173} // namespace WebKit
174