[refactor] More post-NSS WebCrypto cleanups (utility functions).
[chromium-blink-merge.git] / content / browser / cache_storage / cache_storage_dispatcher_host.cc
blob3dd8d45ec15efd528c4790e62c98a9f658ebc4f5
1 // Copyright 2015 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.
5 #include "content/browser/cache_storage/cache_storage_dispatcher_host.h"
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "base/strings/string16.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "base/trace_event/trace_event.h"
12 #include "content/browser/bad_message.h"
13 #include "content/browser/cache_storage/cache_storage_cache.h"
14 #include "content/browser/cache_storage/cache_storage_context_impl.h"
15 #include "content/browser/cache_storage/cache_storage_manager.h"
16 #include "content/common/cache_storage/cache_storage_messages.h"
17 #include "content/public/browser/content_browser_client.h"
18 #include "content/public/common/origin_util.h"
19 #include "storage/browser/blob/blob_data_handle.h"
20 #include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerCacheError.h"
22 namespace content {
24 namespace {
26 const uint32 kFilteredMessageClasses[] = {CacheStorageMsgStart};
28 blink::WebServiceWorkerCacheError ToWebServiceWorkerCacheError(
29 CacheStorageError err) {
30 switch (err) {
31 case CACHE_STORAGE_OK:
32 NOTREACHED();
33 return blink::WebServiceWorkerCacheErrorNotImplemented;
34 case CACHE_STORAGE_ERROR_EXISTS:
35 return blink::WebServiceWorkerCacheErrorExists;
36 case CACHE_STORAGE_ERROR_STORAGE:
37 // TODO(nhiroki): Add WebServiceWorkerCacheError equivalent to
38 // CACHE_STORAGE_ERROR_STORAGE.
39 return blink::WebServiceWorkerCacheErrorNotFound;
40 case CACHE_STORAGE_ERROR_NOT_FOUND:
41 return blink::WebServiceWorkerCacheErrorNotFound;
43 NOTREACHED();
44 return blink::WebServiceWorkerCacheErrorNotImplemented;
47 bool OriginCanAccessCacheStorage(const GURL& url) {
48 return IsOriginSecure(url);
51 } // namespace
53 CacheStorageDispatcherHost::CacheStorageDispatcherHost()
54 : BrowserMessageFilter(kFilteredMessageClasses,
55 arraysize(kFilteredMessageClasses)) {
58 CacheStorageDispatcherHost::~CacheStorageDispatcherHost() {
61 void CacheStorageDispatcherHost::Init(CacheStorageContextImpl* context) {
62 DCHECK_CURRENTLY_ON(BrowserThread::UI);
63 BrowserThread::PostTask(
64 BrowserThread::IO, FROM_HERE,
65 base::Bind(&CacheStorageDispatcherHost::CreateCacheListener, this,
66 make_scoped_refptr(context)));
69 void CacheStorageDispatcherHost::OnDestruct() const {
70 BrowserThread::DeleteOnIOThread::Destruct(this);
73 bool CacheStorageDispatcherHost::OnMessageReceived(
74 const IPC::Message& message) {
75 DCHECK_CURRENTLY_ON(BrowserThread::IO);
77 bool handled = true;
78 IPC_BEGIN_MESSAGE_MAP(CacheStorageDispatcherHost, message)
79 IPC_MESSAGE_HANDLER(CacheStorageHostMsg_CacheStorageHas, OnCacheStorageHas)
80 IPC_MESSAGE_HANDLER(CacheStorageHostMsg_CacheStorageOpen, OnCacheStorageOpen)
81 IPC_MESSAGE_HANDLER(CacheStorageHostMsg_CacheStorageDelete,
82 OnCacheStorageDelete)
83 IPC_MESSAGE_HANDLER(CacheStorageHostMsg_CacheStorageKeys, OnCacheStorageKeys)
84 IPC_MESSAGE_HANDLER(CacheStorageHostMsg_CacheStorageMatch,
85 OnCacheStorageMatch)
86 IPC_MESSAGE_HANDLER(CacheStorageHostMsg_CacheMatch, OnCacheMatch)
87 IPC_MESSAGE_HANDLER(CacheStorageHostMsg_CacheMatchAll, OnCacheMatchAll)
88 IPC_MESSAGE_HANDLER(CacheStorageHostMsg_CacheKeys, OnCacheKeys)
89 IPC_MESSAGE_HANDLER(CacheStorageHostMsg_CacheBatch, OnCacheBatch)
90 IPC_MESSAGE_HANDLER(CacheStorageHostMsg_CacheClosed, OnCacheClosed)
91 IPC_MESSAGE_HANDLER(CacheStorageHostMsg_BlobDataHandled, OnBlobDataHandled)
92 IPC_MESSAGE_UNHANDLED(handled = false)
93 IPC_END_MESSAGE_MAP()
95 if (!handled)
96 bad_message::ReceivedBadMessage(this, bad_message::CSDH_NOT_RECOGNIZED);
97 return handled;
100 void CacheStorageDispatcherHost::CreateCacheListener(
101 CacheStorageContextImpl* context) {
102 DCHECK_CURRENTLY_ON(BrowserThread::IO);
103 context_ = context;
106 void CacheStorageDispatcherHost::OnCacheStorageHas(
107 int thread_id,
108 int request_id,
109 const GURL& origin,
110 const base::string16& cache_name) {
111 TRACE_EVENT0("CacheStorage", "CacheStorageDispatcherHost::OnCacheStorageHas");
112 if (!OriginCanAccessCacheStorage(origin)) {
113 bad_message::ReceivedBadMessage(this, bad_message::CSDH_INVALID_ORIGIN);
114 return;
116 context_->cache_manager()->HasCache(
117 origin, base::UTF16ToUTF8(cache_name),
118 base::Bind(&CacheStorageDispatcherHost::OnCacheStorageHasCallback, this,
119 thread_id, request_id));
122 void CacheStorageDispatcherHost::OnCacheStorageOpen(
123 int thread_id,
124 int request_id,
125 const GURL& origin,
126 const base::string16& cache_name) {
127 TRACE_EVENT0("CacheStorage",
128 "CacheStorageDispatcherHost::OnCacheStorageOpen");
129 if (!OriginCanAccessCacheStorage(origin)) {
130 bad_message::ReceivedBadMessage(this, bad_message::CSDH_INVALID_ORIGIN);
131 return;
133 context_->cache_manager()->OpenCache(
134 origin, base::UTF16ToUTF8(cache_name),
135 base::Bind(&CacheStorageDispatcherHost::OnCacheStorageOpenCallback, this,
136 thread_id, request_id));
139 void CacheStorageDispatcherHost::OnCacheStorageDelete(
140 int thread_id,
141 int request_id,
142 const GURL& origin,
143 const base::string16& cache_name) {
144 TRACE_EVENT0("CacheStorage",
145 "CacheStorageDispatcherHost::OnCacheStorageDelete");
146 if (!OriginCanAccessCacheStorage(origin)) {
147 bad_message::ReceivedBadMessage(this, bad_message::CSDH_INVALID_ORIGIN);
148 return;
150 context_->cache_manager()->DeleteCache(
151 origin, base::UTF16ToUTF8(cache_name),
152 base::Bind(&CacheStorageDispatcherHost::OnCacheStorageDeleteCallback,
153 this, thread_id, request_id));
156 void CacheStorageDispatcherHost::OnCacheStorageKeys(int thread_id,
157 int request_id,
158 const GURL& origin) {
159 TRACE_EVENT0("CacheStorage",
160 "CacheStorageDispatcherHost::OnCacheStorageKeys");
161 if (!OriginCanAccessCacheStorage(origin)) {
162 bad_message::ReceivedBadMessage(this, bad_message::CSDH_INVALID_ORIGIN);
163 return;
165 context_->cache_manager()->EnumerateCaches(
166 origin,
167 base::Bind(&CacheStorageDispatcherHost::OnCacheStorageKeysCallback, this,
168 thread_id, request_id));
171 void CacheStorageDispatcherHost::OnCacheStorageMatch(
172 int thread_id,
173 int request_id,
174 const GURL& origin,
175 const ServiceWorkerFetchRequest& request,
176 const CacheStorageCacheQueryParams& match_params) {
177 TRACE_EVENT0("CacheStorage",
178 "CacheStorageDispatcherHost::OnCacheStorageMatch");
179 if (!OriginCanAccessCacheStorage(origin)) {
180 bad_message::ReceivedBadMessage(this, bad_message::CSDH_INVALID_ORIGIN);
181 return;
183 scoped_ptr<ServiceWorkerFetchRequest> scoped_request(
184 new ServiceWorkerFetchRequest(request.url, request.method,
185 request.headers, request.referrer,
186 request.is_reload));
188 if (match_params.cache_name.empty()) {
189 context_->cache_manager()->MatchAllCaches(
190 origin, scoped_request.Pass(),
191 base::Bind(&CacheStorageDispatcherHost::OnCacheStorageMatchCallback,
192 this, thread_id, request_id));
193 return;
195 context_->cache_manager()->MatchCache(
196 origin, base::UTF16ToUTF8(match_params.cache_name), scoped_request.Pass(),
197 base::Bind(&CacheStorageDispatcherHost::OnCacheStorageMatchCallback, this,
198 thread_id, request_id));
201 void CacheStorageDispatcherHost::OnCacheMatch(
202 int thread_id,
203 int request_id,
204 int cache_id,
205 const ServiceWorkerFetchRequest& request,
206 const CacheStorageCacheQueryParams& match_params) {
207 IDToCacheMap::iterator it = id_to_cache_map_.find(cache_id);
208 if (it == id_to_cache_map_.end()) {
209 Send(new CacheStorageMsg_CacheMatchError(
210 thread_id, request_id, blink::WebServiceWorkerCacheErrorNotFound));
211 return;
214 scoped_refptr<CacheStorageCache> cache = it->second;
215 scoped_ptr<ServiceWorkerFetchRequest> scoped_request(
216 new ServiceWorkerFetchRequest(request.url, request.method,
217 request.headers, request.referrer,
218 request.is_reload));
219 cache->Match(scoped_request.Pass(),
220 base::Bind(&CacheStorageDispatcherHost::OnCacheMatchCallback,
221 this, thread_id, request_id, cache));
224 void CacheStorageDispatcherHost::OnCacheMatchAll(
225 int thread_id,
226 int request_id,
227 int cache_id,
228 const ServiceWorkerFetchRequest& request,
229 const CacheStorageCacheQueryParams& match_params) {
230 IDToCacheMap::iterator it = id_to_cache_map_.find(cache_id);
231 if (it == id_to_cache_map_.end()) {
232 Send(new CacheStorageMsg_CacheMatchError(
233 thread_id, request_id, blink::WebServiceWorkerCacheErrorNotFound));
234 return;
237 scoped_refptr<CacheStorageCache> cache = it->second;
238 if (request.url.is_empty()) {
239 cache->MatchAll(
240 base::Bind(&CacheStorageDispatcherHost::OnCacheMatchAllCallback, this,
241 thread_id, request_id, cache));
242 return;
245 scoped_ptr<ServiceWorkerFetchRequest> scoped_request(
246 new ServiceWorkerFetchRequest(request.url, request.method,
247 request.headers, request.referrer,
248 request.is_reload));
249 cache->Match(
250 scoped_request.Pass(),
251 base::Bind(&CacheStorageDispatcherHost::OnCacheMatchAllCallbackAdapter,
252 this, thread_id, request_id, cache));
255 void CacheStorageDispatcherHost::OnCacheKeys(
256 int thread_id,
257 int request_id,
258 int cache_id,
259 const ServiceWorkerFetchRequest& request,
260 const CacheStorageCacheQueryParams& match_params) {
261 IDToCacheMap::iterator it = id_to_cache_map_.find(cache_id);
262 if (it == id_to_cache_map_.end()) {
263 Send(new CacheStorageMsg_CacheKeysError(
264 thread_id, request_id, blink::WebServiceWorkerCacheErrorNotFound));
265 return;
268 scoped_refptr<CacheStorageCache> cache = it->second;
270 cache->Keys(base::Bind(&CacheStorageDispatcherHost::OnCacheKeysCallback, this,
271 thread_id, request_id, cache));
274 void CacheStorageDispatcherHost::OnCacheBatch(
275 int thread_id,
276 int request_id,
277 int cache_id,
278 const std::vector<CacheStorageBatchOperation>& operations) {
279 IDToCacheMap::iterator it = id_to_cache_map_.find(cache_id);
280 if (it == id_to_cache_map_.end()) {
281 Send(new CacheStorageMsg_CacheBatchError(
282 thread_id, request_id, blink::WebServiceWorkerCacheErrorNotFound));
283 return;
285 scoped_refptr<CacheStorageCache> cache = it->second;
286 cache->BatchOperation(
287 operations, base::Bind(&CacheStorageDispatcherHost::OnCacheBatchCallback,
288 this, thread_id, request_id, cache));
291 void CacheStorageDispatcherHost::OnCacheClosed(int cache_id) {
292 DropCacheReference(cache_id);
295 void CacheStorageDispatcherHost::OnBlobDataHandled(const std::string& uuid) {
296 DropBlobDataHandle(uuid);
299 void CacheStorageDispatcherHost::OnCacheStorageHasCallback(
300 int thread_id,
301 int request_id,
302 bool has_cache,
303 CacheStorageError error) {
304 if (error != CACHE_STORAGE_OK) {
305 Send(new CacheStorageMsg_CacheStorageHasError(
306 thread_id, request_id, ToWebServiceWorkerCacheError(error)));
307 return;
309 if (!has_cache) {
310 Send(new CacheStorageMsg_CacheStorageHasError(
311 thread_id, request_id, blink::WebServiceWorkerCacheErrorNotFound));
312 return;
314 Send(new CacheStorageMsg_CacheStorageHasSuccess(thread_id, request_id));
317 void CacheStorageDispatcherHost::OnCacheStorageOpenCallback(
318 int thread_id,
319 int request_id,
320 const scoped_refptr<CacheStorageCache>& cache,
321 CacheStorageError error) {
322 if (error != CACHE_STORAGE_OK) {
323 Send(new CacheStorageMsg_CacheStorageOpenError(
324 thread_id, request_id, ToWebServiceWorkerCacheError(error)));
325 return;
327 CacheID cache_id = StoreCacheReference(cache);
328 Send(new CacheStorageMsg_CacheStorageOpenSuccess(thread_id, request_id,
329 cache_id));
332 void CacheStorageDispatcherHost::OnCacheStorageDeleteCallback(
333 int thread_id,
334 int request_id,
335 bool deleted,
336 CacheStorageError error) {
337 if (!deleted || error != CACHE_STORAGE_OK) {
338 Send(new CacheStorageMsg_CacheStorageDeleteError(
339 thread_id, request_id, ToWebServiceWorkerCacheError(error)));
340 return;
342 Send(new CacheStorageMsg_CacheStorageDeleteSuccess(thread_id, request_id));
345 void CacheStorageDispatcherHost::OnCacheStorageKeysCallback(
346 int thread_id,
347 int request_id,
348 const std::vector<std::string>& strings,
349 CacheStorageError error) {
350 if (error != CACHE_STORAGE_OK) {
351 Send(new CacheStorageMsg_CacheStorageKeysError(
352 thread_id, request_id, ToWebServiceWorkerCacheError(error)));
353 return;
356 std::vector<base::string16> string16s;
357 for (size_t i = 0, max = strings.size(); i < max; ++i) {
358 string16s.push_back(base::UTF8ToUTF16(strings[i]));
360 Send(new CacheStorageMsg_CacheStorageKeysSuccess(thread_id, request_id,
361 string16s));
364 void CacheStorageDispatcherHost::OnCacheStorageMatchCallback(
365 int thread_id,
366 int request_id,
367 CacheStorageError error,
368 scoped_ptr<ServiceWorkerResponse> response,
369 scoped_ptr<storage::BlobDataHandle> blob_data_handle) {
370 if (error != CACHE_STORAGE_OK) {
371 Send(new CacheStorageMsg_CacheStorageMatchError(
372 thread_id, request_id, ToWebServiceWorkerCacheError(error)));
373 return;
376 if (blob_data_handle)
377 StoreBlobDataHandle(*blob_data_handle);
379 Send(new CacheStorageMsg_CacheStorageMatchSuccess(thread_id, request_id,
380 *response));
383 void CacheStorageDispatcherHost::OnCacheMatchCallback(
384 int thread_id,
385 int request_id,
386 const scoped_refptr<CacheStorageCache>& cache,
387 CacheStorageError error,
388 scoped_ptr<ServiceWorkerResponse> response,
389 scoped_ptr<storage::BlobDataHandle> blob_data_handle) {
390 if (error != CACHE_STORAGE_OK) {
391 Send(new CacheStorageMsg_CacheMatchError(
392 thread_id, request_id, ToWebServiceWorkerCacheError(error)));
393 return;
396 if (blob_data_handle)
397 StoreBlobDataHandle(*blob_data_handle);
399 Send(new CacheStorageMsg_CacheMatchSuccess(thread_id, request_id, *response));
402 void CacheStorageDispatcherHost::OnCacheMatchAllCallbackAdapter(
403 int thread_id,
404 int request_id,
405 const scoped_refptr<CacheStorageCache>& cache,
406 CacheStorageError error,
407 scoped_ptr<ServiceWorkerResponse> response,
408 scoped_ptr<storage::BlobDataHandle> blob_data_handle) {
409 scoped_ptr<CacheStorageCache::Responses> responses(
410 new CacheStorageCache::Responses);
411 scoped_ptr<CacheStorageCache::BlobDataHandles> blob_data_handles(
412 new CacheStorageCache::BlobDataHandles);
413 if (error == CACHE_STORAGE_OK) {
414 DCHECK(response);
415 responses->push_back(*response);
416 if (blob_data_handle)
417 blob_data_handles->push_back(*blob_data_handle);
419 OnCacheMatchAllCallback(thread_id, request_id, cache, error, responses.Pass(),
420 blob_data_handles.Pass());
423 void CacheStorageDispatcherHost::OnCacheMatchAllCallback(
424 int thread_id,
425 int request_id,
426 const scoped_refptr<CacheStorageCache>& cache,
427 CacheStorageError error,
428 scoped_ptr<CacheStorageCache::Responses> responses,
429 scoped_ptr<CacheStorageCache::BlobDataHandles> blob_data_handles) {
430 if (error != CACHE_STORAGE_OK && error != CACHE_STORAGE_ERROR_NOT_FOUND) {
431 Send(new CacheStorageMsg_CacheMatchAllError(
432 thread_id, request_id, ToWebServiceWorkerCacheError(error)));
433 return;
436 for (const storage::BlobDataHandle& handle : *blob_data_handles)
437 StoreBlobDataHandle(handle);
439 Send(new CacheStorageMsg_CacheMatchAllSuccess(thread_id, request_id,
440 *responses));
443 void CacheStorageDispatcherHost::OnCacheKeysCallback(
444 int thread_id,
445 int request_id,
446 const scoped_refptr<CacheStorageCache>& cache,
447 CacheStorageError error,
448 scoped_ptr<CacheStorageCache::Requests> requests) {
449 if (error != CACHE_STORAGE_OK) {
450 Send(new CacheStorageMsg_CacheKeysError(
451 thread_id, request_id, ToWebServiceWorkerCacheError(error)));
452 return;
455 CacheStorageCache::Requests out;
457 for (CacheStorageCache::Requests::const_iterator it = requests->begin();
458 it != requests->end(); ++it) {
459 ServiceWorkerFetchRequest request(it->url, it->method, it->headers,
460 it->referrer, it->is_reload);
461 out.push_back(request);
464 Send(new CacheStorageMsg_CacheKeysSuccess(thread_id, request_id, out));
467 void CacheStorageDispatcherHost::OnCacheBatchCallback(
468 int thread_id,
469 int request_id,
470 const scoped_refptr<CacheStorageCache>& cache,
471 CacheStorageError error) {
472 if (error != CACHE_STORAGE_OK) {
473 Send(new CacheStorageMsg_CacheBatchError(
474 thread_id, request_id, ToWebServiceWorkerCacheError(error)));
475 return;
478 Send(new CacheStorageMsg_CacheBatchSuccess(thread_id, request_id));
481 CacheStorageDispatcherHost::CacheID
482 CacheStorageDispatcherHost::StoreCacheReference(
483 const scoped_refptr<CacheStorageCache>& cache) {
484 int cache_id = next_cache_id_++;
485 id_to_cache_map_[cache_id] = cache;
486 return cache_id;
489 void CacheStorageDispatcherHost::DropCacheReference(CacheID cache_id) {
490 id_to_cache_map_.erase(cache_id);
493 void CacheStorageDispatcherHost::StoreBlobDataHandle(
494 const storage::BlobDataHandle& blob_data_handle) {
495 std::pair<UUIDToBlobDataHandleList::iterator, bool> rv =
496 blob_handle_store_.insert(std::make_pair(
497 blob_data_handle.uuid(), std::list<storage::BlobDataHandle>()));
498 rv.first->second.push_front(storage::BlobDataHandle(blob_data_handle));
501 void CacheStorageDispatcherHost::DropBlobDataHandle(const std::string& uuid) {
502 UUIDToBlobDataHandleList::iterator it = blob_handle_store_.find(uuid);
503 if (it == blob_handle_store_.end())
504 return;
505 DCHECK(!it->second.empty());
506 it->second.pop_front();
507 if (it->second.empty())
508 blob_handle_store_.erase(it);
511 } // namespace content