Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(48)

Side by Side Diff: content/browser/service_worker/service_worker_cache.cc

Issue 465463002: Initial implementation of ServiceWorkerCache. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@cache2
Patch Set: Default backend Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 "content/browser/service_worker/service_worker_cache.h" 5 #include "content/browser/service_worker/service_worker_cache.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/files/file_path.h" 9 #include "base/files/file_path.h"
10 #include "base/guid.h"
11 #include "base/message_loop/message_loop_proxy.h"
12 #include "content/browser/service_worker/service_worker_cache.pb.h"
13 #include "content/public/browser/browser_thread.h"
14 #include "net/base/io_buffer.h"
15 #include "net/base/net_errors.h"
16 #include "net/disk_cache/disk_cache.h"
10 #include "net/url_request/url_request_context.h" 17 #include "net/url_request/url_request_context.h"
18 #include "webkit/browser/blob/blob_data_handle.h"
11 #include "webkit/browser/blob/blob_storage_context.h" 19 #include "webkit/browser/blob/blob_storage_context.h"
20 #include "webkit/browser/blob/blob_url_request_job_factory.h"
12 21
13 namespace content { 22 namespace content {
14 23
24 namespace {
25
26 typedef scoped_ptr<disk_cache::Backend> ScopedBackendPtr;
27 typedef base::Callback<void(bool)> BoolCallback;
28 typedef base::Callback<void(disk_cache::ScopedEntryPtr, bool)>
29 EntryBoolCallback;
30 enum EntryIndex { INDEX_HEADERS = 0, INDEX_RESPONSE_BODY };
31
32 // The maximum size of an individual cache. Ultimately cache size is controlled
33 // per-origin.
34 const int kMaxCacheBytes = 512 * 1024 * 1024;
35
36 // Buffer size for cache and blob reading/writing.
37 const int kBufferSize = 1024 * 512;
38
39 struct ResponseReadContext {
40 ResponseReadContext(scoped_refptr<net::IOBufferWithSize> buff,
41 scoped_refptr<storage::BlobData> blob)
42 : buffer(buff), blob_data(blob), total_bytes_read(0) {}
43
44 scoped_refptr<net::IOBufferWithSize> buffer;
45 scoped_refptr<storage::BlobData> blob_data;
46 int total_bytes_read;
47
48 DISALLOW_COPY_AND_ASSIGN(ResponseReadContext);
49 };
50
51 // Streams data from a blob and writes it to a given disk_cache::Entry.
52 class BlobReader : public net::URLRequest::Delegate {
53 public:
54 typedef base::Callback<void(disk_cache::ScopedEntryPtr, bool)>
55 EntryBoolCallback;
56
57 BlobReader(disk_cache::ScopedEntryPtr entry)
58 : cache_entry_offset_(0),
59 buffer_(new net::IOBufferWithSize(kBufferSize)),
60 weak_ptr_factory_(this) {
61 DCHECK(entry);
62 entry_ = entry.Pass();
63 }
64
65 void StreamBlobToCache(net::URLRequestContext* request_context,
66 scoped_ptr<storage::BlobDataHandle> blob_data_handle,
67 const EntryBoolCallback& callback) {
68 callback_ = callback;
69 blob_request_ = storage::BlobProtocolHandler::CreateBlobRequest(
70 blob_data_handle.Pass(), request_context, this);
71 blob_request_->Start();
72 }
73
74 // net::URLRequest::Delegate overrides for reading blobs.
75 virtual void OnReceivedRedirect(net::URLRequest* request,
76 const net::RedirectInfo& redirect_info,
77 bool* defer_redirect) OVERRIDE {
78 NOTREACHED();
79 }
80 virtual void OnAuthRequired(net::URLRequest* request,
81 net::AuthChallengeInfo* auth_info) OVERRIDE {
82 NOTREACHED();
83 }
84 virtual void OnCertificateRequested(
85 net::URLRequest* request,
86 net::SSLCertRequestInfo* cert_request_info) OVERRIDE {
87 NOTREACHED();
88 }
89 virtual void OnSSLCertificateError(net::URLRequest* request,
90 const net::SSLInfo& ssl_info,
91 bool fatal) OVERRIDE {
92 NOTREACHED();
93 }
94 virtual void OnBeforeNetworkStart(net::URLRequest* request,
95 bool* defer) OVERRIDE {
96 NOTREACHED();
97 }
98
99 virtual void OnResponseStarted(net::URLRequest* request) OVERRIDE {
100 if (!request->status().is_success()) {
101 callback_.Run(entry_.Pass(), false);
102 return;
103 }
104 ReadFromBlob();
105 }
106
107 virtual void ReadFromBlob() {
108 int bytes_read = 0;
109 bool done =
110 blob_request_->Read(buffer_.get(), buffer_->size(), &bytes_read);
111 if (done)
112 OnReadCompleted(blob_request_.get(), bytes_read);
113 }
114
115 virtual void OnReadCompleted(net::URLRequest* request,
116 int bytes_read) OVERRIDE {
117 if (!request->status().is_success()) {
118 callback_.Run(entry_.Pass(), false);
119 return;
120 }
121
122 if (bytes_read == 0) {
123 callback_.Run(entry_.Pass(), true);
124 return;
125 }
126
127 net::CompletionCallback cache_write_callback =
128 base::Bind(&BlobReader::DidWriteDataToEntry,
129 weak_ptr_factory_.GetWeakPtr(),
130 bytes_read);
131
132 int rv = entry_->WriteData(INDEX_RESPONSE_BODY,
133 cache_entry_offset_,
134 buffer_,
135 bytes_read,
136 cache_write_callback,
137 true /* truncate */);
138 if (rv != net::ERR_IO_PENDING)
139 cache_write_callback.Run(rv);
140 }
141
142 void DidWriteDataToEntry(int expected_bytes, int rv) {
143 if (rv != expected_bytes) {
144 callback_.Run(entry_.Pass(), false);
145 return;
146 }
147
148 cache_entry_offset_ += rv;
149 ReadFromBlob();
150 }
151
152 private:
153 int cache_entry_offset_;
154 disk_cache::ScopedEntryPtr entry_;
155 scoped_ptr<net::URLRequest> blob_request_;
156 EntryBoolCallback callback_;
157 scoped_refptr<net::IOBufferWithSize> buffer_;
158 base::WeakPtrFactory<BlobReader> weak_ptr_factory_;
159 };
160
161 // Put callbacks
162 void PutDidCreateEntry(ServiceWorkerFetchRequest* request,
163 ServiceWorkerResponse* response,
164 const ServiceWorkerCache::ErrorCallback& callback,
165 scoped_ptr<disk_cache::Entry*> entryptr,
166 scoped_ptr<storage::BlobDataHandle> blob_data_handle,
167 net::URLRequestContext* request_context,
168 int rv);
169 void PutDidWriteHeaders(ServiceWorkerResponse* response,
170 const ServiceWorkerCache::ErrorCallback& callback,
171 disk_cache::ScopedEntryPtr entry,
172 scoped_ptr<storage::BlobDataHandle> blob_data_handle,
173 net::URLRequestContext* request_context,
174 int expected_bytes,
175 int rv);
176 void PutDidWriteBlobToCache(const ServiceWorkerCache::ErrorCallback& callback,
177 scoped_ptr<BlobReader> blob_reader,
178 disk_cache::ScopedEntryPtr entry,
179 bool success);
180
181 // Match callbacks
182 void MatchDidOpenEntry(ServiceWorkerFetchRequest* request,
183 const ServiceWorkerCache::ResponseCallback& callback,
184 base::WeakPtr<storage::BlobStorageContext> blob_storage,
185 scoped_ptr<disk_cache::Entry*> entryptr,
186 int rv);
187 void MatchDidReadHeaderData(
188 ServiceWorkerFetchRequest* request,
189 const ServiceWorkerCache::ResponseCallback& callback,
190 base::WeakPtr<storage::BlobStorageContext> blob_storage,
191 disk_cache::ScopedEntryPtr entry,
192 const scoped_refptr<net::IOBufferWithSize>& buffer,
193 int rv);
194 void MatchDidReadResponseBodyData(
195 ServiceWorkerFetchRequest* request,
196 const ServiceWorkerCache::ResponseCallback& callback,
197 base::WeakPtr<storage::BlobStorageContext> blob_storage,
198 disk_cache::ScopedEntryPtr entry,
199 scoped_ptr<ServiceWorkerResponse> response,
200 scoped_ptr<ResponseReadContext> response_context,
201 int rv);
202 void MatchDoneWithBody(ServiceWorkerFetchRequest* request,
203 const ServiceWorkerCache::ResponseCallback& callback,
204 base::WeakPtr<storage::BlobStorageContext> blob_storage,
205 scoped_ptr<ServiceWorkerResponse> response,
206 scoped_ptr<ResponseReadContext> response_context);
207
208 // Delete callbacks
209 void DeleteDidOpenEntry(ServiceWorkerFetchRequest* request,
210 const ServiceWorkerCache::ErrorCallback& callback,
211 scoped_ptr<disk_cache::Entry*> entryptr,
212 int rv);
213
214 // CreateBackend callbacks
215 void CreateBackendDidCreate(const ServiceWorkerCache::ErrorCallback& callback,
216 scoped_ptr<ScopedBackendPtr> backend_ptr,
217 base::WeakPtr<ServiceWorkerCache> cache,
218 int rv);
219
220 void PutDidCreateEntry(ServiceWorkerFetchRequest* request,
221 ServiceWorkerResponse* response,
222 const ServiceWorkerCache::ErrorCallback& callback,
223 scoped_ptr<disk_cache::Entry*> entryptr,
224 scoped_ptr<storage::BlobDataHandle> blob_data_handle,
225 net::URLRequestContext* request_context,
226 int rv) {
227 if (rv != net::OK) {
228 callback.Run(ServiceWorkerCache::ErrorTypeExists);
229 return;
230 }
231
232 DCHECK(entryptr);
233 disk_cache::ScopedEntryPtr entry(*entryptr);
234
235 ServiceWorkerRequestResponseHeaders headers;
236 headers.set_method(request->method);
237
238 headers.set_status_code(response->status_code);
239 headers.set_status_text(response->status_text);
240 for (std::map<std::string, std::string>::const_iterator it =
241 request->headers.begin();
242 it != request->headers.end();
243 ++it) {
244 ServiceWorkerRequestResponseHeaders::HeaderMap* header_map =
245 headers.add_request_headers();
246 header_map->set_name(it->first);
247 header_map->set_value(it->second);
248 }
249
250 for (std::map<std::string, std::string>::const_iterator it =
251 response->headers.begin();
252 it != response->headers.end();
253 ++it) {
254 ServiceWorkerRequestResponseHeaders::HeaderMap* header_map =
255 headers.add_response_headers();
256 header_map->set_name(it->first);
257 header_map->set_value(it->second);
258 }
259
260 scoped_ptr<std::string> serialized(new std::string());
261 if (!headers.SerializeToString(serialized.get())) {
262 callback.Run(ServiceWorkerCache::ErrorTypeStorage);
263 return;
264 }
265
266 scoped_refptr<net::StringIOBuffer> buffer(
267 new net::StringIOBuffer(serialized.Pass()));
268
269 // Get a temporary copy of the entry pointer before passing it in base::Bind.
270 disk_cache::Entry* tmp_entry_ptr = entry.get();
271
272 net::CompletionCallback write_headers_callback =
273 base::Bind(PutDidWriteHeaders,
274 response,
275 callback,
276 base::Passed(entry.Pass()),
277 base::Passed(blob_data_handle.Pass()),
278 request_context,
279 buffer->size());
280
281 rv = tmp_entry_ptr->WriteData(INDEX_HEADERS,
282 0 /* offset */,
283 buffer,
284 buffer->size(),
285 write_headers_callback,
286 true /* truncate */);
287
288 if (rv != net::ERR_IO_PENDING)
289 write_headers_callback.Run(rv);
290 }
291
292 void PutDidWriteHeaders(ServiceWorkerResponse* response,
293 const ServiceWorkerCache::ErrorCallback& callback,
294 disk_cache::ScopedEntryPtr entry,
295 scoped_ptr<storage::BlobDataHandle> blob_data_handle,
296 net::URLRequestContext* request_context,
297 int expected_bytes,
298 int rv) {
299 if (rv != expected_bytes) {
300 entry->Doom();
301 callback.Run(ServiceWorkerCache::ErrorTypeStorage);
302 return;
303 }
304
305 // The metadata is written, now for the response content. The data is streamed
306 // from the blob into the cache entry.
307
308 if (response->blob_uuid.empty()) {
309 callback.Run(ServiceWorkerCache::ErrorTypeOK);
310 return;
311 }
312
313 DCHECK(blob_data_handle);
314
315 scoped_ptr<BlobReader> reader(new BlobReader(entry.Pass()));
316 BlobReader* reader_ptr = reader.get();
317
318 reader_ptr->StreamBlobToCache(
319 request_context,
320 blob_data_handle.Pass(),
321 base::Bind(
322 PutDidWriteBlobToCache, callback, base::Passed(reader.Pass())));
323 }
324
325 void PutDidWriteBlobToCache(const ServiceWorkerCache::ErrorCallback& callback,
326 scoped_ptr<BlobReader> blob_reader,
327 disk_cache::ScopedEntryPtr entry,
328 bool success) {
329 if (!success) {
330 entry->Doom();
331 callback.Run(ServiceWorkerCache::ErrorTypeStorage);
332 return;
333 }
334
335 callback.Run(ServiceWorkerCache::ErrorTypeOK);
336 }
337
338 void MatchDidOpenEntry(ServiceWorkerFetchRequest* request,
339 const ServiceWorkerCache::ResponseCallback& callback,
340 base::WeakPtr<storage::BlobStorageContext> blob_storage,
341 scoped_ptr<disk_cache::Entry*> entryptr,
342 int rv) {
343 if (rv != net::OK) {
344 callback.Run(ServiceWorkerCache::ErrorTypeNotFound,
345 scoped_ptr<ServiceWorkerResponse>(),
346 scoped_ptr<storage::BlobDataHandle>());
347 return;
348 }
349
350 DCHECK(entryptr);
351 disk_cache::ScopedEntryPtr entry(*entryptr);
352
353 scoped_refptr<net::IOBufferWithSize> buffer(
354 new net::IOBufferWithSize(entry->GetDataSize(INDEX_HEADERS)));
355
356 // Copy the entry pointer before passing it in base::Bind.
357 disk_cache::Entry* tmp_entry_ptr = entry.get();
358
359 net::CompletionCallback read_header_callback =
360 base::Bind(MatchDidReadHeaderData,
361 request,
362 callback,
363 blob_storage,
364 base::Passed(entry.Pass()),
365 buffer);
366
367 int read_rv = tmp_entry_ptr->ReadData(
368 INDEX_HEADERS, 0, buffer.get(), buffer->size(), read_header_callback);
369
370 if (read_rv != net::ERR_IO_PENDING)
371 read_header_callback.Run(read_rv);
372 }
373
374 void MatchDidReadHeaderData(
375 ServiceWorkerFetchRequest* request,
376 const ServiceWorkerCache::ResponseCallback& callback,
377 base::WeakPtr<storage::BlobStorageContext> blob_storage,
378 disk_cache::ScopedEntryPtr entry,
379 const scoped_refptr<net::IOBufferWithSize>& buffer,
380 int rv) {
381 if (rv != buffer->size()) {
382 callback.Run(ServiceWorkerCache::ErrorTypeStorage,
383 scoped_ptr<ServiceWorkerResponse>(),
384 scoped_ptr<storage::BlobDataHandle>());
385
386 return;
387 }
388
389 ServiceWorkerRequestResponseHeaders headers;
390
391 if (!headers.ParseFromArray(buffer->data(), buffer->size())) {
392 callback.Run(ServiceWorkerCache::ErrorTypeStorage,
393 scoped_ptr<ServiceWorkerResponse>(),
394 scoped_ptr<storage::BlobDataHandle>());
395
396 return;
397 }
398
399 scoped_ptr<ServiceWorkerResponse> response(
400 new ServiceWorkerResponse(request->url,
401 headers.status_code(),
402 headers.status_text(),
403 std::map<std::string, std::string>(),
404 ""));
405
406 for (int i = 0; i < headers.response_headers_size(); ++i) {
407 const ServiceWorkerRequestResponseHeaders::HeaderMap header =
408 headers.response_headers(i);
409 response->headers.insert(std::make_pair(header.name(), header.value()));
410 }
411
412 // TODO(jkarlin): Insert vary validation here.
413
414 if (entry->GetDataSize(INDEX_RESPONSE_BODY) == 0) {
415 callback.Run(ServiceWorkerCache::ErrorTypeOK,
416 response.Pass(),
417 scoped_ptr<storage::BlobDataHandle>());
418 return;
419 }
420
421 // Stream the response body into a blob.
422 if (!blob_storage) {
423 callback.Run(ServiceWorkerCache::ErrorTypeStorage,
424 scoped_ptr<ServiceWorkerResponse>(),
425 scoped_ptr<storage::BlobDataHandle>());
426
427 return;
428 }
429
430 response->blob_uuid = base::GenerateGUID();
431
432 scoped_refptr<storage::BlobData> blob_data =
433 new storage::BlobData(response->blob_uuid);
434 scoped_refptr<net::IOBufferWithSize> response_body_buffer(
435 new net::IOBufferWithSize(kBufferSize));
436
437 scoped_ptr<ResponseReadContext> read_context(
438 new ResponseReadContext(response_body_buffer, blob_data));
439
440 // Copy the entry pointer before passing it in base::Bind.
441 disk_cache::Entry* tmp_entry_ptr = entry.get();
442
443 net::CompletionCallback read_callback =
444 base::Bind(MatchDidReadResponseBodyData,
445 request,
446 callback,
447 blob_storage,
448 base::Passed(entry.Pass()),
449 base::Passed(response.Pass()),
450 base::Passed(read_context.Pass()));
451
452 int read_rv = tmp_entry_ptr->ReadData(INDEX_RESPONSE_BODY,
453 0,
454 response_body_buffer.get(),
455 response_body_buffer->size(),
456 read_callback);
457
458 if (read_rv != net::ERR_IO_PENDING)
459 read_callback.Run(read_rv);
460 }
461
462 void MatchDidReadResponseBodyData(
463 ServiceWorkerFetchRequest* request,
464 const ServiceWorkerCache::ResponseCallback& callback,
465 base::WeakPtr<storage::BlobStorageContext> blob_storage,
466 disk_cache::ScopedEntryPtr entry,
467 scoped_ptr<ServiceWorkerResponse> response,
468 scoped_ptr<ResponseReadContext> response_context,
469 int rv) {
470 if (rv < 0) {
471 callback.Run(ServiceWorkerCache::ErrorTypeStorage,
472 scoped_ptr<ServiceWorkerResponse>(),
473 scoped_ptr<storage::BlobDataHandle>());
474 return;
475 }
476
477 if (rv == 0) {
478 MatchDoneWithBody(request,
479 callback,
480 blob_storage,
481 response.Pass(),
482 response_context.Pass());
483 return;
484 }
485
486 // TODO(jkarlin): This copying of the the entire cache response into memory is
487 // awful. Create a new interface around SimpleCache that provides access the
488 // data directly from the file. See bug http://crbug.com/403493.
489 response_context->blob_data->AppendData(response_context->buffer->data(), rv);
490 response_context->total_bytes_read += rv;
491 int total_bytes_read = response_context->total_bytes_read;
492
493 // Grab some pointers before passing them in bind.
494 net::IOBufferWithSize* buffer = response_context->buffer;
495 disk_cache::Entry* tmp_entry_ptr = entry.get();
496
497 net::CompletionCallback read_callback =
498 base::Bind(MatchDidReadResponseBodyData,
499 request,
500 callback,
501 blob_storage,
502 base::Passed(entry.Pass()),
503 base::Passed(response.Pass()),
504 base::Passed(response_context.Pass()));
505
506 int read_rv = tmp_entry_ptr->ReadData(INDEX_RESPONSE_BODY,
507 total_bytes_read,
508 buffer,
509 buffer->size(),
510 read_callback);
511
512 if (read_rv != net::ERR_IO_PENDING)
513 read_callback.Run(read_rv);
514 }
515
516 void MatchDoneWithBody(ServiceWorkerFetchRequest* request,
517 const ServiceWorkerCache::ResponseCallback& callback,
518 base::WeakPtr<storage::BlobStorageContext> blob_storage,
519 scoped_ptr<ServiceWorkerResponse> response,
520 scoped_ptr<ResponseReadContext> response_context) {
521 if (!blob_storage) {
522 callback.Run(ServiceWorkerCache::ErrorTypeStorage,
523 scoped_ptr<ServiceWorkerResponse>(),
524 scoped_ptr<storage::BlobDataHandle>());
525 return;
526 }
527
528 scoped_ptr<storage::BlobDataHandle> blob_data_handle(
529 blob_storage->AddFinishedBlob(response_context->blob_data.get()));
530
531 callback.Run(ServiceWorkerCache::ErrorTypeOK,
532 response.Pass(),
533 blob_data_handle.Pass());
534 }
535
536 void DeleteDidOpenEntry(ServiceWorkerFetchRequest* request,
537 const ServiceWorkerCache::ErrorCallback& callback,
538 scoped_ptr<disk_cache::Entry*> entryptr,
539 int rv) {
540 if (rv != net::OK) {
541 callback.Run(ServiceWorkerCache::ErrorTypeNotFound);
542 return;
543 }
544
545 DCHECK(entryptr);
546 disk_cache::ScopedEntryPtr entry(*entryptr);
547
548 entry->Doom();
549 callback.Run(ServiceWorkerCache::ErrorTypeOK);
550 }
551
552 void CreateBackendDidCreate(const ServiceWorkerCache::ErrorCallback& callback,
553 scoped_ptr<ScopedBackendPtr> backend_ptr,
554 base::WeakPtr<ServiceWorkerCache> cache,
555 int rv) {
556 if (rv != net::OK || !cache) {
557 callback.Run(ServiceWorkerCache::ErrorTypeStorage);
558 return;
559 }
560 cache->set_backend(backend_ptr->Pass());
561 callback.Run(ServiceWorkerCache::ErrorTypeOK);
562 }
563
564 } // namespace
565
15 // static 566 // static
16 scoped_ptr<ServiceWorkerCache> ServiceWorkerCache::CreateMemoryCache( 567 scoped_ptr<ServiceWorkerCache> ServiceWorkerCache::CreateMemoryCache(
17 const std::string& name, 568 const std::string& name,
18 net::URLRequestContext* request_context, 569 net::URLRequestContext* request_context,
19 base::WeakPtr<storage::BlobStorageContext> blob_context) { 570 base::WeakPtr<storage::BlobStorageContext> blob_context) {
20 return make_scoped_ptr(new ServiceWorkerCache( 571 return make_scoped_ptr(new ServiceWorkerCache(
21 base::FilePath(), name, request_context, blob_context)); 572 base::FilePath(), name, request_context, blob_context));
22 } 573 }
23 574
24 // static 575 // static
25 scoped_ptr<ServiceWorkerCache> ServiceWorkerCache::CreatePersistentCache( 576 scoped_ptr<ServiceWorkerCache> ServiceWorkerCache::CreatePersistentCache(
26 const base::FilePath& path, 577 const base::FilePath& path,
27 const std::string& name, 578 const std::string& name,
28 net::URLRequestContext* request_context, 579 net::URLRequestContext* request_context,
29 base::WeakPtr<storage::BlobStorageContext> blob_context) { 580 base::WeakPtr<storage::BlobStorageContext> blob_context) {
30 return make_scoped_ptr( 581 return make_scoped_ptr(
31 new ServiceWorkerCache(path, name, request_context, blob_context)); 582 new ServiceWorkerCache(path, name, request_context, blob_context));
32 } 583 }
33 584
34 void ServiceWorkerCache::CreateBackend( 585 ServiceWorkerCache::~ServiceWorkerCache() {
35 const base::Callback<void(bool)>& callback) {
36 callback.Run(true);
37 } 586 }
38 587
39 base::WeakPtr<ServiceWorkerCache> ServiceWorkerCache::AsWeakPtr() { 588 base::WeakPtr<ServiceWorkerCache> ServiceWorkerCache::AsWeakPtr() {
40 return weak_ptr_factory_.GetWeakPtr(); 589 return weak_ptr_factory_.GetWeakPtr();
41 } 590 }
42 591
592 void ServiceWorkerCache::CreateBackend(const ErrorCallback& callback) {
593 DCHECK(!backend_);
594
595 // Use APP_CACHE as opposed to DISK_CACHE to prevent cache eviction.
596 net::CacheType cache_type =
597 path_.empty() ? net::MEMORY_CACHE : net::APP_CACHE;
598
599 scoped_ptr<ScopedBackendPtr> backend_ptr(new ScopedBackendPtr());
600
601 // Temporary pointer so that backend_ptr can be Pass()'d in Bind below.
602 ScopedBackendPtr* backend = backend_ptr.get();
603
604 net::CompletionCallback create_cache_callback =
605 base::Bind(CreateBackendDidCreate,
606 callback,
607 base::Passed(backend_ptr.Pass()),
608 weak_ptr_factory_.GetWeakPtr());
609
610 // TODO(jkarlin): Use the cache MessageLoopProxy that ServiceWorkerCacheCore
611 // has for disk caches.
612 // TODO(jkarlin): Switch to SimpleCache after it supports APP_CACHE and after
613 // debugging why the QuickStressBody unittest fails with it.
614 int rv = disk_cache::CreateCacheBackend(
615 cache_type,
616 net::CACHE_BACKEND_DEFAULT,
617 path_,
618 kMaxCacheBytes,
619 false, /* force */
620 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE).get(),
621 NULL,
622 backend,
623 create_cache_callback);
624 if (rv != net::ERR_IO_PENDING)
625 create_cache_callback.Run(rv);
626 }
627
628 void ServiceWorkerCache::Put(ServiceWorkerFetchRequest* request,
629 ServiceWorkerResponse* response,
630 const ErrorCallback& callback) {
631 DCHECK(backend_);
632
633 scoped_ptr<disk_cache::Entry*> entry(new disk_cache::Entry*);
634
635 disk_cache::Entry** entry_ptr = entry.get();
636
637 scoped_ptr<storage::BlobDataHandle> blob_data_handle;
638
639 if (!response->blob_uuid.empty()) {
640 if (!blob_storage_context_) {
641 callback.Run(ErrorTypeStorage);
642 return;
643 }
644 blob_data_handle =
645 blob_storage_context_->GetBlobDataFromUUID(response->blob_uuid);
646 if (!blob_data_handle) {
647 callback.Run(ErrorTypeStorage);
648 return;
649 }
650 }
651
652 net::CompletionCallback create_entry_callback =
653 base::Bind(PutDidCreateEntry,
654 request,
655 response,
656 callback,
657 base::Passed(entry.Pass()),
658 base::Passed(blob_data_handle.Pass()),
659 request_context_);
660
661 int rv = backend_->CreateEntry(
662 request->url.spec(), entry_ptr, create_entry_callback);
663
664 if (rv != net::ERR_IO_PENDING)
665 create_entry_callback.Run(rv);
666 }
667
668 void ServiceWorkerCache::Match(ServiceWorkerFetchRequest* request,
669 const ResponseCallback& callback) {
670 DCHECK(backend_);
671
672 scoped_ptr<disk_cache::Entry*> entry(new disk_cache::Entry*);
673
674 disk_cache::Entry** entry_ptr = entry.get();
675
676 net::CompletionCallback open_entry_callback =
677 base::Bind(MatchDidOpenEntry,
678 request,
679 callback,
680 blob_storage_context_,
681 base::Passed(entry.Pass()));
682
683 int rv =
684 backend_->OpenEntry(request->url.spec(), entry_ptr, open_entry_callback);
685 if (rv != net::ERR_IO_PENDING)
686 open_entry_callback.Run(rv);
687 }
688
689 void ServiceWorkerCache::Delete(ServiceWorkerFetchRequest* request,
690 const ErrorCallback& callback) {
691 DCHECK(backend_);
692
693 scoped_ptr<disk_cache::Entry*> entry(new disk_cache::Entry*);
694
695 disk_cache::Entry** entry_ptr = entry.get();
696
697 net::CompletionCallback open_entry_callback = base::Bind(
698 DeleteDidOpenEntry, request, callback, base::Passed(entry.Pass()));
699
700 int rv =
701 backend_->OpenEntry(request->url.spec(), entry_ptr, open_entry_callback);
702 if (rv != net::ERR_IO_PENDING)
703 open_entry_callback.Run(rv);
704 }
705
706 bool ServiceWorkerCache::HasCreatedBackend() const {
707 return backend_;
708 }
709
43 ServiceWorkerCache::ServiceWorkerCache( 710 ServiceWorkerCache::ServiceWorkerCache(
44 const base::FilePath& path, 711 const base::FilePath& path,
45 const std::string& name, 712 const std::string& name,
46 net::URLRequestContext* request_context, 713 net::URLRequestContext* request_context,
47 base::WeakPtr<storage::BlobStorageContext> blob_context) 714 base::WeakPtr<storage::BlobStorageContext> blob_context)
48 : path_(path), 715 : path_(path),
49 name_(name), 716 name_(name),
50 request_context_(request_context), 717 request_context_(request_context),
51 blob_storage_context_(blob_context), 718 blob_storage_context_(blob_context),
52 id_(0), 719 id_(0),
53 weak_ptr_factory_(this) { 720 weak_ptr_factory_(this) {
54 } 721 }
55 722
56 ServiceWorkerCache::~ServiceWorkerCache() {
57 }
58
59 } // namespace content 723 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/service_worker/service_worker_cache.h ('k') | content/browser/service_worker/service_worker_cache.proto » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698