Chromium Code Reviews| 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 |