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