Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1767)

Side by Side Diff: Source/modules/serviceworkers/Cache.cpp

Issue 1055543004: Move Cache Storage API implementation to modules/cachestorage (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Rebased Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/modules/serviceworkers/Cache.h ('k') | Source/modules/serviceworkers/Cache.idl » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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.
4
5 #include "config.h"
6 #include "modules/serviceworkers/Cache.h"
7
8 #include "bindings/core/v8/ExceptionState.h"
9 #include "bindings/core/v8/ScriptPromiseResolver.h"
10 #include "bindings/core/v8/ScriptState.h"
11 #include "bindings/core/v8/V8ThrowException.h"
12 #include "core/dom/DOMException.h"
13 #include "modules/fetch/BodyStreamBuffer.h"
14 #include "modules/fetch/Request.h"
15 #include "modules/fetch/Response.h"
16 #include "public/platform/WebServiceWorkerCache.h"
17
18 namespace blink {
19
20 namespace {
21
22 // FIXME: Consider using CallbackPromiseAdapter.
23 class CacheMatchCallbacks : public WebServiceWorkerCache::CacheMatchCallbacks {
24 WTF_MAKE_NONCOPYABLE(CacheMatchCallbacks);
25 public:
26 CacheMatchCallbacks(PassRefPtrWillBeRawPtr<ScriptPromiseResolver> resolver)
27 : m_resolver(resolver) { }
28
29 virtual void onSuccess(WebServiceWorkerResponse* webResponse) override
30 {
31 m_resolver->resolve(Response::create(m_resolver->scriptState()->executio nContext(), *webResponse));
32 m_resolver.clear();
33 }
34
35 virtual void onError(WebServiceWorkerCacheError* reason) override
36 {
37 if (*reason == WebServiceWorkerCacheErrorNotFound)
38 m_resolver->resolve();
39 else
40 m_resolver->reject(Cache::domExceptionForCacheError(*reason));
41 m_resolver.clear();
42 }
43
44 private:
45 RefPtrWillBePersistent<ScriptPromiseResolver> m_resolver;
46 };
47
48 // FIXME: Consider using CallbackPromiseAdapter.
49 class CacheWithResponsesCallbacks : public WebServiceWorkerCache::CacheWithRespo nsesCallbacks {
50 WTF_MAKE_NONCOPYABLE(CacheWithResponsesCallbacks);
51 public:
52 CacheWithResponsesCallbacks(PassRefPtrWillBeRawPtr<ScriptPromiseResolver> re solver)
53 : m_resolver(resolver) { }
54
55 virtual void onSuccess(WebVector<WebServiceWorkerResponse>* webResponses) ov erride
56 {
57 HeapVector<Member<Response>> responses;
58 for (size_t i = 0; i < webResponses->size(); ++i)
59 responses.append(Response::create(m_resolver->scriptState()->executi onContext(), (*webResponses)[i]));
60 m_resolver->resolve(responses);
61 m_resolver.clear();
62 }
63
64 virtual void onError(WebServiceWorkerCacheError* reason) override
65 {
66 m_resolver->reject(Cache::domExceptionForCacheError(*reason));
67 m_resolver.clear();
68 }
69
70 protected:
71 RefPtrWillBePersistent<ScriptPromiseResolver> m_resolver;
72 };
73
74 // FIXME: Consider using CallbackPromiseAdapter.
75 class CacheAddOrPutCallbacks : public CacheWithResponsesCallbacks {
76 WTF_MAKE_NONCOPYABLE(CacheAddOrPutCallbacks);
77 public:
78 CacheAddOrPutCallbacks(PassRefPtrWillBeRawPtr<ScriptPromiseResolver> resolve r)
79 : CacheWithResponsesCallbacks(resolver) { }
80
81 virtual void onSuccess(WebVector<WebServiceWorkerResponse>* webResponses) ov erride
82 {
83 // FIXME: Since response is ignored, consider simplifying public API.
84 m_resolver->resolve();
85 m_resolver.clear();
86 }
87 };
88
89 // FIXME: Consider using CallbackPromiseAdapter.
90 class CacheDeleteCallback : public WebServiceWorkerCache::CacheWithResponsesCall backs {
91 WTF_MAKE_NONCOPYABLE(CacheDeleteCallback);
92 public:
93 CacheDeleteCallback(PassRefPtrWillBeRawPtr<ScriptPromiseResolver> resolver)
94 : m_resolver(resolver) { }
95
96 virtual void onSuccess(WebVector<WebServiceWorkerResponse>* webResponses) ov erride
97 {
98 // FIXME: Since response is ignored, consider simplifying public API.
99 m_resolver->resolve(true);
100 m_resolver.clear();
101 }
102
103 virtual void onError(WebServiceWorkerCacheError* reason) override
104 {
105 if (*reason == WebServiceWorkerCacheErrorNotFound)
106 m_resolver->resolve(false);
107 else
108 m_resolver->reject(Cache::domExceptionForCacheError(*reason));
109 m_resolver.clear();
110 }
111
112 private:
113 RefPtrWillBePersistent<ScriptPromiseResolver> m_resolver;
114 };
115
116 // FIXME: Consider using CallbackPromiseAdapter.
117 class CacheWithRequestsCallbacks : public WebServiceWorkerCache::CacheWithReques tsCallbacks {
118 WTF_MAKE_NONCOPYABLE(CacheWithRequestsCallbacks);
119 public:
120 CacheWithRequestsCallbacks(PassRefPtrWillBeRawPtr<ScriptPromiseResolver> res olver)
121 : m_resolver(resolver) { }
122
123 virtual void onSuccess(WebVector<WebServiceWorkerRequest>* webRequests) over ride
124 {
125 HeapVector<Member<Request>> requests;
126 for (size_t i = 0; i < webRequests->size(); ++i)
127 requests.append(Request::create(m_resolver->scriptState()->execution Context(), (*webRequests)[i]));
128 m_resolver->resolve(requests);
129 m_resolver.clear();
130 }
131
132 virtual void onError(WebServiceWorkerCacheError* reason) override
133 {
134 m_resolver->reject(Cache::domExceptionForCacheError(*reason));
135 m_resolver.clear();
136 }
137
138 private:
139 RefPtrWillBePersistent<ScriptPromiseResolver> m_resolver;
140 };
141
142 ScriptPromise rejectAsNotImplemented(ScriptState* scriptState)
143 {
144 return ScriptPromise::rejectWithDOMException(scriptState, DOMException::crea te(NotSupportedError, "Cache is not implemented"));
145 }
146
147 } // namespace
148
149 class Cache::AsyncPutBatch final : public BodyStreamBuffer::BlobHandleCreatorCli ent {
150 public:
151 AsyncPutBatch(PassRefPtrWillBeRawPtr<ScriptPromiseResolver> resolver, Cache* cache, Request* request, Response* response)
152 : m_resolver(resolver)
153 , m_cache(cache)
154 {
155 request->populateWebServiceWorkerRequest(m_webRequest);
156 response->populateWebServiceWorkerResponse(m_webResponse);
157 }
158 ~AsyncPutBatch() override { }
159 void didCreateBlobHandle(PassRefPtr<BlobDataHandle> handle) override
160 {
161 WebVector<WebServiceWorkerCache::BatchOperation> batchOperations(size_t( 1));
162 batchOperations[0].operationType = WebServiceWorkerCache::OperationTypeP ut;
163 batchOperations[0].request = m_webRequest;
164 batchOperations[0].response = m_webResponse;
165 batchOperations[0].response.setBlobDataHandle(handle);
166 m_cache->webCache()->dispatchBatch(new CacheAddOrPutCallbacks(m_resolver .get()), batchOperations);
167 cleanup();
168 }
169 void didFail(PassRefPtrWillBeRawPtr<DOMException> exception) override
170 {
171 ScriptState* state = m_resolver->scriptState();
172 ScriptState::Scope scope(state);
173 m_resolver->reject(V8ThrowException::createTypeError(state->isolate(), e xception->toString()));
174 cleanup();
175 }
176
177 DEFINE_INLINE_VIRTUAL_TRACE()
178 {
179 visitor->trace(m_resolver);
180 visitor->trace(m_cache);
181 BlobHandleCreatorClient::trace(visitor);
182 }
183
184 private:
185 void cleanup()
186 {
187 m_resolver = nullptr;
188 m_cache = nullptr;
189 }
190 RefPtrWillBeMember<ScriptPromiseResolver> m_resolver;
191 Member<Cache> m_cache;
192 WebServiceWorkerRequest m_webRequest;
193 WebServiceWorkerResponse m_webResponse;
194 };
195
196 Cache* Cache::create(WebServiceWorkerCache* webCache)
197 {
198 return new Cache(webCache);
199 }
200
201 ScriptPromise Cache::match(ScriptState* scriptState, const RequestInfo& request, const CacheQueryOptions& options, ExceptionState& exceptionState)
202 {
203 ASSERT(!request.isNull());
204 if (request.isRequest())
205 return matchImpl(scriptState, request.getAsRequest(), options);
206 Request* newRequest = Request::create(scriptState->executionContext(), reque st.getAsUSVString(), exceptionState);
207 if (exceptionState.hadException())
208 return ScriptPromise();
209 return matchImpl(scriptState, newRequest, options);
210 }
211
212 ScriptPromise Cache::matchAll(ScriptState* scriptState, const RequestInfo& reque st, const CacheQueryOptions& options, ExceptionState& exceptionState)
213 {
214 ASSERT(!request.isNull());
215 if (request.isRequest())
216 return matchAllImpl(scriptState, request.getAsRequest(), options);
217 Request* newRequest = Request::create(scriptState->executionContext(), reque st.getAsUSVString(), exceptionState);
218 if (exceptionState.hadException())
219 return ScriptPromise();
220 return matchAllImpl(scriptState, newRequest, options);
221 }
222
223 ScriptPromise Cache::add(ScriptState* scriptState, const RequestInfo& request, E xceptionState& exceptionState)
224 {
225 ASSERT(!request.isNull());
226 if (request.isRequest())
227 return addImpl(scriptState, request.getAsRequest());
228 Request* newRequest = Request::create(scriptState->executionContext(), reque st.getAsUSVString(), exceptionState);
229 if (exceptionState.hadException())
230 return ScriptPromise();
231 return addImpl(scriptState, newRequest);
232 }
233
234 ScriptPromise Cache::addAll(ScriptState* scriptState, const Vector<ScriptValue>& rawRequests)
235 {
236 // FIXME: Implement this.
237 return rejectAsNotImplemented(scriptState);
238 }
239
240 ScriptPromise Cache::deleteFunction(ScriptState* scriptState, const RequestInfo& request, const CacheQueryOptions& options, ExceptionState& exceptionState)
241 {
242 ASSERT(!request.isNull());
243 if (request.isRequest())
244 return deleteImpl(scriptState, request.getAsRequest(), options);
245 Request* newRequest = Request::create(scriptState->executionContext(), reque st.getAsUSVString(), exceptionState);
246 if (exceptionState.hadException())
247 return ScriptPromise();
248 return deleteImpl(scriptState, newRequest, options);
249 }
250
251 ScriptPromise Cache::put(ScriptState* scriptState, const RequestInfo& request, R esponse* response, ExceptionState& exceptionState)
252 {
253 ASSERT(!request.isNull());
254 if (request.isRequest())
255 return putImpl(scriptState, request.getAsRequest(), response);
256 Request* newRequest = Request::create(scriptState->executionContext(), reque st.getAsUSVString(), exceptionState);
257 if (exceptionState.hadException())
258 return ScriptPromise();
259 return putImpl(scriptState, newRequest, response);
260 }
261
262 ScriptPromise Cache::keys(ScriptState* scriptState, ExceptionState&)
263 {
264 return keysImpl(scriptState);
265 }
266
267 ScriptPromise Cache::keys(ScriptState* scriptState, const RequestInfo& request, const CacheQueryOptions& options, ExceptionState& exceptionState)
268 {
269 ASSERT(!request.isNull());
270 if (request.isRequest())
271 return keysImpl(scriptState, request.getAsRequest(), options);
272 Request* newRequest = Request::create(scriptState->executionContext(), reque st.getAsUSVString(), exceptionState);
273 if (exceptionState.hadException())
274 return ScriptPromise();
275 return keysImpl(scriptState, newRequest, options);
276 }
277
278 // static
279 WebServiceWorkerCache::QueryParams Cache::toWebQueryParams(const CacheQueryOptio ns& options)
280 {
281 WebServiceWorkerCache::QueryParams webQueryParams;
282 webQueryParams.ignoreSearch = options.ignoreSearch();
283 webQueryParams.ignoreMethod = options.ignoreMethod();
284 webQueryParams.ignoreVary = options.ignoreVary();
285 webQueryParams.cacheName = options.cacheName();
286 return webQueryParams;
287 }
288
289 Cache::Cache(WebServiceWorkerCache* webCache)
290 : m_webCache(adoptPtr(webCache)) { }
291
292 ScriptPromise Cache::matchImpl(ScriptState* scriptState, const Request* request, const CacheQueryOptions& options)
293 {
294 WebServiceWorkerRequest webRequest;
295 request->populateWebServiceWorkerRequest(webRequest);
296
297 RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver:: create(scriptState);
298 const ScriptPromise promise = resolver->promise();
299 m_webCache->dispatchMatch(new CacheMatchCallbacks(resolver), webRequest, toW ebQueryParams(options));
300 return promise;
301 }
302
303 ScriptPromise Cache::matchAllImpl(ScriptState* scriptState, const Request* reque st, const CacheQueryOptions& options)
304 {
305 WebServiceWorkerRequest webRequest;
306 request->populateWebServiceWorkerRequest(webRequest);
307
308 RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver:: create(scriptState);
309 const ScriptPromise promise = resolver->promise();
310 m_webCache->dispatchMatchAll(new CacheWithResponsesCallbacks(resolver), webR equest, toWebQueryParams(options));
311 return promise;
312 }
313
314 ScriptPromise Cache::addImpl(ScriptState* scriptState, const Request*)
315 {
316 // FIXME: Implement this.
317 return rejectAsNotImplemented(scriptState);
318 }
319
320 ScriptPromise Cache::addAllImpl(ScriptState* scriptState, const Vector<const Req uest*>)
321 {
322 // FIXME: Implement this.
323 return rejectAsNotImplemented(scriptState);
324 }
325
326 PassRefPtrWillBeRawPtr<DOMException> Cache::domExceptionForCacheError(WebService WorkerCacheError reason)
327 {
328 switch (reason) {
329 case WebServiceWorkerCacheErrorNotImplemented:
330 return DOMException::create(NotSupportedError, "Method is not implemente d.");
331 case WebServiceWorkerCacheErrorNotFound:
332 return DOMException::create(NotFoundError, "Entry was not found.");
333 case WebServiceWorkerCacheErrorExists:
334 return DOMException::create(InvalidAccessError, "Entry already exists.") ;
335 default:
336 ASSERT_NOT_REACHED();
337 return DOMException::create(NotSupportedError, "Unknown error.");
338 }
339 }
340
341 ScriptPromise Cache::deleteImpl(ScriptState* scriptState, const Request* request , const CacheQueryOptions& options)
342 {
343 WebVector<WebServiceWorkerCache::BatchOperation> batchOperations(size_t(1));
344 batchOperations[0].operationType = WebServiceWorkerCache::OperationTypeDelet e;
345 request->populateWebServiceWorkerRequest(batchOperations[0].request);
346 batchOperations[0].matchParams = toWebQueryParams(options);
347
348 RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver:: create(scriptState);
349 const ScriptPromise promise = resolver->promise();
350 m_webCache->dispatchBatch(new CacheDeleteCallback(resolver), batchOperations );
351 return promise;
352 }
353
354 ScriptPromise Cache::putImpl(ScriptState* scriptState, Request* request, Respons e* response)
355 {
356 KURL url(KURL(), request->url());
357 if (!url.protocolIsInHTTPFamily())
358 return ScriptPromise::reject(scriptState, V8ThrowException::createTypeEr ror(scriptState->isolate(), "Request scheme '" + url.protocol() + "' is unsuppor ted"));
359 if (request->method() != "GET")
360 return ScriptPromise::reject(scriptState, V8ThrowException::createTypeEr ror(scriptState->isolate(), "Request method '" + request->method() + "' is unsup ported"));
361 if (request->hasBody() && request->bodyUsed())
362 return ScriptPromise::reject(scriptState, V8ThrowException::createTypeEr ror(scriptState->isolate(), "Request body is already used"));
363 if (response->hasBody() && response->bodyUsed())
364 return ScriptPromise::reject(scriptState, V8ThrowException::createTypeEr ror(scriptState->isolate(), "Response body is already used"));
365
366 if (request->hasBody())
367 request->lockBody(Body::PassBody);
368 if (response->hasBody())
369 response->lockBody(Body::PassBody);
370
371 RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver:: create(scriptState);
372 const ScriptPromise promise = resolver->promise();
373 if (BodyStreamBuffer* buffer = response->internalBuffer()) {
374 if (buffer == response->buffer() && response->isBodyConsumed())
375 buffer = response->createDrainingStream();
376 // If the response body type is stream, read the all data and create the
377 // blob handle and dispatch the put batch asynchronously.
378 buffer->readAllAndCreateBlobHandle(response->internalMIMEType(), new Asy ncPutBatch(resolver, this, request, response));
379 return promise;
380 }
381 WebVector<WebServiceWorkerCache::BatchOperation> batchOperations(size_t(1));
382 batchOperations[0].operationType = WebServiceWorkerCache::OperationTypePut;
383 request->populateWebServiceWorkerRequest(batchOperations[0].request);
384 response->populateWebServiceWorkerResponse(batchOperations[0].response);
385
386 m_webCache->dispatchBatch(new CacheAddOrPutCallbacks(resolver), batchOperati ons);
387 return promise;
388 }
389
390 ScriptPromise Cache::keysImpl(ScriptState* scriptState)
391 {
392 RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver:: create(scriptState);
393 const ScriptPromise promise = resolver->promise();
394 m_webCache->dispatchKeys(new CacheWithRequestsCallbacks(resolver), 0, WebSer viceWorkerCache::QueryParams());
395 return promise;
396 }
397
398 ScriptPromise Cache::keysImpl(ScriptState* scriptState, const Request* request, const CacheQueryOptions& options)
399 {
400 WebServiceWorkerRequest webRequest;
401 request->populateWebServiceWorkerRequest(webRequest);
402
403 RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver:: create(scriptState);
404 const ScriptPromise promise = resolver->promise();
405 m_webCache->dispatchKeys(new CacheWithRequestsCallbacks(resolver), 0, toWebQ ueryParams(options));
406 return promise;
407 }
408
409 WebServiceWorkerCache* Cache::webCache() const
410 {
411 return m_webCache.get();
412 }
413
414 } // namespace blink
OLDNEW
« no previous file with comments | « Source/modules/serviceworkers/Cache.h ('k') | Source/modules/serviceworkers/Cache.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698