3 * Copyright (C) 2017 Apple Inc. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
18 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
24 * THE POSSIBILITY OF SUCH DAMAGE.
28 #include "CacheStorageConnection.h"
30 #include "CacheQueryOptions.h"
31 #include "Exception.h"
32 #include "HTTPParsers.h"
36 Exception CacheStorageConnection::exceptionFromError(Error error)
38 ASSERT(error != Error::None);
41 case Error::NotImplemented:
42 return Exception { NotSupportedError, ASCIILiteral("Not implemented") };
44 return Exception { TypeError, ASCIILiteral("Unknown error") };
48 bool CacheStorageConnection::queryCacheMatch(const ResourceRequest& request, const ResourceRequest& cachedRequest, const ResourceResponse& cachedResponse, const CacheQueryOptions& options)
50 ASSERT(options.ignoreMethod || request.httpMethod() == "GET");
52 URL requestURL = request.url();
53 URL cachedRequestURL = cachedRequest.url();
55 if (options.ignoreSearch) {
56 requestURL.setQuery({ });
57 cachedRequestURL.setQuery({ });
59 if (!equalIgnoringFragmentIdentifier(requestURL, cachedRequestURL))
62 if (options.ignoreVary)
65 String varyValue = cachedResponse.httpHeaderField(WebCore::HTTPHeaderName::Vary);
66 if (varyValue.isNull())
69 // FIXME: This is inefficient, we should be able to split and trim whitespaces at the same time.
70 Vector<String> varyHeaderNames;
71 varyValue.split(',', false, varyHeaderNames);
72 for (auto& name : varyHeaderNames) {
73 if (stripLeadingAndTrailingHTTPSpaces(name) == "*")
75 if (cachedRequest.httpHeaderField(name) != request.httpHeaderField(name))
81 void CacheStorageConnection::open(const String& origin, const String& cacheName, OpenRemoveCallback&& callback)
83 uint64_t requestIdentifier = ++m_lastRequestIdentifier;
84 m_openAndRemoveCachePendingRequests.add(requestIdentifier, WTFMove(callback));
86 doOpen(requestIdentifier, origin, cacheName);
89 void CacheStorageConnection::remove(uint64_t cacheIdentifier, OpenRemoveCallback&& callback)
91 uint64_t requestIdentifier = ++m_lastRequestIdentifier;
92 m_openAndRemoveCachePendingRequests.add(requestIdentifier, WTFMove(callback));
94 doRemove(requestIdentifier, cacheIdentifier);
97 void CacheStorageConnection::retrieveCaches(const String& origin, CachesCallback&& callback)
99 uint64_t requestIdentifier = ++m_lastRequestIdentifier;
100 m_retrieveCachesPendingRequests.add(requestIdentifier, WTFMove(callback));
102 doRetrieveCaches(requestIdentifier, origin);
105 void CacheStorageConnection::retrieveRecords(uint64_t cacheIdentifier, RecordsCallback&& callback)
107 uint64_t requestIdentifier = ++m_lastRequestIdentifier;
108 m_retrieveRecordsPendingRequests.add(requestIdentifier, WTFMove(callback));
110 doRetrieveRecords(requestIdentifier, cacheIdentifier);
113 void CacheStorageConnection::batchDeleteOperation(uint64_t cacheIdentifier, const WebCore::ResourceRequest& request, WebCore::CacheQueryOptions&& options, BatchOperationCallback&& callback)
115 uint64_t requestIdentifier = ++m_lastRequestIdentifier;
116 m_batchDeleteAndPutPendingRequests.add(requestIdentifier, WTFMove(callback));
118 doBatchDeleteOperation(requestIdentifier, cacheIdentifier, request, WTFMove(options));
121 void CacheStorageConnection::batchPutOperation(uint64_t cacheIdentifier, Vector<WebCore::CacheStorageConnection::Record>&& records, BatchOperationCallback&& callback)
123 uint64_t requestIdentifier = ++m_lastRequestIdentifier;
124 m_batchDeleteAndPutPendingRequests.add(requestIdentifier, WTFMove(callback));
126 doBatchPutOperation(requestIdentifier, cacheIdentifier, WTFMove(records));
129 void CacheStorageConnection::openOrRemoveCompleted(uint64_t requestIdentifier, uint64_t cacheIdentifier, Error error)
131 if (auto callback = m_openAndRemoveCachePendingRequests.take(requestIdentifier))
132 callback(cacheIdentifier, error);
135 void CacheStorageConnection::updateCaches(uint64_t requestIdentifier, Vector<CacheInfo>&& caches)
137 if (auto callback = m_retrieveCachesPendingRequests.take(requestIdentifier))
138 callback(WTFMove(caches));
141 void CacheStorageConnection::updateRecords(uint64_t requestIdentifier, Vector<Record>&& records)
143 if (auto callback = m_retrieveRecordsPendingRequests.take(requestIdentifier))
144 callback(WTFMove(records));
147 void CacheStorageConnection::deleteRecordsCompleted(uint64_t requestIdentifier, Vector<uint64_t>&& records, Error error)
149 if (auto callback = m_batchDeleteAndPutPendingRequests.take(requestIdentifier))
150 callback(WTFMove(records), error);
153 void CacheStorageConnection::putRecordsCompleted(uint64_t requestIdentifier, Vector<uint64_t>&& records, Error error)
155 if (auto callback = m_batchDeleteAndPutPendingRequests.take(requestIdentifier))
156 callback(WTFMove(records), error);
159 } // namespace WebCore