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"
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 "storage/browser/blob/blob_data_handle.h"
19 #include "third_party/WebKit/public/platform/WebServiceWorkerCacheError.h"
25 const uint32 kFilteredMessageClasses
[] = {CacheStorageMsgStart
};
27 blink::WebServiceWorkerCacheError
ToWebServiceWorkerCacheError(
28 CacheStorageError err
) {
30 case CACHE_STORAGE_OK
:
32 return blink::WebServiceWorkerCacheErrorNotImplemented
;
33 case CACHE_STORAGE_ERROR_EXISTS
:
34 return blink::WebServiceWorkerCacheErrorExists
;
35 case CACHE_STORAGE_ERROR_STORAGE
:
36 // TODO(nhiroki): Add WebServiceWorkerCacheError equivalent to
37 // CACHE_STORAGE_ERROR_STORAGE.
38 return blink::WebServiceWorkerCacheErrorNotFound
;
39 case CACHE_STORAGE_ERROR_NOT_FOUND
:
40 return blink::WebServiceWorkerCacheErrorNotFound
;
43 return blink::WebServiceWorkerCacheErrorNotImplemented
;
48 CacheStorageDispatcherHost::CacheStorageDispatcherHost()
49 : BrowserMessageFilter(kFilteredMessageClasses
,
50 arraysize(kFilteredMessageClasses
)) {
53 CacheStorageDispatcherHost::~CacheStorageDispatcherHost() {
56 void CacheStorageDispatcherHost::Init(CacheStorageContextImpl
* context
) {
57 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
58 BrowserThread::PostTask(
59 BrowserThread::IO
, FROM_HERE
,
60 base::Bind(&CacheStorageDispatcherHost::CreateCacheListener
, this,
61 make_scoped_refptr(context
)));
64 void CacheStorageDispatcherHost::OnDestruct() const {
65 BrowserThread::DeleteOnIOThread::Destruct(this);
68 bool CacheStorageDispatcherHost::OnMessageReceived(
69 const IPC::Message
& message
) {
70 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
73 IPC_BEGIN_MESSAGE_MAP(CacheStorageDispatcherHost
, message
)
74 IPC_MESSAGE_HANDLER(CacheStorageHostMsg_CacheStorageHas
, OnCacheStorageHas
)
75 IPC_MESSAGE_HANDLER(CacheStorageHostMsg_CacheStorageOpen
, OnCacheStorageOpen
)
76 IPC_MESSAGE_HANDLER(CacheStorageHostMsg_CacheStorageDelete
,
78 IPC_MESSAGE_HANDLER(CacheStorageHostMsg_CacheStorageKeys
, OnCacheStorageKeys
)
79 IPC_MESSAGE_HANDLER(CacheStorageHostMsg_CacheStorageMatch
,
81 IPC_MESSAGE_HANDLER(CacheStorageHostMsg_CacheMatch
, OnCacheMatch
)
82 IPC_MESSAGE_HANDLER(CacheStorageHostMsg_CacheMatchAll
, OnCacheMatchAll
)
83 IPC_MESSAGE_HANDLER(CacheStorageHostMsg_CacheKeys
, OnCacheKeys
)
84 IPC_MESSAGE_HANDLER(CacheStorageHostMsg_CacheBatch
, OnCacheBatch
)
85 IPC_MESSAGE_HANDLER(CacheStorageHostMsg_CacheClosed
, OnCacheClosed
)
86 IPC_MESSAGE_HANDLER(CacheStorageHostMsg_BlobDataHandled
, OnBlobDataHandled
)
87 IPC_MESSAGE_UNHANDLED(handled
= false)
91 bad_message::ReceivedBadMessage(this, bad_message::CSDH_NOT_RECOGNIZED
);
95 void CacheStorageDispatcherHost::CreateCacheListener(
96 CacheStorageContextImpl
* context
) {
97 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
101 void CacheStorageDispatcherHost::OnCacheStorageHas(
105 const base::string16
& cache_name
) {
106 TRACE_EVENT0("CacheStorage", "CacheStorageDispatcherHost::OnCacheStorageHas");
107 context_
->cache_manager()->HasCache(
108 origin
, base::UTF16ToUTF8(cache_name
),
109 base::Bind(&CacheStorageDispatcherHost::OnCacheStorageHasCallback
, this,
110 thread_id
, request_id
));
113 void CacheStorageDispatcherHost::OnCacheStorageOpen(
117 const base::string16
& cache_name
) {
118 TRACE_EVENT0("CacheStorage",
119 "CacheStorageDispatcherHost::OnCacheStorageOpen");
120 context_
->cache_manager()->OpenCache(
121 origin
, base::UTF16ToUTF8(cache_name
),
122 base::Bind(&CacheStorageDispatcherHost::OnCacheStorageOpenCallback
, this,
123 thread_id
, request_id
));
126 void CacheStorageDispatcherHost::OnCacheStorageDelete(
130 const base::string16
& cache_name
) {
131 TRACE_EVENT0("CacheStorage",
132 "CacheStorageDispatcherHost::OnCacheStorageDelete");
133 context_
->cache_manager()->DeleteCache(
134 origin
, base::UTF16ToUTF8(cache_name
),
135 base::Bind(&CacheStorageDispatcherHost::OnCacheStorageDeleteCallback
,
136 this, thread_id
, request_id
));
139 void CacheStorageDispatcherHost::OnCacheStorageKeys(int thread_id
,
141 const GURL
& origin
) {
142 TRACE_EVENT0("CacheStorage",
143 "CacheStorageDispatcherHost::OnCacheStorageKeys");
144 context_
->cache_manager()->EnumerateCaches(
146 base::Bind(&CacheStorageDispatcherHost::OnCacheStorageKeysCallback
, this,
147 thread_id
, request_id
));
150 void CacheStorageDispatcherHost::OnCacheStorageMatch(
154 const ServiceWorkerFetchRequest
& request
,
155 const CacheStorageCacheQueryParams
& match_params
) {
156 TRACE_EVENT0("CacheStorage",
157 "CacheStorageDispatcherHost::OnCacheStorageMatch");
159 scoped_ptr
<ServiceWorkerFetchRequest
> scoped_request(
160 new ServiceWorkerFetchRequest(request
.url
, request
.method
,
161 request
.headers
, request
.referrer
,
164 if (match_params
.cache_name
.empty()) {
165 context_
->cache_manager()->MatchAllCaches(
166 origin
, scoped_request
.Pass(),
167 base::Bind(&CacheStorageDispatcherHost::OnCacheStorageMatchCallback
,
168 this, thread_id
, request_id
));
171 context_
->cache_manager()->MatchCache(
172 origin
, base::UTF16ToUTF8(match_params
.cache_name
), scoped_request
.Pass(),
173 base::Bind(&CacheStorageDispatcherHost::OnCacheStorageMatchCallback
, this,
174 thread_id
, request_id
));
177 void CacheStorageDispatcherHost::OnCacheMatch(
181 const ServiceWorkerFetchRequest
& request
,
182 const CacheStorageCacheQueryParams
& match_params
) {
183 IDToCacheMap::iterator it
= id_to_cache_map_
.find(cache_id
);
184 if (it
== id_to_cache_map_
.end()) {
185 Send(new CacheStorageMsg_CacheMatchError(
186 thread_id
, request_id
, blink::WebServiceWorkerCacheErrorNotFound
));
190 scoped_refptr
<CacheStorageCache
> cache
= it
->second
;
191 scoped_ptr
<ServiceWorkerFetchRequest
> scoped_request(
192 new ServiceWorkerFetchRequest(request
.url
, request
.method
,
193 request
.headers
, request
.referrer
,
195 cache
->Match(scoped_request
.Pass(),
196 base::Bind(&CacheStorageDispatcherHost::OnCacheMatchCallback
,
197 this, thread_id
, request_id
, cache
));
200 void CacheStorageDispatcherHost::OnCacheMatchAll(
204 const ServiceWorkerFetchRequest
& request
,
205 const CacheStorageCacheQueryParams
& match_params
) {
206 // TODO(gavinp,jkarlin): Implement this method.
207 Send(new CacheStorageMsg_CacheMatchAllError(
208 thread_id
, request_id
, blink::WebServiceWorkerCacheErrorNotImplemented
));
211 void CacheStorageDispatcherHost::OnCacheKeys(
215 const ServiceWorkerFetchRequest
& request
,
216 const CacheStorageCacheQueryParams
& match_params
) {
217 IDToCacheMap::iterator it
= id_to_cache_map_
.find(cache_id
);
218 if (it
== id_to_cache_map_
.end()) {
219 Send(new CacheStorageMsg_CacheKeysError(
220 thread_id
, request_id
, blink::WebServiceWorkerCacheErrorNotFound
));
224 scoped_refptr
<CacheStorageCache
> cache
= it
->second
;
226 cache
->Keys(base::Bind(&CacheStorageDispatcherHost::OnCacheKeysCallback
, this,
227 thread_id
, request_id
, cache
));
230 void CacheStorageDispatcherHost::OnCacheBatch(
234 const std::vector
<CacheStorageBatchOperation
>& operations
) {
235 IDToCacheMap::iterator it
= id_to_cache_map_
.find(cache_id
);
236 if (it
== id_to_cache_map_
.end()) {
237 Send(new CacheStorageMsg_CacheBatchError(
238 thread_id
, request_id
, blink::WebServiceWorkerCacheErrorNotFound
));
241 scoped_refptr
<CacheStorageCache
> cache
= it
->second
;
242 cache
->BatchOperation(
243 operations
, base::Bind(&CacheStorageDispatcherHost::OnCacheBatchCallback
,
244 this, thread_id
, request_id
, cache
));
247 void CacheStorageDispatcherHost::OnCacheClosed(int cache_id
) {
248 DropCacheReference(cache_id
);
251 void CacheStorageDispatcherHost::OnBlobDataHandled(const std::string
& uuid
) {
252 DropBlobDataHandle(uuid
);
255 void CacheStorageDispatcherHost::OnCacheStorageHasCallback(
259 CacheStorageError error
) {
260 if (error
!= CACHE_STORAGE_OK
) {
261 Send(new CacheStorageMsg_CacheStorageHasError(
262 thread_id
, request_id
, ToWebServiceWorkerCacheError(error
)));
266 Send(new CacheStorageMsg_CacheStorageHasError(
267 thread_id
, request_id
, blink::WebServiceWorkerCacheErrorNotFound
));
270 Send(new CacheStorageMsg_CacheStorageHasSuccess(thread_id
, request_id
));
273 void CacheStorageDispatcherHost::OnCacheStorageOpenCallback(
276 const scoped_refptr
<CacheStorageCache
>& cache
,
277 CacheStorageError error
) {
278 if (error
!= CACHE_STORAGE_OK
) {
279 Send(new CacheStorageMsg_CacheStorageOpenError(
280 thread_id
, request_id
, ToWebServiceWorkerCacheError(error
)));
283 CacheID cache_id
= StoreCacheReference(cache
);
284 Send(new CacheStorageMsg_CacheStorageOpenSuccess(thread_id
, request_id
,
288 void CacheStorageDispatcherHost::OnCacheStorageDeleteCallback(
292 CacheStorageError error
) {
293 if (!deleted
|| error
!= CACHE_STORAGE_OK
) {
294 Send(new CacheStorageMsg_CacheStorageDeleteError(
295 thread_id
, request_id
, ToWebServiceWorkerCacheError(error
)));
298 Send(new CacheStorageMsg_CacheStorageDeleteSuccess(thread_id
, request_id
));
301 void CacheStorageDispatcherHost::OnCacheStorageKeysCallback(
304 const std::vector
<std::string
>& strings
,
305 CacheStorageError error
) {
306 if (error
!= CACHE_STORAGE_OK
) {
307 Send(new CacheStorageMsg_CacheStorageKeysError(
308 thread_id
, request_id
, ToWebServiceWorkerCacheError(error
)));
312 std::vector
<base::string16
> string16s
;
313 for (size_t i
= 0, max
= strings
.size(); i
< max
; ++i
) {
314 string16s
.push_back(base::UTF8ToUTF16(strings
[i
]));
316 Send(new CacheStorageMsg_CacheStorageKeysSuccess(thread_id
, request_id
,
320 void CacheStorageDispatcherHost::OnCacheStorageMatchCallback(
323 CacheStorageError error
,
324 scoped_ptr
<ServiceWorkerResponse
> response
,
325 scoped_ptr
<storage::BlobDataHandle
> blob_data_handle
) {
326 if (error
!= CACHE_STORAGE_OK
) {
327 Send(new CacheStorageMsg_CacheStorageMatchError(
328 thread_id
, request_id
, ToWebServiceWorkerCacheError(error
)));
332 if (blob_data_handle
)
333 StoreBlobDataHandle(blob_data_handle
.Pass());
335 Send(new CacheStorageMsg_CacheStorageMatchSuccess(thread_id
, request_id
,
339 void CacheStorageDispatcherHost::OnCacheMatchCallback(
342 const scoped_refptr
<CacheStorageCache
>& cache
,
343 CacheStorageError error
,
344 scoped_ptr
<ServiceWorkerResponse
> response
,
345 scoped_ptr
<storage::BlobDataHandle
> blob_data_handle
) {
346 if (error
!= CACHE_STORAGE_OK
) {
347 Send(new CacheStorageMsg_CacheMatchError(
348 thread_id
, request_id
, ToWebServiceWorkerCacheError(error
)));
352 if (blob_data_handle
)
353 StoreBlobDataHandle(blob_data_handle
.Pass());
355 Send(new CacheStorageMsg_CacheMatchSuccess(thread_id
, request_id
, *response
));
358 void CacheStorageDispatcherHost::OnCacheKeysCallback(
361 const scoped_refptr
<CacheStorageCache
>& cache
,
362 CacheStorageError error
,
363 scoped_ptr
<CacheStorageCache::Requests
> requests
) {
364 if (error
!= CACHE_STORAGE_OK
) {
365 Send(new CacheStorageMsg_CacheKeysError(
366 thread_id
, request_id
, ToWebServiceWorkerCacheError(error
)));
370 CacheStorageCache::Requests out
;
372 for (CacheStorageCache::Requests::const_iterator it
= requests
->begin();
373 it
!= requests
->end(); ++it
) {
374 ServiceWorkerFetchRequest
request(it
->url
, it
->method
, it
->headers
,
375 it
->referrer
, it
->is_reload
);
376 out
.push_back(request
);
379 Send(new CacheStorageMsg_CacheKeysSuccess(thread_id
, request_id
, out
));
382 void CacheStorageDispatcherHost::OnCacheBatchCallback(
385 const scoped_refptr
<CacheStorageCache
>& cache
,
386 CacheStorageError error
) {
387 if (error
!= CACHE_STORAGE_OK
) {
388 Send(new CacheStorageMsg_CacheBatchError(
389 thread_id
, request_id
, ToWebServiceWorkerCacheError(error
)));
393 Send(new CacheStorageMsg_CacheBatchSuccess(thread_id
, request_id
));
396 CacheStorageDispatcherHost::CacheID
397 CacheStorageDispatcherHost::StoreCacheReference(
398 const scoped_refptr
<CacheStorageCache
>& cache
) {
399 int cache_id
= next_cache_id_
++;
400 id_to_cache_map_
[cache_id
] = cache
;
404 void CacheStorageDispatcherHost::DropCacheReference(CacheID cache_id
) {
405 id_to_cache_map_
.erase(cache_id
);
408 void CacheStorageDispatcherHost::StoreBlobDataHandle(
409 scoped_ptr
<storage::BlobDataHandle
> blob_data_handle
) {
410 DCHECK(blob_data_handle
);
411 std::pair
<UUIDToBlobDataHandleList::iterator
, bool> rv
=
412 blob_handle_store_
.insert(std::make_pair(
413 blob_data_handle
->uuid(), std::list
<storage::BlobDataHandle
>()));
414 rv
.first
->second
.push_front(storage::BlobDataHandle(*blob_data_handle
));
417 void CacheStorageDispatcherHost::DropBlobDataHandle(std::string uuid
) {
418 UUIDToBlobDataHandleList::iterator it
= blob_handle_store_
.find(uuid
);
419 if (it
== blob_handle_store_
.end())
421 DCHECK(!it
->second
.empty());
422 it
->second
.pop_front();
423 if (it
->second
.empty())
424 blob_handle_store_
.erase(it
);
427 } // namespace content