1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
6 #include "modules/serviceworkers/Cache.h"
8 #include "bindings/core/v8/ScriptPromiseResolver.h"
9 #include "bindings/core/v8/ScriptState.h"
10 #include "bindings/core/v8/V8ThrowException.h"
11 #include "core/dom/DOMException.h"
12 #include "modules/serviceworkers/Request.h"
13 #include "modules/serviceworkers/Response.h"
14 #include "public/platform/WebServiceWorkerCache.h"
20 WebServiceWorkerCache::QueryParams toWebQueryParams(const QueryParams& queryParams)
22 WebServiceWorkerCache::QueryParams webQueryParams;
23 // FIXME: The queryParams.hasXXXX() calls can be removed if defaults are
24 // added to the IDL. https://github.com/slightlyoff/ServiceWorker/issues/466
25 webQueryParams.ignoreSearch = queryParams.hasIgnoreSearch() && queryParams.ignoreSearch();
26 webQueryParams.ignoreMethod = queryParams.hasIgnoreMethod() && queryParams.ignoreMethod();
27 webQueryParams.ignoreVary = queryParams.hasIgnoreVary() && queryParams.ignoreVary();
28 webQueryParams.prefixMatch = queryParams.hasPrefixMatch() && queryParams.prefixMatch();
29 webQueryParams.cacheName = queryParams.cacheName();
30 return webQueryParams;
33 // FIXME: Consider using CallbackPromiseAdapter.
34 class CacheMatchCallbacks : public WebServiceWorkerCache::CacheMatchCallbacks {
35 WTF_MAKE_NONCOPYABLE(CacheMatchCallbacks);
37 CacheMatchCallbacks(PassRefPtr<ScriptPromiseResolver> resolver)
38 : m_resolver(resolver) { }
40 virtual void onSuccess(WebServiceWorkerResponse* webResponse) OVERRIDE
42 m_resolver->resolve(Response::create(m_resolver->scriptState()->executionContext(), *webResponse));
46 virtual void onError(WebServiceWorkerCacheError* reason) OVERRIDE
48 m_resolver->reject(Cache::domExceptionForCacheError(*reason));
53 RefPtr<ScriptPromiseResolver> m_resolver;
56 // FIXME: Consider using CallbackPromiseAdapter.
57 class CacheWithResponsesCallbacks : public WebServiceWorkerCache::CacheWithResponsesCallbacks {
58 WTF_MAKE_NONCOPYABLE(CacheWithResponsesCallbacks);
60 CacheWithResponsesCallbacks(PassRefPtr<ScriptPromiseResolver> resolver)
61 : m_resolver(resolver) { }
63 virtual void onSuccess(WebVector<WebServiceWorkerResponse>* webResponses) OVERRIDE
65 HeapVector<Member<Response> > responses;
66 for (size_t i = 0; i < webResponses->size(); ++i)
67 responses.append(Response::create(m_resolver->scriptState()->executionContext(), (*webResponses)[i]));
68 m_resolver->resolve(responses);
72 virtual void onError(WebServiceWorkerCacheError* reason) OVERRIDE
74 m_resolver->reject(Cache::domExceptionForCacheError(*reason));
79 RefPtr<ScriptPromiseResolver> m_resolver;
82 // FIXME: Consider using CallbackPromiseAdapter.
83 class CacheWithRequestsCallbacks : public WebServiceWorkerCache::CacheWithRequestsCallbacks {
84 WTF_MAKE_NONCOPYABLE(CacheWithRequestsCallbacks);
86 CacheWithRequestsCallbacks(PassRefPtr<ScriptPromiseResolver> resolver)
87 : m_resolver(resolver) { }
89 virtual void onSuccess(WebVector<WebServiceWorkerRequest>* webRequests) OVERRIDE
91 HeapVector<Member<Request> > requests;
92 for (size_t i = 0; i < webRequests->size(); ++i)
93 requests.append(Request::create(m_resolver->scriptState()->executionContext(), (*webRequests)[i]));
94 m_resolver->resolve(requests);
98 virtual void onError(WebServiceWorkerCacheError* reason) OVERRIDE
100 m_resolver->reject(Cache::domExceptionForCacheError(*reason));
105 RefPtr<ScriptPromiseResolver> m_resolver;
108 ScriptPromise rejectForCacheError(ScriptState* scriptState, WebServiceWorkerCacheError error)
110 return ScriptPromise::rejectWithDOMException(scriptState, Cache::domExceptionForCacheError(error));
113 ScriptPromise rejectAsNotImplemented(ScriptState* scriptState)
115 return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(NotSupportedError, "Cache is not implemented"));
120 Cache* Cache::create(WebServiceWorkerCache* webCache)
122 return new Cache(webCache);
125 ScriptPromise Cache::match(ScriptState* scriptState, Request* originalRequest, const QueryParams& queryParams)
127 TrackExceptionState exceptionState;
128 Request* request = Request::create(scriptState->executionContext(), originalRequest, exceptionState);
129 if (exceptionState.hadException()) {
130 // FIXME: We should throw the caught error.
131 return rejectForCacheError(scriptState, WebServiceWorkerCacheErrorNotFound);
133 return matchImpl(scriptState, request, queryParams);
136 ScriptPromise Cache::match(ScriptState* scriptState, const String& requestString, const QueryParams& queryParams)
138 TrackExceptionState exceptionState;
139 Request* request = Request::create(scriptState->executionContext(), requestString, exceptionState);
140 if (exceptionState.hadException()) {
141 // FIXME: We should throw the caught error.
142 return rejectForCacheError(scriptState, WebServiceWorkerCacheErrorNotFound);
144 return matchImpl(scriptState, request, queryParams);
147 ScriptPromise Cache::matchAll(ScriptState* scriptState, Request* originalRequest, const QueryParams& queryParams)
149 TrackExceptionState exceptionState;
150 Request* request = Request::create(scriptState->executionContext(), originalRequest, exceptionState);
151 if (exceptionState.hadException()) {
152 // FIXME: We should throw the caught error.
153 return rejectForCacheError(scriptState, WebServiceWorkerCacheErrorNotFound);
155 return matchAllImpl(scriptState, request, queryParams);
158 ScriptPromise Cache::matchAll(ScriptState* scriptState, const String& requestString, const QueryParams& queryParams)
160 TrackExceptionState exceptionState;
161 Request* request = Request::create(scriptState->executionContext(), requestString, exceptionState);
162 if (exceptionState.hadException()) {
163 // FIXME: We should throw the caught error.
164 return rejectForCacheError(scriptState, WebServiceWorkerCacheErrorNotFound);
166 return matchAllImpl(scriptState, request, queryParams);
169 ScriptPromise Cache::add(ScriptState* scriptState, Request* originalRequest)
171 TrackExceptionState exceptionState;
172 Request* request = Request::create(scriptState->executionContext(), originalRequest, exceptionState);
173 if (exceptionState.hadException()) {
174 // FIXME: We should throw the caught error.
175 return rejectForCacheError(scriptState, WebServiceWorkerCacheErrorNotFound);
177 return addImpl(scriptState, request);
180 ScriptPromise Cache::add(ScriptState* scriptState, const String& requestString)
182 TrackExceptionState exceptionState;
183 Request* request = Request::create(scriptState->executionContext(), requestString, exceptionState);
184 if (exceptionState.hadException()) {
185 // FIXME: We should throw the caught error.
186 return rejectForCacheError(scriptState, WebServiceWorkerCacheErrorNotFound);
188 return addImpl(scriptState, request);
191 ScriptPromise Cache::addAll(ScriptState* scriptState, const Vector<ScriptValue>& rawRequests)
193 // FIXME: Implement this.
194 return rejectAsNotImplemented(scriptState);
197 ScriptPromise Cache::deleteFunction(ScriptState* scriptState, Request* originalRequest, const QueryParams& queryParams)
199 TrackExceptionState exceptionState;
200 Request* request = Request::create(scriptState->executionContext(), originalRequest, exceptionState);
201 if (exceptionState.hadException()) {
202 // FIXME: We should throw the caught error.
203 return rejectForCacheError(scriptState, WebServiceWorkerCacheErrorNotFound);
205 return deleteImpl(scriptState, request, queryParams);
208 ScriptPromise Cache::deleteFunction(ScriptState* scriptState, const String& requestString, const QueryParams& queryParams)
210 TrackExceptionState exceptionState;
211 Request* request = Request::create(scriptState->executionContext(), requestString, exceptionState);
212 if (exceptionState.hadException()) {
213 // FIXME: We should throw the caught error.
214 return rejectForCacheError(scriptState, WebServiceWorkerCacheErrorNotFound);
216 return deleteImpl(scriptState, request, queryParams);
219 ScriptPromise Cache::put(ScriptState* scriptState, Request* originalRequest, Response* response)
221 TrackExceptionState exceptionState;
222 Request* request = Request::create(scriptState->executionContext(), originalRequest, exceptionState);
223 if (exceptionState.hadException()) {
224 // FIXME: We should throw the caught error.
225 return rejectForCacheError(scriptState, WebServiceWorkerCacheErrorNotFound);
227 return putImpl(scriptState, request, response);
230 ScriptPromise Cache::put(ScriptState* scriptState, const String& requestString, Response* response)
232 TrackExceptionState exceptionState;
233 Request* request = Request::create(scriptState->executionContext(), requestString, exceptionState);
234 if (exceptionState.hadException()) {
235 // FIXME: We should throw the caught error.
236 return rejectForCacheError(scriptState, WebServiceWorkerCacheErrorNotFound);
238 return putImpl(scriptState, request, response);
241 ScriptPromise Cache::keys(ScriptState* scriptState)
243 return keysImpl(scriptState);
246 ScriptPromise Cache::keys(ScriptState* scriptState, Request* originalRequest, const QueryParams& queryParams)
248 TrackExceptionState exceptionState;
249 Request* request = Request::create(scriptState->executionContext(), originalRequest, exceptionState);
250 if (exceptionState.hadException()) {
251 // FIXME: We should throw the caught error.
252 return rejectForCacheError(scriptState, WebServiceWorkerCacheErrorNotFound);
254 return keysImpl(scriptState, request, queryParams);
257 ScriptPromise Cache::keys(ScriptState* scriptState, const String& requestString, const QueryParams& queryParams)
259 TrackExceptionState exceptionState;
260 Request* request = Request::create(scriptState->executionContext(), requestString, exceptionState);
261 if (exceptionState.hadException()) {
262 // FIXME: We should throw the caught error.
263 return rejectForCacheError(scriptState, WebServiceWorkerCacheErrorNotFound);
265 return keysImpl(scriptState, request, queryParams);
268 Cache::Cache(WebServiceWorkerCache* webCache)
269 : m_webCache(adoptPtr(webCache)) { }
271 ScriptPromise Cache::matchImpl(ScriptState* scriptState, Request* request, const QueryParams& queryParams)
273 WebServiceWorkerRequest webRequest;
274 request->populateWebServiceWorkerRequest(webRequest);
276 RefPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState);
277 const ScriptPromise promise = resolver->promise();
278 m_webCache->dispatchMatch(new CacheMatchCallbacks(resolver), webRequest, toWebQueryParams(queryParams));
282 ScriptPromise Cache::matchAllImpl(ScriptState* scriptState, Request* request, const QueryParams& queryParams)
284 WebServiceWorkerRequest webRequest;
285 request->populateWebServiceWorkerRequest(webRequest);
287 RefPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState);
288 const ScriptPromise promise = resolver->promise();
289 m_webCache->dispatchMatchAll(new CacheWithResponsesCallbacks(resolver), webRequest, toWebQueryParams(queryParams));
293 ScriptPromise Cache::addImpl(ScriptState* scriptState, Request*)
295 // FIXME: Implement this.
296 return rejectAsNotImplemented(scriptState);
299 ScriptPromise Cache::addAllImpl(ScriptState* scriptState, Vector<Request*>)
301 // FIXME: Implement this.
302 return rejectAsNotImplemented(scriptState);
305 PassRefPtrWillBeRawPtr<DOMException> Cache::domExceptionForCacheError(WebServiceWorkerCacheError reason)
308 case WebServiceWorkerCacheErrorNotImplemented:
309 return DOMException::create(NotSupportedError, "Method is not implemented.");
310 case WebServiceWorkerCacheErrorNotFound:
311 return DOMException::create(NotFoundError, "Entry was not found.");
312 case WebServiceWorkerCacheErrorExists:
313 return DOMException::create(InvalidAccessError, "Entry already exists.");
315 ASSERT_NOT_REACHED();
316 return DOMException::create(NotSupportedError, "Unknown error.");
320 ScriptPromise Cache::deleteImpl(ScriptState* scriptState, Request* request, const QueryParams& queryParams)
322 WebVector<WebServiceWorkerCache::BatchOperation> batchOperations(size_t(1));
323 batchOperations[0].operationType = WebServiceWorkerCache::OperationTypeDelete;
324 request->populateWebServiceWorkerRequest(batchOperations[0].request);
325 batchOperations[0].matchParams = toWebQueryParams(queryParams);
327 RefPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState);
328 const ScriptPromise promise = resolver->promise();
329 m_webCache->dispatchBatch(new CacheWithResponsesCallbacks(resolver), batchOperations);
333 ScriptPromise Cache::putImpl(ScriptState* scriptState, Request* request, Response* response)
335 WebVector<WebServiceWorkerCache::BatchOperation> batchOperations(size_t(1));
336 batchOperations[0].operationType = WebServiceWorkerCache::OperationTypePut;
337 request->populateWebServiceWorkerRequest(batchOperations[0].request);
338 response->populateWebServiceWorkerResponse(batchOperations[0].response);
340 RefPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState);
341 const ScriptPromise promise = resolver->promise();
342 m_webCache->dispatchBatch(new CacheWithResponsesCallbacks(resolver), batchOperations);
346 ScriptPromise Cache::keysImpl(ScriptState* scriptState)
348 RefPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState);
349 const ScriptPromise promise = resolver->promise();
350 m_webCache->dispatchKeys(new CacheWithRequestsCallbacks(resolver), 0, WebServiceWorkerCache::QueryParams());
354 ScriptPromise Cache::keysImpl(ScriptState* scriptState, Request* request, const QueryParams& queryParams)
356 WebServiceWorkerRequest webRequest;
357 request->populateWebServiceWorkerRequest(webRequest);
359 RefPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState);
360 const ScriptPromise promise = resolver->promise();
361 m_webCache->dispatchKeys(new CacheWithRequestsCallbacks(resolver), 0, toWebQueryParams(queryParams));