1/*
2 * Copyright (C) 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 "NetworkCacheStorage.h"
29#include <WebCore/DOMCacheEngine.h>
30#include <wtf/Vector.h>
31#include <wtf/text/WTFString.h>
32
33namespace WebKit {
34
35namespace CacheStorage {
36
37class Caches;
38
39struct RecordInformation {
40 NetworkCache::Key key;
41 double insertionTime { 0 };
42
43 uint64_t identifier { 0 };
44 uint64_t updateResponseCounter { 0 };
45
46 uint64_t size { 0 };
47
48 URL url;
49 bool hasVaryStar { false };
50 HashMap<String, String> varyHeaders;
51};
52
53class AsynchronousPutTaskCounter;
54class ReadRecordTaskCounter;
55
56class Cache {
57public:
58 enum class State { Uninitialized, Opening, Open };
59 Cache(Caches&, uint64_t identifier, State, String&& name, String&& uniqueName);
60
61 bool isOpened() const { return m_state == State::Open; }
62 void open(WebCore::DOMCacheEngine::CompletionCallback&&);
63
64 uint64_t identifier() const { return m_identifier; }
65 const String& name() const { return m_name; }
66 const String& uniqueName() const { return m_uniqueName; }
67 bool isActive() const { return m_state != State::Uninitialized; }
68
69 void retrieveRecords(const URL&, WebCore::DOMCacheEngine::RecordsCallback&&);
70 WebCore::DOMCacheEngine::CacheInfo info() const { return { m_identifier, m_name }; }
71
72 void put(Vector<WebCore::DOMCacheEngine::Record>&&, WebCore::DOMCacheEngine::RecordIdentifiersCallback&&);
73 void remove(WebCore::ResourceRequest&&, WebCore::CacheQueryOptions&&, WebCore::DOMCacheEngine::RecordIdentifiersCallback&&);
74
75 Vector<NetworkCache::Key> keys() const;
76
77 void dispose();
78 void clearMemoryRepresentation();
79
80 static Optional<WebCore::DOMCacheEngine::Record> decode(const NetworkCache::Storage::Record&);
81 static NetworkCache::Storage::Record encode(const RecordInformation&, const WebCore::DOMCacheEngine::Record&);
82
83 struct DecodedRecord {
84 DecodedRecord(double insertionTime, uint64_t size, WebCore::DOMCacheEngine::Record&& record)
85 : insertionTime(insertionTime)
86 , size(size)
87 , record(WTFMove(record))
88 { }
89
90 double insertionTime { 0 };
91 uint64_t size { 0 };
92 WebCore::DOMCacheEngine::Record record;
93 };
94 static Optional<DecodedRecord> decodeRecordHeader(const NetworkCache::Storage::Record&);
95
96private:
97 Vector<RecordInformation>* recordsFromURL(const URL&);
98 const Vector<RecordInformation>* recordsFromURL(const URL&) const;
99 RecordInformation& addRecord(Vector<RecordInformation>*, const WebCore::DOMCacheEngine::Record&);
100
101 void storeRecords(Vector<WebCore::DOMCacheEngine::Record>&&, WebCore::DOMCacheEngine::RecordIdentifiersCallback&&);
102
103 RecordInformation toRecordInformation(const WebCore::DOMCacheEngine::Record&);
104
105 void finishOpening(WebCore::DOMCacheEngine::CompletionCallback&&, Optional<WebCore::DOMCacheEngine::Error>&&);
106 void retrieveRecord(const RecordInformation&, Ref<ReadRecordTaskCounter>&&);
107
108 void readRecordsList(WebCore::DOMCacheEngine::CompletionCallback&&);
109 void writeRecordToDisk(const RecordInformation&, WebCore::DOMCacheEngine::Record&&, Ref<AsynchronousPutTaskCounter>&&, uint64_t previousRecordSize);
110 void updateRecordToDisk(RecordInformation&, WebCore::DOMCacheEngine::Record&&, Ref<AsynchronousPutTaskCounter>&&);
111 void removeRecordFromDisk(const RecordInformation&);
112 void readRecordFromDisk(const RecordInformation&, WTF::Function<void(Expected<WebCore::DOMCacheEngine::Record, WebCore::DOMCacheEngine::Error>&&)>&&);
113 void removeFromRecordList(const Vector<uint64_t>&);
114
115 Caches& m_caches;
116 State m_state;
117 uint64_t m_identifier { 0 };
118 String m_name;
119 String m_uniqueName;
120 HashMap<String, Vector<RecordInformation>> m_records;
121 uint64_t m_nextRecordIdentifier { 0 };
122 Vector<WebCore::DOMCacheEngine::CompletionCallback> m_pendingOpeningCallbacks;
123};
124
125} // namespace CacheStorage
126
127} // namespace WebKit
128