Home | History | Annotate | Download | only in service_worker
      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 "content/renderer/service_worker/service_worker_cache_storage_dispatcher.h"
      6 
      7 #include <map>
      8 #include <string>
      9 #include <utility>
     10 
     11 #include "base/logging.h"
     12 #include "base/strings/utf_string_conversions.h"
     13 #include "content/common/service_worker/service_worker_messages.h"
     14 #include "content/public/renderer/render_thread.h"
     15 #include "content/renderer/service_worker/service_worker_script_context.h"
     16 #include "third_party/WebKit/public/platform/WebHTTPHeaderVisitor.h"
     17 #include "third_party/WebKit/public/platform/WebServiceWorkerCache.h"
     18 #include "third_party/WebKit/public/platform/WebServiceWorkerRequest.h"
     19 #include "third_party/WebKit/public/platform/WebServiceWorkerResponse.h"
     20 
     21 namespace content {
     22 
     23 using blink::WebServiceWorkerCacheError;
     24 using blink::WebServiceWorkerRequest;
     25 
     26 namespace {
     27 
     28 class HeaderVisitor : public blink::WebHTTPHeaderVisitor {
     29  public:
     30   HeaderVisitor(ServiceWorkerHeaderMap* headers) : headers_(headers) {}
     31   virtual ~HeaderVisitor() {}
     32 
     33   virtual void visitHeader(const blink::WebString& name,
     34                            const blink::WebString& value) {
     35     headers_->insert(ServiceWorkerHeaderMap::value_type(
     36         base::UTF16ToASCII(name), base::UTF16ToASCII(value)));
     37   }
     38 
     39  private:
     40   ServiceWorkerHeaderMap* headers_;
     41 };
     42 
     43 scoped_ptr<HeaderVisitor> MakeHeaderVisitor(ServiceWorkerHeaderMap* headers) {
     44   return scoped_ptr<HeaderVisitor>(new HeaderVisitor(headers)).Pass();
     45 }
     46 
     47 ServiceWorkerFetchRequest FetchRequestFromWebRequest(
     48     const blink::WebServiceWorkerRequest& web_request) {
     49   ServiceWorkerHeaderMap headers;
     50   web_request.visitHTTPHeaderFields(MakeHeaderVisitor(&headers).get());
     51 
     52   return ServiceWorkerFetchRequest(web_request.url(),
     53                                    base::UTF16ToASCII(web_request.method()),
     54                                    headers, web_request.referrerUrl(),
     55                                    web_request.isReload());
     56 }
     57 
     58 void PopulateWebRequestFromFetchRequest(
     59     const ServiceWorkerFetchRequest& request,
     60     blink::WebServiceWorkerRequest* web_request) {
     61   web_request->setURL(request.url);
     62   web_request->setMethod(base::ASCIIToUTF16(request.method));
     63   for (ServiceWorkerHeaderMap::const_iterator i = request.headers.begin(),
     64                                             end = request.headers.end();
     65        i != end; ++i) {
     66     web_request->setHeader(base::ASCIIToUTF16(i->first),
     67                            base::ASCIIToUTF16(i->second));
     68   }
     69   web_request->setReferrer(base::ASCIIToUTF16(request.referrer.spec()),
     70                            blink::WebReferrerPolicy::WebReferrerPolicyNever);
     71   web_request->setIsReload(request.is_reload);
     72 }
     73 
     74 blink::WebVector<blink::WebServiceWorkerRequest> WebRequestsFromRequests(
     75     const std::vector<ServiceWorkerFetchRequest>& requests) {
     76   blink::WebVector<blink::WebServiceWorkerRequest>
     77       web_requests(requests.size());
     78   for (size_t i = 0; i < requests.size(); ++i)
     79     PopulateWebRequestFromFetchRequest(requests[i], &(web_requests[i]));
     80   return web_requests;
     81 }
     82 
     83 ServiceWorkerResponse ResponseFromWebResponse(
     84     const blink::WebServiceWorkerResponse& web_response) {
     85   ServiceWorkerHeaderMap headers;
     86   web_response.visitHTTPHeaderFields(MakeHeaderVisitor(&headers).get());
     87 
     88   return ServiceWorkerResponse(
     89       web_response.url(), web_response.status(),
     90       base::UTF16ToASCII(web_response.statusText()), headers,
     91       base::UTF16ToASCII(web_response.blobUUID()));
     92 }
     93 
     94 void PopulateWebResponseFromResponse(
     95     const ServiceWorkerResponse& response,
     96     blink::WebServiceWorkerResponse* web_response) {
     97   web_response->setURL(response.url);
     98   web_response->setStatus(response.status_code);
     99   web_response->setStatusText(base::ASCIIToUTF16(response.status_text));
    100   for (ServiceWorkerHeaderMap::const_iterator i = response.headers.begin(),
    101                                             end = response.headers.end();
    102        i != end; ++i) {
    103     web_response->setHeader(base::ASCIIToUTF16(i->first),
    104                             base::ASCIIToUTF16(i->second));
    105   }
    106   // TODO(gavinp): set blob here.
    107 }
    108 
    109 blink::WebVector<blink::WebServiceWorkerResponse> WebResponsesFromResponses(
    110     const std::vector<ServiceWorkerResponse>& responses) {
    111   blink::WebVector<blink::WebServiceWorkerResponse>
    112       web_responses(responses.size());
    113   for (size_t i = 0; i < responses.size(); ++i)
    114     PopulateWebResponseFromResponse(responses[i], &(web_responses[i]));
    115   return web_responses;
    116 }
    117 
    118 ServiceWorkerCacheQueryParams QueryParamsFromWebQueryParams(
    119     const blink::WebServiceWorkerCache::QueryParams& web_query_params) {
    120   ServiceWorkerCacheQueryParams query_params;
    121   query_params.ignore_search = web_query_params.ignoreSearch;
    122   query_params.ignore_method = web_query_params.ignoreMethod;
    123   query_params.ignore_vary = web_query_params.ignoreVary;
    124   query_params.prefix_match = web_query_params.prefixMatch;
    125 
    126   return query_params;
    127 }
    128 
    129 ServiceWorkerCacheOperationType CacheOperationTypeFromWebCacheOperationType(
    130     blink::WebServiceWorkerCache::OperationType operation_type) {
    131   switch (operation_type) {
    132     case blink::WebServiceWorkerCache::OperationTypePut:
    133       return SERVICE_WORKER_CACHE_OPERATION_TYPE_PUT;
    134     case blink::WebServiceWorkerCache::OperationTypeDelete:
    135       return SERVICE_WORKER_CACHE_OPERATION_TYPE_DELETE;
    136     default:
    137       return SERVICE_WORKER_CACHE_OPERATION_TYPE_UNDEFINED;
    138   }
    139 }
    140 
    141 ServiceWorkerBatchOperation BatchOperationFromWebBatchOperation(
    142     const blink::WebServiceWorkerCache::BatchOperation& web_operation) {
    143   ServiceWorkerBatchOperation operation;
    144   operation.operation_type =
    145       CacheOperationTypeFromWebCacheOperationType(web_operation.operationType);
    146   operation.request = FetchRequestFromWebRequest(web_operation.request);
    147   operation.response = ResponseFromWebResponse(web_operation.response);
    148   operation.match_params =
    149       QueryParamsFromWebQueryParams(web_operation.matchParams);
    150   return operation;
    151 }
    152 
    153 template<typename T>
    154 void ClearCallbacksMapWithErrors(T* callbacks_map) {
    155   typename T::iterator iter(callbacks_map);
    156   while (!iter.IsAtEnd()) {
    157     blink::WebServiceWorkerCacheError reason =
    158         blink::WebServiceWorkerCacheErrorNotFound;
    159     iter.GetCurrentValue()->onError(&reason);
    160     callbacks_map->Remove(iter.GetCurrentKey());
    161     iter.Advance();
    162   }
    163 }
    164 
    165 }  // namespace
    166 
    167 // The WebCache object is the Chromium side implementation of the Blink
    168 // WebServiceWorkerCache API. Most of its methods delegate directly to the
    169 // ServiceWorkerStorage object, which is able to assign unique IDs as well
    170 // as have a lifetime longer than the requests.
    171 class ServiceWorkerCacheStorageDispatcher::WebCache
    172     : public blink::WebServiceWorkerCache {
    173  public:
    174   WebCache(base::WeakPtr<ServiceWorkerCacheStorageDispatcher> dispatcher,
    175            int cache_id)
    176       : dispatcher_(dispatcher),
    177         cache_id_(cache_id) {}
    178 
    179   virtual ~WebCache() {
    180     if (dispatcher_)
    181       dispatcher_->OnWebCacheDestruction(cache_id_);
    182   }
    183 
    184   // From blink::WebServiceWorkerCache:
    185   virtual void dispatchMatch(CacheMatchCallbacks* callbacks,
    186                              const blink::WebServiceWorkerRequest& request,
    187                              const QueryParams& query_params) {
    188     if (!dispatcher_)
    189       return;
    190     dispatcher_->dispatchMatchForCache(cache_id_, callbacks, request,
    191                                        query_params);
    192   }
    193   virtual void dispatchMatchAll(CacheWithResponsesCallbacks* callbacks,
    194                                 const blink::WebServiceWorkerRequest& request,
    195                                 const QueryParams& query_params) {
    196     if (!dispatcher_)
    197       return;
    198     dispatcher_->dispatchMatchAllForCache(cache_id_, callbacks, request,
    199                                           query_params);
    200   }
    201   virtual void dispatchKeys(CacheWithRequestsCallbacks* callbacks,
    202                             const blink::WebServiceWorkerRequest* request,
    203                             const QueryParams& query_params) {
    204     if (!dispatcher_)
    205       return;
    206     dispatcher_->dispatchKeysForCache(cache_id_, callbacks, request,
    207                                       query_params);
    208   }
    209   virtual void dispatchBatch(
    210       CacheWithResponsesCallbacks* callbacks,
    211       const blink::WebVector<BatchOperation>& batch_operations) {
    212     if (!dispatcher_)
    213       return;
    214     dispatcher_->dispatchBatchForCache(cache_id_, callbacks, batch_operations);
    215   }
    216 
    217  private:
    218   const base::WeakPtr<ServiceWorkerCacheStorageDispatcher> dispatcher_;
    219   const int cache_id_;
    220 };
    221 
    222 ServiceWorkerCacheStorageDispatcher::ServiceWorkerCacheStorageDispatcher(
    223     ServiceWorkerScriptContext* script_context)
    224     : script_context_(script_context),
    225       weak_factory_(this) {}
    226 
    227 ServiceWorkerCacheStorageDispatcher::~ServiceWorkerCacheStorageDispatcher() {
    228   ClearCallbacksMapWithErrors(&get_callbacks_);
    229   ClearCallbacksMapWithErrors(&has_callbacks_);
    230   ClearCallbacksMapWithErrors(&create_callbacks_);
    231   ClearCallbacksMapWithErrors(&delete_callbacks_);
    232   ClearCallbacksMapWithErrors(&keys_callbacks_);
    233 
    234   ClearCallbacksMapWithErrors(&cache_match_callbacks_);
    235   ClearCallbacksMapWithErrors(&cache_match_all_callbacks_);
    236   ClearCallbacksMapWithErrors(&cache_keys_callbacks_);
    237   ClearCallbacksMapWithErrors(&cache_batch_callbacks_);
    238 }
    239 
    240 bool ServiceWorkerCacheStorageDispatcher::OnMessageReceived(
    241     const IPC::Message& message)  {
    242   bool handled = true;
    243   IPC_BEGIN_MESSAGE_MAP(ServiceWorkerCacheStorageDispatcher, message)
    244       IPC_MESSAGE_HANDLER(ServiceWorkerMsg_CacheStorageGetSuccess,
    245                           OnCacheStorageGetSuccess)
    246       IPC_MESSAGE_HANDLER(ServiceWorkerMsg_CacheStorageHasSuccess,
    247                           OnCacheStorageHasSuccess)
    248       IPC_MESSAGE_HANDLER(ServiceWorkerMsg_CacheStorageCreateSuccess,
    249                           OnCacheStorageCreateSuccess)
    250       IPC_MESSAGE_HANDLER(ServiceWorkerMsg_CacheStorageDeleteSuccess,
    251                           OnCacheStorageDeleteSuccess)
    252       IPC_MESSAGE_HANDLER(ServiceWorkerMsg_CacheStorageKeysSuccess,
    253                           OnCacheStorageKeysSuccess)
    254       IPC_MESSAGE_HANDLER(ServiceWorkerMsg_CacheStorageGetError,
    255                           OnCacheStorageGetError)
    256       IPC_MESSAGE_HANDLER(ServiceWorkerMsg_CacheStorageHasError,
    257                           OnCacheStorageHasError)
    258       IPC_MESSAGE_HANDLER(ServiceWorkerMsg_CacheStorageCreateError,
    259                           OnCacheStorageCreateError)
    260       IPC_MESSAGE_HANDLER(ServiceWorkerMsg_CacheStorageDeleteError,
    261                           OnCacheStorageDeleteError)
    262       IPC_MESSAGE_HANDLER(ServiceWorkerMsg_CacheStorageKeysError,
    263                           OnCacheStorageKeysError)
    264       IPC_MESSAGE_HANDLER(ServiceWorkerMsg_CacheMatchSuccess,
    265                           OnCacheMatchSuccess)
    266       IPC_MESSAGE_HANDLER(ServiceWorkerMsg_CacheMatchAllSuccess,
    267                           OnCacheMatchAllSuccess)
    268       IPC_MESSAGE_HANDLER(ServiceWorkerMsg_CacheKeysSuccess,
    269                           OnCacheKeysSuccess)
    270       IPC_MESSAGE_HANDLER(ServiceWorkerMsg_CacheBatchSuccess,
    271                           OnCacheBatchSuccess)
    272       IPC_MESSAGE_HANDLER(ServiceWorkerMsg_CacheMatchError,
    273                           OnCacheMatchError)
    274       IPC_MESSAGE_HANDLER(ServiceWorkerMsg_CacheMatchAllError,
    275                           OnCacheMatchAllError)
    276       IPC_MESSAGE_HANDLER(ServiceWorkerMsg_CacheKeysError,
    277                           OnCacheKeysError)
    278       IPC_MESSAGE_HANDLER(ServiceWorkerMsg_CacheBatchError,
    279                           OnCacheBatchError)
    280      IPC_MESSAGE_UNHANDLED(handled = false)
    281   IPC_END_MESSAGE_MAP()
    282 
    283   return handled;
    284 }
    285 
    286 void ServiceWorkerCacheStorageDispatcher::OnCacheStorageGetSuccess(
    287     int request_id,
    288     int cache_id) {
    289   WebCache* web_cache = new WebCache(weak_factory_.GetWeakPtr(), cache_id);
    290   web_caches_.AddWithID(web_cache, cache_id);
    291   CacheStorageWithCacheCallbacks* callbacks = get_callbacks_.Lookup(request_id);
    292   callbacks->onSuccess(web_cache);
    293   get_callbacks_.Remove(request_id);
    294 }
    295 
    296 void ServiceWorkerCacheStorageDispatcher::OnCacheStorageHasSuccess(
    297     int request_id) {
    298   CacheStorageCallbacks* callbacks = has_callbacks_.Lookup(request_id);
    299   callbacks->onSuccess();
    300   has_callbacks_.Remove(request_id);
    301 }
    302 
    303 void ServiceWorkerCacheStorageDispatcher::OnCacheStorageCreateSuccess(
    304     int request_id,
    305     int cache_id) {
    306   WebCache* web_cache = new WebCache(weak_factory_.GetWeakPtr(), cache_id);
    307   web_caches_.AddWithID(web_cache, cache_id);
    308   CacheStorageWithCacheCallbacks* callbacks =
    309       create_callbacks_.Lookup(request_id);
    310   callbacks->onSuccess(web_cache);
    311   create_callbacks_.Remove(request_id);
    312 }
    313 
    314 void ServiceWorkerCacheStorageDispatcher::OnCacheStorageDeleteSuccess(
    315     int request_id) {
    316   CacheStorageCallbacks* callbacks = delete_callbacks_.Lookup(request_id);
    317   callbacks->onSuccess();
    318   delete_callbacks_.Remove(request_id);
    319 }
    320 
    321 void ServiceWorkerCacheStorageDispatcher::OnCacheStorageKeysSuccess(
    322     int request_id,
    323     const std::vector<base::string16>& keys) {
    324   CacheStorageKeysCallbacks* callbacks = keys_callbacks_.Lookup(request_id);
    325   blink::WebVector<blink::WebString> webKeys(keys.size());
    326   for (size_t i = 0; i < keys.size(); ++i)
    327     webKeys[i] = keys[i];
    328 
    329   callbacks->onSuccess(&webKeys);
    330   keys_callbacks_.Remove(request_id);
    331 }
    332 
    333 void ServiceWorkerCacheStorageDispatcher::OnCacheStorageGetError(
    334       int request_id,
    335       blink::WebServiceWorkerCacheError reason) {
    336   CacheStorageWithCacheCallbacks* callbacks =
    337       get_callbacks_.Lookup(request_id);
    338   callbacks->onError(&reason);
    339   get_callbacks_.Remove(request_id);
    340 }
    341 
    342 void ServiceWorkerCacheStorageDispatcher::OnCacheStorageHasError(
    343       int request_id,
    344       blink::WebServiceWorkerCacheError reason) {
    345   CacheStorageCallbacks* callbacks = has_callbacks_.Lookup(request_id);
    346   callbacks->onError(&reason);
    347   has_callbacks_.Remove(request_id);
    348 }
    349 
    350 void ServiceWorkerCacheStorageDispatcher::OnCacheStorageCreateError(
    351     int request_id,
    352     blink::WebServiceWorkerCacheError reason) {
    353   CacheStorageWithCacheCallbacks* callbacks =
    354       create_callbacks_.Lookup(request_id);
    355   callbacks->onError(&reason);
    356   create_callbacks_.Remove(request_id);
    357 }
    358 
    359 void ServiceWorkerCacheStorageDispatcher::OnCacheStorageDeleteError(
    360       int request_id,
    361       blink::WebServiceWorkerCacheError reason) {
    362   CacheStorageCallbacks* callbacks = delete_callbacks_.Lookup(request_id);
    363   callbacks->onError(&reason);
    364   delete_callbacks_.Remove(request_id);
    365 }
    366 
    367 void ServiceWorkerCacheStorageDispatcher::OnCacheStorageKeysError(
    368       int request_id,
    369       blink::WebServiceWorkerCacheError reason) {
    370   CacheStorageKeysCallbacks* callbacks = keys_callbacks_.Lookup(request_id);
    371   callbacks->onError(&reason);
    372   keys_callbacks_.Remove(request_id);
    373 }
    374 
    375 void ServiceWorkerCacheStorageDispatcher::OnCacheMatchSuccess(
    376     int request_id,
    377     const ServiceWorkerResponse& response) {
    378   blink::WebServiceWorkerCache::CacheMatchCallbacks* callbacks =
    379       cache_match_callbacks_.Lookup(request_id);
    380 
    381   blink::WebServiceWorkerResponse web_response;
    382   PopulateWebResponseFromResponse(response, &web_response);
    383   callbacks->onSuccess(&web_response);
    384   cache_match_callbacks_.Remove(request_id);
    385 }
    386 
    387 void ServiceWorkerCacheStorageDispatcher::OnCacheMatchAllSuccess(
    388     int request_id,
    389     const std::vector<ServiceWorkerResponse>& responses) {
    390   blink::WebServiceWorkerCache::CacheWithResponsesCallbacks* callbacks =
    391       cache_match_all_callbacks_.Lookup(request_id);
    392 
    393   blink::WebVector<blink::WebServiceWorkerResponse>
    394       web_responses = WebResponsesFromResponses(responses);
    395   callbacks->onSuccess(&web_responses);
    396   cache_match_all_callbacks_.Remove(request_id);
    397 }
    398 
    399 void ServiceWorkerCacheStorageDispatcher::OnCacheKeysSuccess(
    400 
    401     int request_id,
    402     const std::vector<ServiceWorkerFetchRequest>& requests) {
    403   blink::WebServiceWorkerCache::CacheWithRequestsCallbacks* callbacks =
    404       cache_keys_callbacks_.Lookup(request_id);
    405 
    406   blink::WebVector<blink::WebServiceWorkerRequest>
    407       web_requests = WebRequestsFromRequests(requests);
    408   callbacks->onSuccess(&web_requests);
    409   cache_keys_callbacks_.Remove(request_id);
    410 }
    411 
    412 void ServiceWorkerCacheStorageDispatcher::OnCacheBatchSuccess(
    413     int request_id,
    414     const std::vector<ServiceWorkerResponse>& responses) {
    415   blink::WebServiceWorkerCache::CacheWithResponsesCallbacks* callbacks =
    416       cache_batch_callbacks_.Lookup(request_id);
    417 
    418   blink::WebVector<blink::WebServiceWorkerResponse>
    419       web_responses = WebResponsesFromResponses(responses);
    420   callbacks->onSuccess(&web_responses);
    421   cache_batch_callbacks_.Remove(request_id);
    422 }
    423 
    424 void ServiceWorkerCacheStorageDispatcher::OnCacheMatchError(
    425     int request_id,
    426     blink::WebServiceWorkerCacheError reason) {
    427   blink::WebServiceWorkerCache::CacheMatchCallbacks* callbacks =
    428       cache_match_callbacks_.Lookup(request_id);
    429   callbacks->onError(&reason);
    430   cache_match_callbacks_.Remove(request_id);
    431 }
    432 
    433 void ServiceWorkerCacheStorageDispatcher::OnCacheMatchAllError(
    434     int request_id,
    435     blink::WebServiceWorkerCacheError reason) {
    436   blink::WebServiceWorkerCache::CacheWithResponsesCallbacks* callbacks =
    437       cache_match_all_callbacks_.Lookup(request_id);
    438   callbacks->onError(&reason);
    439   cache_match_all_callbacks_.Remove(request_id);
    440 }
    441 
    442 void ServiceWorkerCacheStorageDispatcher::OnCacheKeysError(
    443     int request_id,
    444     blink::WebServiceWorkerCacheError reason) {
    445   blink::WebServiceWorkerCache::CacheWithRequestsCallbacks* callbacks =
    446       cache_keys_callbacks_.Lookup(request_id);
    447   callbacks->onError(&reason);
    448   cache_keys_callbacks_.Remove(request_id);
    449 }
    450 
    451 void ServiceWorkerCacheStorageDispatcher::OnCacheBatchError(
    452     int request_id,
    453     blink::WebServiceWorkerCacheError reason) {
    454   blink::WebServiceWorkerCache::CacheWithResponsesCallbacks* callbacks =
    455       cache_batch_callbacks_.Lookup(request_id);
    456   callbacks->onError(&reason);
    457   cache_batch_callbacks_.Remove(request_id);
    458 }
    459 
    460 void ServiceWorkerCacheStorageDispatcher::dispatchGet(
    461     CacheStorageWithCacheCallbacks* callbacks,
    462     const blink::WebString& cacheName) {
    463   int request_id = get_callbacks_.Add(callbacks);
    464   script_context_->Send(new ServiceWorkerHostMsg_CacheStorageGet(
    465       script_context_->GetRoutingID(), request_id, cacheName));
    466 }
    467 
    468 void ServiceWorkerCacheStorageDispatcher::dispatchHas(
    469     CacheStorageCallbacks* callbacks,
    470     const blink::WebString& cacheName) {
    471   int request_id = has_callbacks_.Add(callbacks);
    472   script_context_->Send(new ServiceWorkerHostMsg_CacheStorageHas(
    473       script_context_->GetRoutingID(), request_id, cacheName));
    474 }
    475 
    476 void ServiceWorkerCacheStorageDispatcher::dispatchCreate(
    477     CacheStorageWithCacheCallbacks* callbacks,
    478     const blink::WebString& cacheName) {
    479   int request_id = create_callbacks_.Add(callbacks);
    480   script_context_->Send(new ServiceWorkerHostMsg_CacheStorageCreate(
    481       script_context_->GetRoutingID(), request_id, cacheName));
    482 }
    483 
    484 void ServiceWorkerCacheStorageDispatcher::dispatchDelete(
    485     CacheStorageCallbacks* callbacks,
    486     const blink::WebString& cacheName) {
    487   int request_id = delete_callbacks_.Add(callbacks);
    488   script_context_->Send(new ServiceWorkerHostMsg_CacheStorageDelete(
    489       script_context_->GetRoutingID(), request_id, cacheName));
    490 }
    491 
    492 void ServiceWorkerCacheStorageDispatcher::dispatchKeys(
    493     CacheStorageKeysCallbacks* callbacks) {
    494   int request_id = keys_callbacks_.Add(callbacks);
    495   script_context_->Send(new ServiceWorkerHostMsg_CacheStorageKeys(
    496       script_context_->GetRoutingID(), request_id));
    497 }
    498 
    499 void ServiceWorkerCacheStorageDispatcher::dispatchMatchForCache(
    500     int cache_id,
    501     blink::WebServiceWorkerCache::CacheMatchCallbacks* callbacks,
    502     const blink::WebServiceWorkerRequest& request,
    503     const blink::WebServiceWorkerCache::QueryParams& query_params) {
    504   int request_id = cache_match_callbacks_.Add(callbacks);
    505 
    506   script_context_->Send(new ServiceWorkerHostMsg_CacheMatch(
    507       script_context_->GetRoutingID(), request_id, cache_id,
    508       FetchRequestFromWebRequest(request),
    509       QueryParamsFromWebQueryParams(query_params)));
    510 }
    511 
    512 void ServiceWorkerCacheStorageDispatcher::dispatchMatchAllForCache(
    513     int cache_id,
    514     blink::WebServiceWorkerCache::CacheWithResponsesCallbacks* callbacks,
    515     const blink::WebServiceWorkerRequest& request,
    516     const blink::WebServiceWorkerCache::QueryParams& query_params) {
    517   int request_id = cache_match_all_callbacks_.Add(callbacks);
    518 
    519   script_context_->Send(new ServiceWorkerHostMsg_CacheMatchAll(
    520       script_context_->GetRoutingID(), request_id, cache_id,
    521       FetchRequestFromWebRequest(request),
    522       QueryParamsFromWebQueryParams(query_params)));
    523 }
    524 
    525 void ServiceWorkerCacheStorageDispatcher::dispatchKeysForCache(
    526     int cache_id,
    527     blink::WebServiceWorkerCache::CacheWithRequestsCallbacks* callbacks,
    528     const blink::WebServiceWorkerRequest* request,
    529     const blink::WebServiceWorkerCache::QueryParams& query_params) {
    530   int request_id = cache_keys_callbacks_.Add(callbacks);
    531 
    532   script_context_->Send(new ServiceWorkerHostMsg_CacheKeys(
    533       script_context_->GetRoutingID(), request_id, cache_id,
    534       request ? FetchRequestFromWebRequest(*request)
    535               : ServiceWorkerFetchRequest(),
    536       QueryParamsFromWebQueryParams(query_params)));
    537 }
    538 
    539 void ServiceWorkerCacheStorageDispatcher::dispatchBatchForCache(
    540     int cache_id,
    541     blink::WebServiceWorkerCache::CacheWithResponsesCallbacks* callbacks,
    542     const blink::WebVector<
    543         blink::WebServiceWorkerCache::BatchOperation>& web_operations) {
    544   int request_id = cache_batch_callbacks_.Add(callbacks);
    545 
    546   std::vector<ServiceWorkerBatchOperation> operations;
    547   operations.reserve(web_operations.size());
    548   for (size_t i = 0; i < web_operations.size(); ++i) {
    549     operations.push_back(
    550         BatchOperationFromWebBatchOperation(web_operations[i]));
    551   }
    552 
    553   script_context_->Send(new ServiceWorkerHostMsg_CacheBatch(
    554       script_context_->GetRoutingID(), request_id, cache_id, operations));
    555 }
    556 
    557 void ServiceWorkerCacheStorageDispatcher::OnWebCacheDestruction(int cache_id) {
    558   web_caches_.Remove(cache_id);
    559   script_context_->Send(new ServiceWorkerHostMsg_CacheClosed(
    560       script_context_->GetRoutingID(), cache_id));
    561 }
    562 
    563 }  // namespace content
    564