OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "config.h" | 5 #include "config.h" |
6 #include "modules/cachestorage/Cache.h" | 6 #include "modules/cachestorage/Cache.h" |
7 | 7 |
8 #include "bindings/core/v8/CallbackPromiseAdapter.h" | 8 #include "bindings/core/v8/CallbackPromiseAdapter.h" |
9 #include "bindings/core/v8/ExceptionState.h" | 9 #include "bindings/core/v8/ExceptionState.h" |
10 #include "bindings/core/v8/ScriptPromiseResolver.h" | 10 #include "bindings/core/v8/ScriptPromiseResolver.h" |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
146 public: | 146 public: |
147 static v8::Local<v8::Function> create(ScriptState* scriptState, Cache* cache , Request* request) | 147 static v8::Local<v8::Function> create(ScriptState* scriptState, Cache* cache , Request* request) |
148 { | 148 { |
149 FetchResolvedForAdd* self = new FetchResolvedForAdd(scriptState, cache, request); | 149 FetchResolvedForAdd* self = new FetchResolvedForAdd(scriptState, cache, request); |
150 return self->bindToV8Function(); | 150 return self->bindToV8Function(); |
151 } | 151 } |
152 | 152 |
153 ScriptValue call(ScriptValue value) override | 153 ScriptValue call(ScriptValue value) override |
154 { | 154 { |
155 Response* response = V8Response::toImplWithTypeCheck(scriptState()->isol ate(), value.v8Value()); | 155 Response* response = V8Response::toImplWithTypeCheck(scriptState()->isol ate(), value.v8Value()); |
156 ScriptPromise putPromise = m_cache->putImpl(scriptState(), m_request, re sponse); | 156 ScriptPromise putPromise = m_cache->putImpl(scriptState(), HeapVector<Me mber<Request>>(1, m_request), HeapVector<Member<Response>>(1, response)); |
157 return ScriptValue(scriptState(), putPromise.v8Value()); | 157 return ScriptValue(scriptState(), putPromise.v8Value()); |
158 } | 158 } |
159 | 159 |
160 DEFINE_INLINE_VIRTUAL_TRACE() | 160 DEFINE_INLINE_VIRTUAL_TRACE() |
161 { | 161 { |
162 visitor->trace(m_cache); | 162 visitor->trace(m_cache); |
163 visitor->trace(m_request); | 163 visitor->trace(m_request); |
164 ScriptFunction::trace(visitor); | 164 ScriptFunction::trace(visitor); |
165 } | 165 } |
166 | 166 |
167 private: | 167 private: |
168 FetchResolvedForAdd(ScriptState* scriptState, Cache* cache, Request* request ) | 168 FetchResolvedForAdd(ScriptState* scriptState, Cache* cache, Request* request ) |
169 : ScriptFunction(scriptState) | 169 : ScriptFunction(scriptState) |
170 , m_cache(cache) | 170 , m_cache(cache) |
171 , m_request(request) | 171 , m_request(request) |
172 { | 172 { |
173 } | 173 } |
174 | 174 |
175 Member<Cache> m_cache; | 175 Member<Cache> m_cache; |
176 Member<Request> m_request; | 176 Member<Request> m_request; |
177 }; | 177 }; |
178 | 178 |
179 class Cache::AsyncPutBatch final : public BodyStreamBuffer::BlobHandleCreatorCli ent { | 179 class Cache::BarrierCallbackForPut final : public GarbageCollectedFinalized<Barr ierCallbackForPut> { |
180 public: | 180 public: |
181 AsyncPutBatch(PassRefPtrWillBeRawPtr<ScriptPromiseResolver> resolver, Cache* cache, Request* request, Response* response) | 181 BarrierCallbackForPut(int numberOfOperations, Cache* cache, PassRefPtrWillBe RawPtr<ScriptPromiseResolver> resolver) |
182 : m_resolver(resolver) | 182 : m_numberOfRemainingOperations(numberOfOperations) |
183 , m_cache(cache) | 183 , m_cache(cache) |
184 , m_resolver(resolver) | |
185 { | |
186 ASSERT(0 < m_numberOfRemainingOperations); | |
187 m_batchOperations.resize(numberOfOperations); | |
188 } | |
189 | |
190 void onSuccess(size_t index, const WebServiceWorkerCache::BatchOperation& ba tchOperation) | |
191 { | |
192 ASSERT(index < m_batchOperations.size()); | |
193 if (m_completed) | |
194 return; | |
195 m_batchOperations[index] = batchOperation; | |
196 if (--m_numberOfRemainingOperations != 0) | |
197 return; | |
198 m_cache->webCache()->dispatchBatch(new CallbackPromiseAdapter<void, Cach eStorageError>(m_resolver), m_batchOperations); | |
sof
2015/06/30 09:46:46
Where is m_resolver resolved or cleared?
nhiroki
2015/07/01 02:02:20
m_resolver is resolved in CallbackPromiseAdapter<v
| |
199 } | |
200 | |
201 void onError(DOMException* exception) | |
202 { | |
203 if (m_completed) | |
204 return; | |
205 m_completed = true; | |
206 | |
207 ScriptState* state = m_resolver->scriptState(); | |
208 ScriptState::Scope scope(state); | |
209 m_resolver->reject(V8ThrowException::createTypeError(state->isolate(), e xception->toString())); | |
210 } | |
211 | |
212 DEFINE_INLINE_VIRTUAL_TRACE() | |
213 { | |
214 visitor->trace(m_cache); | |
215 } | |
216 | |
217 private: | |
218 bool m_completed = false; | |
219 int m_numberOfRemainingOperations; | |
220 Member<Cache> m_cache; | |
221 RefPtrWillBePersistent<ScriptPromiseResolver> m_resolver; | |
222 Vector<WebServiceWorkerCache::BatchOperation> m_batchOperations; | |
223 }; | |
224 | |
225 class Cache::BlobHandleCallbackForPut final : public BodyStreamBuffer::BlobHandl eCreatorClient { | |
226 public: | |
227 BlobHandleCallbackForPut(size_t index, BarrierCallbackForPut* barrierCallbac k, Request* request, Response* response) | |
228 : m_index(index) | |
229 , m_barrierCallback(barrierCallback) | |
184 { | 230 { |
185 request->populateWebServiceWorkerRequest(m_webRequest); | 231 request->populateWebServiceWorkerRequest(m_webRequest); |
186 response->populateWebServiceWorkerResponse(m_webResponse); | 232 response->populateWebServiceWorkerResponse(m_webResponse); |
187 } | 233 } |
188 ~AsyncPutBatch() override { } | 234 ~BlobHandleCallbackForPut() override { } |
235 | |
189 void didCreateBlobHandle(PassRefPtr<BlobDataHandle> handle) override | 236 void didCreateBlobHandle(PassRefPtr<BlobDataHandle> handle) override |
190 { | 237 { |
191 WebVector<WebServiceWorkerCache::BatchOperation> batchOperations(size_t( 1)); | 238 WebServiceWorkerCache::BatchOperation batchOperation; |
192 batchOperations[0].operationType = WebServiceWorkerCache::OperationTypeP ut; | 239 batchOperation.operationType = WebServiceWorkerCache::OperationTypePut; |
193 batchOperations[0].request = m_webRequest; | 240 batchOperation.request = m_webRequest; |
194 batchOperations[0].response = m_webResponse; | 241 batchOperation.response = m_webResponse; |
195 batchOperations[0].response.setBlobDataHandle(handle); | 242 batchOperation.response.setBlobDataHandle(handle); |
196 m_cache->webCache()->dispatchBatch(new CallbackPromiseAdapter<void, Cach eStorageError>(m_resolver.get()), batchOperations); | 243 m_barrierCallback->onSuccess(m_index, batchOperation); |
197 cleanup(); | |
198 } | 244 } |
245 | |
199 void didFail(DOMException* exception) override | 246 void didFail(DOMException* exception) override |
200 { | 247 { |
201 ScriptState* state = m_resolver->scriptState(); | 248 m_barrierCallback->onError(exception); |
202 ScriptState::Scope scope(state); | |
203 m_resolver->reject(V8ThrowException::createTypeError(state->isolate(), e xception->toString())); | |
204 cleanup(); | |
205 } | 249 } |
206 | 250 |
207 DEFINE_INLINE_VIRTUAL_TRACE() | 251 DEFINE_INLINE_VIRTUAL_TRACE() |
208 { | 252 { |
209 visitor->trace(m_resolver); | 253 visitor->trace(m_barrierCallback); |
210 visitor->trace(m_cache); | |
211 BlobHandleCreatorClient::trace(visitor); | 254 BlobHandleCreatorClient::trace(visitor); |
212 } | 255 } |
213 | 256 |
214 private: | 257 private: |
215 void cleanup() | 258 const size_t m_index; |
216 { | 259 Member<BarrierCallbackForPut> m_barrierCallback; |
217 m_resolver = nullptr; | 260 |
218 m_cache = nullptr; | |
219 } | |
220 RefPtrWillBeMember<ScriptPromiseResolver> m_resolver; | |
221 Member<Cache> m_cache; | |
222 WebServiceWorkerRequest m_webRequest; | 261 WebServiceWorkerRequest m_webRequest; |
223 WebServiceWorkerResponse m_webResponse; | 262 WebServiceWorkerResponse m_webResponse; |
224 }; | 263 }; |
225 | 264 |
226 Cache* Cache::create(WeakPtr<GlobalFetch::ScopedFetcher> fetcher, WebServiceWork erCache* webCache) | 265 Cache* Cache::create(WeakPtr<GlobalFetch::ScopedFetcher> fetcher, WebServiceWork erCache* webCache) |
227 { | 266 { |
228 return new Cache(fetcher, webCache); | 267 return new Cache(fetcher, webCache); |
229 } | 268 } |
230 | 269 |
231 ScriptPromise Cache::match(ScriptState* scriptState, const RequestInfo& request, const CacheQueryOptions& options, ExceptionState& exceptionState) | 270 ScriptPromise Cache::match(ScriptState* scriptState, const RequestInfo& request, const CacheQueryOptions& options, ExceptionState& exceptionState) |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
282 Request* newRequest = Request::create(scriptState, request.getAsUSVString(), exceptionState); | 321 Request* newRequest = Request::create(scriptState, request.getAsUSVString(), exceptionState); |
283 if (exceptionState.hadException()) | 322 if (exceptionState.hadException()) |
284 return ScriptPromise(); | 323 return ScriptPromise(); |
285 return deleteImpl(scriptState, newRequest, options); | 324 return deleteImpl(scriptState, newRequest, options); |
286 } | 325 } |
287 | 326 |
288 ScriptPromise Cache::put(ScriptState* scriptState, const RequestInfo& request, R esponse* response, ExceptionState& exceptionState) | 327 ScriptPromise Cache::put(ScriptState* scriptState, const RequestInfo& request, R esponse* response, ExceptionState& exceptionState) |
289 { | 328 { |
290 ASSERT(!request.isNull()); | 329 ASSERT(!request.isNull()); |
291 if (request.isRequest()) | 330 if (request.isRequest()) |
292 return putImpl(scriptState, request.getAsRequest(), response); | 331 return putImpl(scriptState, HeapVector<Member<Request>>(1, request.getAs Request()), HeapVector<Member<Response>>(1, response)); |
293 Request* newRequest = Request::create(scriptState, request.getAsUSVString(), exceptionState); | 332 Request* newRequest = Request::create(scriptState, request.getAsUSVString(), exceptionState); |
294 if (exceptionState.hadException()) | 333 if (exceptionState.hadException()) |
295 return ScriptPromise(); | 334 return ScriptPromise(); |
296 return putImpl(scriptState, newRequest, response); | 335 return putImpl(scriptState, HeapVector<Member<Request>>(1, newRequest), Heap Vector<Member<Response>>(1, response)); |
297 } | 336 } |
298 | 337 |
299 ScriptPromise Cache::keys(ScriptState* scriptState, ExceptionState&) | 338 ScriptPromise Cache::keys(ScriptState* scriptState, ExceptionState&) |
300 { | 339 { |
301 return keysImpl(scriptState); | 340 return keysImpl(scriptState); |
302 } | 341 } |
303 | 342 |
304 ScriptPromise Cache::keys(ScriptState* scriptState, const RequestInfo& request, const CacheQueryOptions& options, ExceptionState& exceptionState) | 343 ScriptPromise Cache::keys(ScriptState* scriptState, const RequestInfo& request, const CacheQueryOptions& options, ExceptionState& exceptionState) |
305 { | 344 { |
306 ASSERT(!request.isNull()); | 345 ASSERT(!request.isNull()); |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
374 batchOperations[0].operationType = WebServiceWorkerCache::OperationTypeDelet e; | 413 batchOperations[0].operationType = WebServiceWorkerCache::OperationTypeDelet e; |
375 request->populateWebServiceWorkerRequest(batchOperations[0].request); | 414 request->populateWebServiceWorkerRequest(batchOperations[0].request); |
376 batchOperations[0].matchParams = toWebQueryParams(options); | 415 batchOperations[0].matchParams = toWebQueryParams(options); |
377 | 416 |
378 RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver:: create(scriptState); | 417 RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver:: create(scriptState); |
379 const ScriptPromise promise = resolver->promise(); | 418 const ScriptPromise promise = resolver->promise(); |
380 m_webCache->dispatchBatch(new CacheDeleteCallback(resolver), batchOperations ); | 419 m_webCache->dispatchBatch(new CacheDeleteCallback(resolver), batchOperations ); |
381 return promise; | 420 return promise; |
382 } | 421 } |
383 | 422 |
384 ScriptPromise Cache::putImpl(ScriptState* scriptState, Request* request, Respons e* response) | 423 ScriptPromise Cache::putImpl(ScriptState* scriptState, const HeapVector<Member<R equest>>& requests, const HeapVector<Member<Response>>& responses) |
385 { | 424 { |
386 KURL url(KURL(), request->url()); | |
387 if (!url.protocolIsInHTTPFamily()) | |
388 return ScriptPromise::reject(scriptState, V8ThrowException::createTypeEr ror(scriptState->isolate(), "Request scheme '" + url.protocol() + "' is unsuppor ted")); | |
389 if (request->method() != "GET") | |
390 return ScriptPromise::reject(scriptState, V8ThrowException::createTypeEr ror(scriptState->isolate(), "Request method '" + request->method() + "' is unsup ported")); | |
391 if (request->hasBody() && request->bodyUsed()) | |
392 return ScriptPromise::reject(scriptState, V8ThrowException::createTypeEr ror(scriptState->isolate(), "Request body is already used")); | |
393 if (response->hasBody() && response->bodyUsed()) | |
394 return ScriptPromise::reject(scriptState, V8ThrowException::createTypeEr ror(scriptState->isolate(), "Response body is already used")); | |
395 | |
396 if (request->hasBody()) | |
397 request->lockBody(Body::PassBody); | |
398 if (response->hasBody()) | |
399 response->lockBody(Body::PassBody); | |
400 | |
401 RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver:: create(scriptState); | 425 RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver:: create(scriptState); |
402 const ScriptPromise promise = resolver->promise(); | 426 const ScriptPromise promise = resolver->promise(); |
403 if (BodyStreamBuffer* buffer = response->internalBuffer()) { | 427 BarrierCallbackForPut* barrierCallback = new BarrierCallbackForPut(requests. size(), this, resolver.get()); |
404 if (buffer == response->buffer() && response->isBodyConsumed()) | 428 |
405 buffer = response->createDrainingStream(); | 429 for (size_t i = 0; i < requests.size(); ++i) { |
406 // If the response body type is stream, read the all data and create the | 430 KURL url(KURL(), requests[i]->url()); |
407 // blob handle and dispatch the put batch asynchronously. | 431 if (!url.protocolIsInHTTPFamily()) |
408 buffer->readAllAndCreateBlobHandle(response->internalMIMEType(), new Asy ncPutBatch(resolver, this, request, response)); | 432 return ScriptPromise::reject(scriptState, V8ThrowException::createTy peError(scriptState->isolate(), "Request scheme '" + url.protocol() + "' is unsu pported")); |
409 return promise; | 433 if (requests[i]->method() != "GET") |
434 return ScriptPromise::reject(scriptState, V8ThrowException::createTy peError(scriptState->isolate(), "Request method '" + requests[i]->method() + "' is unsupported")); | |
435 if (requests[i]->hasBody() && requests[i]->bodyUsed()) | |
436 return ScriptPromise::reject(scriptState, V8ThrowException::createTy peError(scriptState->isolate(), "Request body is already used")); | |
437 if (responses[i]->hasBody() && responses[i]->bodyUsed()) | |
438 return ScriptPromise::reject(scriptState, V8ThrowException::createTy peError(scriptState->isolate(), "Response body is already used")); | |
439 | |
440 if (requests[i]->hasBody()) | |
441 requests[i]->lockBody(Body::PassBody); | |
442 if (responses[i]->hasBody()) | |
443 responses[i]->lockBody(Body::PassBody); | |
444 | |
445 if (BodyStreamBuffer* buffer = responses[i]->internalBuffer()) { | |
446 if (buffer == responses[i]->buffer() && responses[i]->isBodyConsumed ()) | |
447 buffer = responses[i]->createDrainingStream(); | |
448 // If the response body type is stream, read the all data and create | |
449 // the blob handle and dispatch the put batch asynchronously. | |
450 buffer->readAllAndCreateBlobHandle(responses[i]->internalMIMEType(), new BlobHandleCallbackForPut(i, barrierCallback, requests[i], responses[i])); | |
451 continue; | |
452 } | |
453 | |
454 WebServiceWorkerCache::BatchOperation batchOperation; | |
455 batchOperation.operationType = WebServiceWorkerCache::OperationTypePut; | |
456 requests[i]->populateWebServiceWorkerRequest(batchOperation.request); | |
457 responses[i]->populateWebServiceWorkerResponse(batchOperation.response); | |
458 barrierCallback->onSuccess(i, batchOperation); | |
410 } | 459 } |
411 WebVector<WebServiceWorkerCache::BatchOperation> batchOperations(size_t(1)); | |
412 batchOperations[0].operationType = WebServiceWorkerCache::OperationTypePut; | |
413 request->populateWebServiceWorkerRequest(batchOperations[0].request); | |
414 response->populateWebServiceWorkerResponse(batchOperations[0].response); | |
415 | 460 |
416 m_webCache->dispatchBatch(new CallbackPromiseAdapter<void, CacheStorageError >(resolver), batchOperations); | |
417 return promise; | 461 return promise; |
418 } | 462 } |
419 | 463 |
420 ScriptPromise Cache::keysImpl(ScriptState* scriptState) | 464 ScriptPromise Cache::keysImpl(ScriptState* scriptState) |
421 { | 465 { |
422 RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver:: create(scriptState); | 466 RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver:: create(scriptState); |
423 const ScriptPromise promise = resolver->promise(); | 467 const ScriptPromise promise = resolver->promise(); |
424 m_webCache->dispatchKeys(new CacheWithRequestsCallbacks(resolver), 0, WebSer viceWorkerCache::QueryParams()); | 468 m_webCache->dispatchKeys(new CacheWithRequestsCallbacks(resolver), 0, WebSer viceWorkerCache::QueryParams()); |
425 return promise; | 469 return promise; |
426 } | 470 } |
427 | 471 |
428 ScriptPromise Cache::keysImpl(ScriptState* scriptState, const Request* request, const CacheQueryOptions& options) | 472 ScriptPromise Cache::keysImpl(ScriptState* scriptState, const Request* request, const CacheQueryOptions& options) |
429 { | 473 { |
430 WebServiceWorkerRequest webRequest; | 474 WebServiceWorkerRequest webRequest; |
431 request->populateWebServiceWorkerRequest(webRequest); | 475 request->populateWebServiceWorkerRequest(webRequest); |
432 | 476 |
433 RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver:: create(scriptState); | 477 RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver:: create(scriptState); |
434 const ScriptPromise promise = resolver->promise(); | 478 const ScriptPromise promise = resolver->promise(); |
435 m_webCache->dispatchKeys(new CacheWithRequestsCallbacks(resolver), 0, toWebQ ueryParams(options)); | 479 m_webCache->dispatchKeys(new CacheWithRequestsCallbacks(resolver), 0, toWebQ ueryParams(options)); |
436 return promise; | 480 return promise; |
437 } | 481 } |
438 | 482 |
439 WebServiceWorkerCache* Cache::webCache() const | 483 WebServiceWorkerCache* Cache::webCache() const |
440 { | 484 { |
441 return m_webCache.get(); | 485 return m_webCache.get(); |
442 } | 486 } |
443 | 487 |
444 } // namespace blink | 488 } // namespace blink |
OLD | NEW |