Remove std::chrono completely
[WebKit.git] / Source / WebKit / NetworkProcess / cache / NetworkCacheSubresourcesEntry.cpp
1 /*
2  * Copyright (C) 2015 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 #include "config.h"
27
28 #if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
29 #include "NetworkCacheSubresourcesEntry.h"
30
31 #include "Logging.h"
32 #include "NetworkCacheCoders.h"
33
34 namespace WebKit {
35 namespace NetworkCache {
36
37 void SubresourceInfo::encode(WTF::Persistence::Encoder& encoder) const
38 {
39     encoder << m_key;
40     encoder << m_lastSeen;
41     encoder << m_firstSeen;
42     encoder << m_isTransient;
43
44     // Do not bother serializing other data members of transient resources as they are empty.
45     if (m_isTransient)
46         return;
47
48     encoder << m_firstPartyForCookies;
49     encoder << m_requestHeaders;
50     encoder.encodeEnum(m_priority);
51 }
52
53 bool SubresourceInfo::decode(WTF::Persistence::Decoder& decoder, SubresourceInfo& info)
54 {
55     if (!decoder.decode(info.m_key))
56         return false;
57     if (!decoder.decode(info.m_lastSeen))
58         return false;
59     if (!decoder.decode(info.m_firstSeen))
60         return false;
61     
62     if (!decoder.decode(info.m_isTransient))
63         return false;
64     
65     if (info.m_isTransient)
66         return true;
67     
68     if (!decoder.decode(info.m_firstPartyForCookies))
69         return false;
70
71     if (!decoder.decode(info.m_requestHeaders))
72         return false;
73
74     if (!decoder.decodeEnum(info.m_priority))
75         return false;
76     
77     return true;
78 }
79
80 Storage::Record SubresourcesEntry::encodeAsStorageRecord() const
81 {
82     WTF::Persistence::Encoder encoder;
83     encoder << m_subresources;
84
85     encoder.encodeChecksum();
86
87     return { m_key, m_timeStamp, { encoder.buffer(), encoder.bufferSize() }, { }, { }};
88 }
89
90 std::unique_ptr<SubresourcesEntry> SubresourcesEntry::decodeStorageRecord(const Storage::Record& storageEntry)
91 {
92     auto entry = std::make_unique<SubresourcesEntry>(storageEntry);
93
94     WTF::Persistence::Decoder decoder(storageEntry.header.data(), storageEntry.header.size());
95     if (!decoder.decode(entry->m_subresources))
96         return nullptr;
97
98     if (!decoder.verifyChecksum()) {
99         LOG(NetworkCache, "(NetworkProcess) checksum verification failure\n");
100         return nullptr;
101     }
102
103     return entry;
104 }
105
106 SubresourcesEntry::SubresourcesEntry(const Storage::Record& storageEntry)
107     : m_key(storageEntry.key)
108     , m_timeStamp(storageEntry.timeStamp)
109 {
110     ASSERT(m_key.type() == "SubResources");
111 }
112
113 SubresourceInfo::SubresourceInfo(const Key& key, const WebCore::ResourceRequest& request, const SubresourceInfo* previousInfo)
114     : m_key(key)
115     , m_lastSeen(WallTime::now())
116     , m_firstSeen(previousInfo ? previousInfo->firstSeen() : m_lastSeen)
117     , m_isTransient(!previousInfo)
118     , m_firstPartyForCookies(request.firstPartyForCookies())
119     , m_requestHeaders(request.httpHeaderFields())
120     , m_priority(request.priority())
121 {
122 }
123
124 static Vector<SubresourceInfo> makeSubresourceInfoVector(const Vector<std::unique_ptr<SubresourceLoad>>& subresourceLoads, Vector<SubresourceInfo>* previousSubresources)
125 {
126     Vector<SubresourceInfo> result;
127     result.reserveInitialCapacity(subresourceLoads.size());
128     
129     HashMap<Key, unsigned> previousMap;
130     if (previousSubresources) {
131         for (unsigned i = 0; i < previousSubresources->size(); ++i)
132             previousMap.add(previousSubresources->at(i).key(), i);
133     }
134
135     HashSet<Key> deduplicationSet;
136     for (auto& load : subresourceLoads) {
137         if (!deduplicationSet.add(load->key).isNewEntry)
138             continue;
139         
140         SubresourceInfo* previousInfo = nullptr;
141         if (previousSubresources) {
142             auto it = previousMap.find(load->key);
143             if (it != previousMap.end())
144                 previousInfo = &(*previousSubresources)[it->value];
145         }
146         
147         result.uncheckedAppend({ load->key, load->request, previousInfo });
148         
149         // FIXME: We should really consider all resources seen for the first time transient.
150         if (!previousSubresources)
151             result.last().setNonTransient();
152     }
153
154     return result;
155 }
156
157 SubresourcesEntry::SubresourcesEntry(Key&& key, const Vector<std::unique_ptr<SubresourceLoad>>& subresourceLoads)
158     : m_key(WTFMove(key))
159     , m_timeStamp(WallTime::now())
160     , m_subresources(makeSubresourceInfoVector(subresourceLoads, nullptr))
161 {
162     ASSERT(m_key.type() == "SubResources");
163 }
164     
165 void SubresourcesEntry::updateSubresourceLoads(const Vector<std::unique_ptr<SubresourceLoad>>& subresourceLoads)
166 {
167     m_subresources = makeSubresourceInfoVector(subresourceLoads, &m_subresources);
168 }
169
170 } // namespace WebKit
171 } // namespace NetworkCache
172
173 #endif // ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)