| 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" |
| 11 #include "bindings/core/v8/ScriptState.h" | 11 #include "bindings/core/v8/ScriptState.h" |
| 12 #include "bindings/core/v8/V8Binding.h" |
| 12 #include "bindings/core/v8/V8ThrowException.h" | 13 #include "bindings/core/v8/V8ThrowException.h" |
| 13 #include "bindings/modules/v8/V8Response.h" | 14 #include "bindings/modules/v8/V8Response.h" |
| 14 #include "core/dom/DOMException.h" | 15 #include "core/dom/DOMException.h" |
| 15 #include "modules/cachestorage/CacheStorageError.h" | 16 #include "modules/cachestorage/CacheStorageError.h" |
| 16 #include "modules/fetch/BodyStreamBuffer.h" | 17 #include "modules/fetch/BodyStreamBuffer.h" |
| 17 #include "modules/fetch/GlobalFetch.h" | 18 #include "modules/fetch/GlobalFetch.h" |
| 18 #include "modules/fetch/Request.h" | 19 #include "modules/fetch/Request.h" |
| 19 #include "modules/fetch/Response.h" | 20 #include "modules/fetch/Response.h" |
| 20 #include "public/platform/WebServiceWorkerCache.h" | 21 #include "public/platform/WebServiceWorkerCache.h" |
| 21 | 22 |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 128 { | 129 { |
| 129 OwnPtr<WebServiceWorkerCacheError> reason = adoptPtr(rawReason); | 130 OwnPtr<WebServiceWorkerCacheError> reason = adoptPtr(rawReason); |
| 130 m_resolver->reject(CacheStorageError::createException(*reason)); | 131 m_resolver->reject(CacheStorageError::createException(*reason)); |
| 131 m_resolver.clear(); | 132 m_resolver.clear(); |
| 132 } | 133 } |
| 133 | 134 |
| 134 private: | 135 private: |
| 135 RefPtrWillBePersistent<ScriptPromiseResolver> m_resolver; | 136 RefPtrWillBePersistent<ScriptPromiseResolver> m_resolver; |
| 136 }; | 137 }; |
| 137 | 138 |
| 138 ScriptPromise rejectAsNotImplemented(ScriptState* scriptState) | 139 // This class provides Promise.all() for ScriptPromise. |
| 139 { | 140 // TODO(nhiroki): Move this somewhere else so that other components can reuse. |
| 140 return ScriptPromise::rejectWithDOMException(scriptState, DOMException::crea
te(NotSupportedError, "Cache is not implemented")); | 141 // TODO(nhiroki): Unfortunately, we have to go through V8 to wait for the fetch |
| 141 } | 142 // promise. It should be better to achieve this only within C++ world. |
| 143 class CacheStoragePromiseAll final : public GarbageCollectedFinalized<CacheStora
gePromiseAll> { |
| 144 public: |
| 145 CacheStoragePromiseAll(Vector<ScriptPromise> promises, PassRefPtrWillBeRawPt
r<ScriptPromiseResolver> resolver) |
| 146 : m_numberOfPendingPromises(promises.size()) |
| 147 , m_resolver(resolver) |
| 148 { |
| 149 m_values.resize(promises.size()); |
| 150 for (size_t i = 0; i < promises.size(); ++i) |
| 151 promises[i].then(createFulfillFunction(i), createRejectFunction()); |
| 152 } |
| 153 |
| 154 void onFulfilled(size_t index, const ScriptValue& value) |
| 155 { |
| 156 ASSERT(index < m_values.size()); |
| 157 if (m_isSettled) |
| 158 return; |
| 159 m_values[index] = value; |
| 160 if (--m_numberOfPendingPromises > 0) |
| 161 return; |
| 162 m_isSettled = true; |
| 163 m_resolver->resolve(m_values); |
| 164 } |
| 165 |
| 166 void onRejected(const ScriptValue& value) |
| 167 { |
| 168 if (m_isSettled) |
| 169 return; |
| 170 m_isSettled = true; |
| 171 m_resolver->reject(value); |
| 172 } |
| 173 |
| 174 ScriptPromise promise() { return m_resolver->promise(); } |
| 175 |
| 176 DEFINE_INLINE_VIRTUAL_TRACE() |
| 177 { |
| 178 visitor->trace(m_resolver); |
| 179 visitor->trace(m_values); |
| 180 } |
| 181 |
| 182 private: |
| 183 class AdapterFunction : public ScriptFunction { |
| 184 public: |
| 185 enum ResolveType { |
| 186 Fulfilled, |
| 187 Rejected, |
| 188 }; |
| 189 |
| 190 static v8::Local<v8::Function> create(ScriptState* scriptState, ResolveT
ype resolveType, size_t index, CacheStoragePromiseAll* promiseAll) |
| 191 { |
| 192 AdapterFunction* self = new AdapterFunction(scriptState, resolveType
, index, promiseAll); |
| 193 return self->bindToV8Function(); |
| 194 } |
| 195 |
| 196 DEFINE_INLINE_VIRTUAL_TRACE() |
| 197 { |
| 198 visitor->trace(m_promiseAll); |
| 199 ScriptFunction::trace(visitor); |
| 200 } |
| 201 |
| 202 private: |
| 203 AdapterFunction(ScriptState* scriptState, ResolveType resolveType, size_
t index, CacheStoragePromiseAll* promiseAll) |
| 204 : ScriptFunction(scriptState) |
| 205 , m_resolveType(resolveType) |
| 206 , m_index(index) |
| 207 , m_promiseAll(promiseAll) { } |
| 208 |
| 209 ScriptValue call(ScriptValue value) override |
| 210 { |
| 211 if (m_resolveType == Fulfilled) |
| 212 m_promiseAll->onFulfilled(m_index, value); |
| 213 else |
| 214 m_promiseAll->onRejected(value); |
| 215 return ScriptValue(scriptState(), m_promiseAll->promise().v8Value())
; |
| 216 } |
| 217 |
| 218 const ResolveType m_resolveType; |
| 219 const size_t m_index; |
| 220 Member<CacheStoragePromiseAll> m_promiseAll; |
| 221 }; |
| 222 |
| 223 v8::Local<v8::Function> createFulfillFunction(size_t index) |
| 224 { |
| 225 return AdapterFunction::create(m_resolver->scriptState(), AdapterFunctio
n::Fulfilled, index, this); |
| 226 } |
| 227 |
| 228 v8::Local<v8::Function> createRejectFunction() |
| 229 { |
| 230 return AdapterFunction::create(m_resolver->scriptState(), AdapterFunctio
n::Rejected, 0, this); |
| 231 } |
| 232 |
| 233 size_t m_numberOfPendingPromises; |
| 234 RefPtrWillBeMember<ScriptPromiseResolver> m_resolver; |
| 235 bool m_isSettled = false; |
| 236 Vector<ScriptValue> m_values; |
| 237 }; |
| 142 | 238 |
| 143 } // namespace | 239 } // namespace |
| 144 | 240 |
| 145 class Cache::FetchResolvedForAdd final : public ScriptFunction { | 241 class Cache::FetchResolvedForAdd final : public ScriptFunction { |
| 146 public: | 242 public: |
| 147 static v8::Local<v8::Function> create(ScriptState* scriptState, Cache* cache
, Request* request) | 243 static v8::Local<v8::Function> create(ScriptState* scriptState, Cache* cache
, const HeapVector<Member<Request>>& requests) |
| 148 { | 244 { |
| 149 FetchResolvedForAdd* self = new FetchResolvedForAdd(scriptState, cache,
request); | 245 FetchResolvedForAdd* self = new FetchResolvedForAdd(scriptState, cache,
requests); |
| 150 return self->bindToV8Function(); | 246 return self->bindToV8Function(); |
| 151 } | 247 } |
| 152 | 248 |
| 153 ScriptValue call(ScriptValue value) override | 249 ScriptValue call(ScriptValue value) override |
| 154 { | 250 { |
| 155 Response* response = V8Response::toImplWithTypeCheck(scriptState()->isol
ate(), value.v8Value()); | 251 NonThrowableExceptionState exceptionState; |
| 156 ScriptPromise putPromise = m_cache->putImpl(scriptState(), HeapVector<Me
mber<Request>>(1, m_request), HeapVector<Member<Response>>(1, response)); | 252 HeapVector<Member<Response>> responses = toMemberNativeArray<Response, V
8Response>(value.v8Value(), m_requests.size(), scriptState()->isolate(), excepti
onState); |
| 253 ScriptPromise putPromise = m_cache->putImpl(scriptState(), m_requests, r
esponses); |
| 157 return ScriptValue(scriptState(), putPromise.v8Value()); | 254 return ScriptValue(scriptState(), putPromise.v8Value()); |
| 158 } | 255 } |
| 159 | 256 |
| 160 DEFINE_INLINE_VIRTUAL_TRACE() | 257 DEFINE_INLINE_VIRTUAL_TRACE() |
| 161 { | 258 { |
| 162 visitor->trace(m_cache); | 259 visitor->trace(m_cache); |
| 163 visitor->trace(m_request); | 260 visitor->trace(m_requests); |
| 164 ScriptFunction::trace(visitor); | 261 ScriptFunction::trace(visitor); |
| 165 } | 262 } |
| 166 | 263 |
| 167 private: | 264 private: |
| 168 FetchResolvedForAdd(ScriptState* scriptState, Cache* cache, Request* request
) | 265 FetchResolvedForAdd(ScriptState* scriptState, Cache* cache, const HeapVector
<Member<Request>>& requests) |
| 169 : ScriptFunction(scriptState) | 266 : ScriptFunction(scriptState) |
| 170 , m_cache(cache) | 267 , m_cache(cache) |
| 171 , m_request(request) | 268 , m_requests(requests) |
| 172 { | 269 { |
| 173 } | 270 } |
| 174 | 271 |
| 175 Member<Cache> m_cache; | 272 Member<Cache> m_cache; |
| 176 Member<Request> m_request; | 273 HeapVector<Member<Request>> m_requests; |
| 177 }; | 274 }; |
| 178 | 275 |
| 179 class Cache::BarrierCallbackForPut final : public GarbageCollectedFinalized<Barr
ierCallbackForPut> { | 276 class Cache::BarrierCallbackForPut final : public GarbageCollectedFinalized<Barr
ierCallbackForPut> { |
| 180 public: | 277 public: |
| 181 BarrierCallbackForPut(int numberOfOperations, Cache* cache, PassRefPtrWillBe
RawPtr<ScriptPromiseResolver> resolver) | 278 BarrierCallbackForPut(int numberOfOperations, Cache* cache, PassRefPtrWillBe
RawPtr<ScriptPromiseResolver> resolver) |
| 182 : m_numberOfRemainingOperations(numberOfOperations) | 279 : m_numberOfRemainingOperations(numberOfOperations) |
| 183 , m_cache(cache) | 280 , m_cache(cache) |
| 184 , m_resolver(resolver) | 281 , m_resolver(resolver) |
| 185 { | 282 { |
| 186 ASSERT(0 < m_numberOfRemainingOperations); | 283 ASSERT(0 < m_numberOfRemainingOperations); |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 291 return matchAllImpl(scriptState, request.getAsRequest(), options); | 388 return matchAllImpl(scriptState, request.getAsRequest(), options); |
| 292 Request* newRequest = Request::create(scriptState, request.getAsUSVString(),
exceptionState); | 389 Request* newRequest = Request::create(scriptState, request.getAsUSVString(),
exceptionState); |
| 293 if (exceptionState.hadException()) | 390 if (exceptionState.hadException()) |
| 294 return ScriptPromise(); | 391 return ScriptPromise(); |
| 295 return matchAllImpl(scriptState, newRequest, options); | 392 return matchAllImpl(scriptState, newRequest, options); |
| 296 } | 393 } |
| 297 | 394 |
| 298 ScriptPromise Cache::add(ScriptState* scriptState, const RequestInfo& request, E
xceptionState& exceptionState) | 395 ScriptPromise Cache::add(ScriptState* scriptState, const RequestInfo& request, E
xceptionState& exceptionState) |
| 299 { | 396 { |
| 300 ASSERT(!request.isNull()); | 397 ASSERT(!request.isNull()); |
| 301 Request* newRequest; | 398 HeapVector<Member<Request>> requests; |
| 302 if (request.isRequest()) { | 399 if (request.isRequest()) { |
| 303 newRequest = request.getAsRequest(); | 400 requests.append(request.getAsRequest()); |
| 304 } else { | 401 } else { |
| 305 newRequest = Request::create(scriptState, request.getAsUSVString(), exce
ptionState); | 402 requests.append(Request::create(scriptState, request.getAsUSVString(), e
xceptionState)); |
| 306 | |
| 307 if (exceptionState.hadException()) | 403 if (exceptionState.hadException()) |
| 308 return ScriptPromise(); | 404 return ScriptPromise(); |
| 309 } | 405 } |
| 310 | 406 |
| 311 Vector<Request*> requestVector; | 407 return addAllImpl(scriptState, requests, exceptionState); |
| 312 requestVector.append(newRequest); | |
| 313 return addAllImpl(scriptState, requestVector, exceptionState); | |
| 314 } | 408 } |
| 315 | 409 |
| 316 ScriptPromise Cache::addAll(ScriptState* scriptState, const Vector<ScriptValue>&
rawRequests) | 410 ScriptPromise Cache::addAll(ScriptState* scriptState, const HeapVector<RequestIn
fo>& rawRequests, ExceptionState& exceptionState) |
| 317 { | 411 { |
| 318 // FIXME: Implement this. | 412 HeapVector<Member<Request>> requests; |
| 319 return rejectAsNotImplemented(scriptState); | 413 for (RequestInfo request : rawRequests) { |
| 414 if (request.isRequest()) { |
| 415 requests.append(request.getAsRequest()); |
| 416 } else { |
| 417 requests.append(Request::create(scriptState, request.getAsUSVString(
), exceptionState)); |
| 418 if (exceptionState.hadException()) |
| 419 return ScriptPromise(); |
| 420 } |
| 421 } |
| 422 |
| 423 return addAllImpl(scriptState, requests, exceptionState); |
| 320 } | 424 } |
| 321 | 425 |
| 322 ScriptPromise Cache::deleteFunction(ScriptState* scriptState, const RequestInfo&
request, const CacheQueryOptions& options, ExceptionState& exceptionState) | 426 ScriptPromise Cache::deleteFunction(ScriptState* scriptState, const RequestInfo&
request, const CacheQueryOptions& options, ExceptionState& exceptionState) |
| 323 { | 427 { |
| 324 ASSERT(!request.isNull()); | 428 ASSERT(!request.isNull()); |
| 325 if (request.isRequest()) | 429 if (request.isRequest()) |
| 326 return deleteImpl(scriptState, request.getAsRequest(), options); | 430 return deleteImpl(scriptState, request.getAsRequest(), options); |
| 327 Request* newRequest = Request::create(scriptState, request.getAsUSVString(),
exceptionState); | 431 Request* newRequest = Request::create(scriptState, request.getAsUSVString(),
exceptionState); |
| 328 if (exceptionState.hadException()) | 432 if (exceptionState.hadException()) |
| 329 return ScriptPromise(); | 433 return ScriptPromise(); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 387 { | 491 { |
| 388 WebServiceWorkerRequest webRequest; | 492 WebServiceWorkerRequest webRequest; |
| 389 request->populateWebServiceWorkerRequest(webRequest); | 493 request->populateWebServiceWorkerRequest(webRequest); |
| 390 | 494 |
| 391 RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::
create(scriptState); | 495 RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::
create(scriptState); |
| 392 const ScriptPromise promise = resolver->promise(); | 496 const ScriptPromise promise = resolver->promise(); |
| 393 m_webCache->dispatchMatchAll(new CacheWithResponsesCallbacks(resolver), webR
equest, toWebQueryParams(options)); | 497 m_webCache->dispatchMatchAll(new CacheWithResponsesCallbacks(resolver), webR
equest, toWebQueryParams(options)); |
| 394 return promise; | 498 return promise; |
| 395 } | 499 } |
| 396 | 500 |
| 397 ScriptPromise Cache::addAllImpl(ScriptState* scriptState, const Vector<Request*>
& requests, ExceptionState& exceptionState) | 501 ScriptPromise Cache::addAllImpl(ScriptState* scriptState, const HeapVector<Membe
r<Request>>& requests, ExceptionState& exceptionState) |
| 398 { | 502 { |
| 399 // TODO(gavinp,nhiroki): Implement addAll for more than one element. | |
| 400 ASSERT(requests.size() == 1); | |
| 401 | |
| 402 Vector<RequestInfo> requestInfos; | 503 Vector<RequestInfo> requestInfos; |
| 403 requestInfos.resize(requests.size()); | 504 requestInfos.resize(requests.size()); |
| 505 Vector<ScriptPromise> promises; |
| 506 promises.resize(requests.size()); |
| 404 for (size_t i = 0; i < requests.size(); ++i) { | 507 for (size_t i = 0; i < requests.size(); ++i) { |
| 405 if (!requests[i]->url().protocolIsInHTTPFamily()) | 508 if (!requests[i]->url().protocolIsInHTTPFamily()) |
| 406 return ScriptPromise::reject(scriptState, V8ThrowException::createTy
peError(scriptState->isolate(), "Add/AddAll does not support schemes other than
\"http\" or \"https\"")); | 509 return ScriptPromise::reject(scriptState, V8ThrowException::createTy
peError(scriptState->isolate(), "Add/AddAll does not support schemes other than
\"http\" or \"https\"")); |
| 407 if (requests[i]->method() != "GET") | 510 if (requests[i]->method() != "GET") |
| 408 return ScriptPromise::reject(scriptState, V8ThrowException::createTy
peError(scriptState->isolate(), "Add/AddAll only supports the GET request method
.")); | 511 return ScriptPromise::reject(scriptState, V8ThrowException::createTy
peError(scriptState->isolate(), "Add/AddAll only supports the GET request method
.")); |
| 409 requestInfos[i].setRequest(requests[i]); | 512 requestInfos[i].setRequest(requests[i]); |
| 513 |
| 514 promises[i] = m_scopedFetcher->fetch(scriptState, requestInfos[i], Dicti
onary(), exceptionState); |
| 410 } | 515 } |
| 411 | 516 |
| 412 ScriptPromise fetchPromise = m_scopedFetcher->fetch(scriptState, requestInfo
s[0], Dictionary(), exceptionState); | 517 RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::
create(scriptState); |
| 413 return fetchPromise.then(FetchResolvedForAdd::create(scriptState, this, requ
ests[0])); | 518 CacheStoragePromiseAll* promiseAll = new CacheStoragePromiseAll(promises, re
solver.get()); |
| 519 return promiseAll->promise().then(FetchResolvedForAdd::create(scriptState, t
his, requests)); |
| 414 } | 520 } |
| 415 | 521 |
| 416 ScriptPromise Cache::deleteImpl(ScriptState* scriptState, const Request* request
, const CacheQueryOptions& options) | 522 ScriptPromise Cache::deleteImpl(ScriptState* scriptState, const Request* request
, const CacheQueryOptions& options) |
| 417 { | 523 { |
| 418 WebVector<WebServiceWorkerCache::BatchOperation> batchOperations(size_t(1)); | 524 WebVector<WebServiceWorkerCache::BatchOperation> batchOperations(size_t(1)); |
| 419 batchOperations[0].operationType = WebServiceWorkerCache::OperationTypeDelet
e; | 525 batchOperations[0].operationType = WebServiceWorkerCache::OperationTypeDelet
e; |
| 420 request->populateWebServiceWorkerRequest(batchOperations[0].request); | 526 request->populateWebServiceWorkerRequest(batchOperations[0].request); |
| 421 batchOperations[0].matchParams = toWebQueryParams(options); | 527 batchOperations[0].matchParams = toWebQueryParams(options); |
| 422 | 528 |
| 423 RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::
create(scriptState); | 529 RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::
create(scriptState); |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 493 m_webCache->dispatchKeys(new CacheWithRequestsCallbacks(resolver), 0, toWebQ
ueryParams(options)); | 599 m_webCache->dispatchKeys(new CacheWithRequestsCallbacks(resolver), 0, toWebQ
ueryParams(options)); |
| 494 return promise; | 600 return promise; |
| 495 } | 601 } |
| 496 | 602 |
| 497 WebServiceWorkerCache* Cache::webCache() const | 603 WebServiceWorkerCache* Cache::webCache() const |
| 498 { | 604 { |
| 499 return m_webCache.get(); | 605 return m_webCache.get(); |
| 500 } | 606 } |
| 501 | 607 |
| 502 } // namespace blink | 608 } // namespace blink |
| OLD | NEW |