Add a DOMPromiseDeferred method to handle ExceptionOr<> results
[WebKit-https.git] / Source / WebCore / Modules / cache / CacheStorageConnection.cpp
1
2 /*
3  * Copyright (C) 2017 Apple Inc. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
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.
13  *
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.
25  */
26
27 #include "config.h"
28 #include "CacheStorageConnection.h"
29
30 #include "CacheQueryOptions.h"
31 #include "Exception.h"
32 #include "HTTPParsers.h"
33
34 namespace WebCore {
35
36 ExceptionOr<void> CacheStorageConnection::errorToException(Error error)
37 {
38     if (error == Error::NotImplemented)
39         return Exception { NotSupportedError, ASCIILiteral("Not implemented") };
40
41     return { };
42 }
43
44 bool CacheStorageConnection::queryCacheMatch(const ResourceRequest& request, const ResourceRequest& cachedRequest, const ResourceResponse& cachedResponse, const CacheQueryOptions& options)
45 {
46     ASSERT(options.ignoreMethod || request.httpMethod() == "GET");
47
48     URL requestURL = request.url();
49     URL cachedRequestURL = cachedRequest.url();
50
51     if (options.ignoreSearch) {
52         requestURL.setQuery({ });
53         cachedRequestURL.setQuery({ });
54     }
55     if (!equalIgnoringFragmentIdentifier(requestURL, cachedRequestURL))
56         return false;
57
58     if (options.ignoreVary)
59         return true;
60
61     String varyValue = cachedResponse.httpHeaderField(WebCore::HTTPHeaderName::Vary);
62     if (varyValue.isNull())
63         return true;
64
65     // FIXME: This is inefficient, we should be able to split and trim whitespaces at the same time.
66     Vector<String> varyHeaderNames;
67     varyValue.split(',', false, varyHeaderNames);
68     for (auto& name : varyHeaderNames) {
69         if (stripLeadingAndTrailingHTTPSpaces(name) == "*")
70             return false;
71         if (cachedRequest.httpHeaderField(name) != request.httpHeaderField(name))
72             return false;
73     }
74     return true;
75 }
76
77 void CacheStorageConnection::open(const String& origin, const String& cacheName, OpenRemoveCallback&& callback)
78 {
79     uint64_t requestIdentifier = ++m_lastRequestIdentifier;
80     m_openAndRemoveCachePendingRequests.add(requestIdentifier, WTFMove(callback));
81
82     doOpen(requestIdentifier, origin, cacheName);
83 }
84
85 void CacheStorageConnection::remove(uint64_t cacheIdentifier, OpenRemoveCallback&& callback)
86 {
87     uint64_t requestIdentifier = ++m_lastRequestIdentifier;
88     m_openAndRemoveCachePendingRequests.add(requestIdentifier, WTFMove(callback));
89
90     doRemove(requestIdentifier, cacheIdentifier);
91 }
92
93 void CacheStorageConnection::retrieveCaches(const String& origin, CachesCallback&& callback)
94 {
95     uint64_t requestIdentifier = ++m_lastRequestIdentifier;
96     m_retrieveCachesPendingRequests.add(requestIdentifier, WTFMove(callback));
97
98     doRetrieveCaches(requestIdentifier, origin);
99 }
100
101 void CacheStorageConnection::retrieveRecords(uint64_t cacheIdentifier, RecordsCallback&& callback)
102 {
103     uint64_t requestIdentifier = ++m_lastRequestIdentifier;
104     m_retrieveRecordsPendingRequests.add(requestIdentifier, WTFMove(callback));
105
106     doRetrieveRecords(requestIdentifier, cacheIdentifier);
107 }
108
109 void CacheStorageConnection::batchDeleteOperation(uint64_t cacheIdentifier, const WebCore::ResourceRequest& request, WebCore::CacheQueryOptions&& options, BatchOperationCallback&& callback)
110 {
111     uint64_t requestIdentifier = ++m_lastRequestIdentifier;
112     m_batchDeleteAndPutPendingRequests.add(requestIdentifier, WTFMove(callback));
113
114     doBatchDeleteOperation(requestIdentifier, cacheIdentifier, request, WTFMove(options));
115 }
116
117 void CacheStorageConnection::batchPutOperation(uint64_t cacheIdentifier, Vector<WebCore::CacheStorageConnection::Record>&& records, BatchOperationCallback&& callback)
118 {
119     uint64_t requestIdentifier = ++m_lastRequestIdentifier;
120     m_batchDeleteAndPutPendingRequests.add(requestIdentifier, WTFMove(callback));
121
122     doBatchPutOperation(requestIdentifier, cacheIdentifier, WTFMove(records));
123 }
124
125 void CacheStorageConnection::openOrRemoveCompleted(uint64_t requestIdentifier, uint64_t cacheIdentifier, Error error)
126 {
127     if (auto callback = m_openAndRemoveCachePendingRequests.take(requestIdentifier))
128         callback(cacheIdentifier, error);
129 }
130
131 void CacheStorageConnection::updateCaches(uint64_t requestIdentifier, Vector<CacheInfo>&& caches)
132 {
133     if (auto callback = m_retrieveCachesPendingRequests.take(requestIdentifier))
134         callback(WTFMove(caches));
135 }
136
137 void CacheStorageConnection::updateRecords(uint64_t requestIdentifier, Vector<Record>&& records)
138 {
139     if (auto callback = m_retrieveRecordsPendingRequests.take(requestIdentifier))
140         callback(WTFMove(records));
141 }
142
143 void CacheStorageConnection::deleteRecordsCompleted(uint64_t requestIdentifier, Vector<uint64_t>&& records, Error error)
144 {
145     if (auto callback = m_batchDeleteAndPutPendingRequests.take(requestIdentifier))
146         callback(WTFMove(records), error);
147 }
148
149 void CacheStorageConnection::putRecordsCompleted(uint64_t requestIdentifier, Vector<uint64_t>&& records, Error error)
150 {
151     if (auto callback = m_batchDeleteAndPutPendingRequests.take(requestIdentifier))
152         callback(WTFMove(records), error);
153 }
154
155 } // namespace WebCore