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 "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" | 10 #include "base/guid.h" |
11 #include "base/message_loop/message_loop_proxy.h" | 11 #include "base/message_loop/message_loop_proxy.h" |
12 #include "content/browser/service_worker/service_worker_cache.pb.h" | 12 #include "content/browser/service_worker/service_worker_cache.pb.h" |
13 #include "content/public/browser/browser_thread.h" | 13 #include "content/public/browser/browser_thread.h" |
14 #include "net/base/io_buffer.h" | 14 #include "net/base/io_buffer.h" |
15 #include "net/base/net_errors.h" | 15 #include "net/base/net_errors.h" |
16 #include "net/disk_cache/disk_cache.h" | 16 #include "net/disk_cache/disk_cache.h" |
17 #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" | 18 #include "webkit/browser/blob/blob_data_handle.h" |
19 #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" | 20 #include "webkit/browser/blob/blob_url_request_job_factory.h" |
21 | 21 |
22 namespace content { | 22 namespace content { |
23 | 23 |
24 namespace { | 24 namespace { |
25 | 25 |
26 typedef scoped_ptr<disk_cache::Backend> ScopedBackendPtr; | 26 typedef scoped_ptr<disk_cache::Backend> ScopedBackendPtr; |
27 typedef base::Callback<void(bool)> BoolCallback; | 27 typedef base::Callback<void(bool)> BoolCallback; |
28 typedef base::Callback<void(disk_cache::ScopedEntryPtr, bool)> | 28 typedef base::Callback<void(disk_cache::ScopedEntryPtr, bool)> |
29 EntryBoolCallback; | 29 EntryBoolCallback; |
30 typedef base::Callback<void(scoped_ptr<ServiceWorkerRequestResponseHeaders>)> | |
31 HeadersCallback; | |
32 | |
30 enum EntryIndex { INDEX_HEADERS = 0, INDEX_RESPONSE_BODY }; | 33 enum EntryIndex { INDEX_HEADERS = 0, INDEX_RESPONSE_BODY }; |
31 | 34 |
32 // The maximum size of an individual cache. Ultimately cache size is controlled | 35 // The maximum size of an individual cache. Ultimately cache size is controlled |
33 // per-origin. | 36 // per-origin. |
34 const int kMaxCacheBytes = 512 * 1024 * 1024; | 37 const int kMaxCacheBytes = 512 * 1024 * 1024; |
35 | 38 |
36 // Buffer size for cache and blob reading/writing. | 39 // Buffer size for cache and blob reading/writing. |
37 const int kBufferSize = 1024 * 512; | 40 const int kBufferSize = 1024 * 512; |
38 | 41 |
39 struct ResponseReadContext { | 42 struct ResponseReadContext { |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
182 void MatchDidOpenEntry(ServiceWorkerFetchRequest* request, | 185 void MatchDidOpenEntry(ServiceWorkerFetchRequest* request, |
183 const ServiceWorkerCache::ResponseCallback& callback, | 186 const ServiceWorkerCache::ResponseCallback& callback, |
184 base::WeakPtr<storage::BlobStorageContext> blob_storage, | 187 base::WeakPtr<storage::BlobStorageContext> blob_storage, |
185 scoped_ptr<disk_cache::Entry*> entryptr, | 188 scoped_ptr<disk_cache::Entry*> entryptr, |
186 int rv); | 189 int rv); |
187 void MatchDidReadHeaderData( | 190 void MatchDidReadHeaderData( |
188 ServiceWorkerFetchRequest* request, | 191 ServiceWorkerFetchRequest* request, |
189 const ServiceWorkerCache::ResponseCallback& callback, | 192 const ServiceWorkerCache::ResponseCallback& callback, |
190 base::WeakPtr<storage::BlobStorageContext> blob_storage, | 193 base::WeakPtr<storage::BlobStorageContext> blob_storage, |
191 disk_cache::ScopedEntryPtr entry, | 194 disk_cache::ScopedEntryPtr entry, |
192 const scoped_refptr<net::IOBufferWithSize>& buffer, | 195 scoped_ptr<ServiceWorkerRequestResponseHeaders> headers); |
193 int rv); | |
194 void MatchDidReadResponseBodyData( | 196 void MatchDidReadResponseBodyData( |
195 ServiceWorkerFetchRequest* request, | 197 ServiceWorkerFetchRequest* request, |
196 const ServiceWorkerCache::ResponseCallback& callback, | 198 const ServiceWorkerCache::ResponseCallback& callback, |
197 base::WeakPtr<storage::BlobStorageContext> blob_storage, | 199 base::WeakPtr<storage::BlobStorageContext> blob_storage, |
198 disk_cache::ScopedEntryPtr entry, | 200 disk_cache::ScopedEntryPtr entry, |
199 scoped_ptr<ServiceWorkerResponse> response, | 201 scoped_ptr<ServiceWorkerResponse> response, |
200 scoped_ptr<ResponseReadContext> response_context, | 202 scoped_ptr<ResponseReadContext> response_context, |
201 int rv); | 203 int rv); |
202 void MatchDoneWithBody(ServiceWorkerFetchRequest* request, | 204 void MatchDoneWithBody(ServiceWorkerFetchRequest* request, |
203 const ServiceWorkerCache::ResponseCallback& callback, | 205 const ServiceWorkerCache::ResponseCallback& callback, |
204 base::WeakPtr<storage::BlobStorageContext> blob_storage, | 206 base::WeakPtr<storage::BlobStorageContext> blob_storage, |
205 scoped_ptr<ServiceWorkerResponse> response, | 207 scoped_ptr<ServiceWorkerResponse> response, |
206 scoped_ptr<ResponseReadContext> response_context); | 208 scoped_ptr<ResponseReadContext> response_context); |
207 | 209 |
208 // Delete callbacks | 210 // Delete callbacks |
209 void DeleteDidOpenEntry(ServiceWorkerFetchRequest* request, | 211 void DeleteDidOpenEntry(ServiceWorkerFetchRequest* request, |
210 const ServiceWorkerCache::ErrorCallback& callback, | 212 const ServiceWorkerCache::ErrorCallback& callback, |
211 scoped_ptr<disk_cache::Entry*> entryptr, | 213 scoped_ptr<disk_cache::Entry*> entryptr, |
212 int rv); | 214 int rv); |
213 | 215 |
216 // Copy headers out of a cache entry and into a protobuf. The callback is | |
217 // guaranteed to be run. | |
218 void ReadHeaders(disk_cache::Entry* entry, const HeadersCallback& callback); | |
219 void ReadHeadersDidReadHeaderData( | |
220 disk_cache::Entry* entry, | |
221 const HeadersCallback& callback, | |
222 const scoped_refptr<net::IOBufferWithSize>& buffer, | |
223 int rv); | |
224 | |
214 // CreateBackend callbacks | 225 // CreateBackend callbacks |
215 void CreateBackendDidCreate(const ServiceWorkerCache::ErrorCallback& callback, | 226 void CreateBackendDidCreate(const ServiceWorkerCache::ErrorCallback& callback, |
216 scoped_ptr<ScopedBackendPtr> backend_ptr, | 227 scoped_ptr<ScopedBackendPtr> backend_ptr, |
217 base::WeakPtr<ServiceWorkerCache> cache, | 228 base::WeakPtr<ServiceWorkerCache> cache, |
218 int rv); | 229 int rv); |
219 | 230 |
220 void PutDidCreateEntry(ServiceWorkerFetchRequest* request, | 231 void PutDidCreateEntry(ServiceWorkerFetchRequest* request, |
221 ServiceWorkerResponse* response, | 232 ServiceWorkerResponse* response, |
222 const ServiceWorkerCache::ErrorCallback& callback, | 233 const ServiceWorkerCache::ErrorCallback& callback, |
223 scoped_ptr<disk_cache::Entry*> entryptr, | 234 scoped_ptr<disk_cache::Entry*> entryptr, |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
343 if (rv != net::OK) { | 354 if (rv != net::OK) { |
344 callback.Run(ServiceWorkerCache::ErrorTypeNotFound, | 355 callback.Run(ServiceWorkerCache::ErrorTypeNotFound, |
345 scoped_ptr<ServiceWorkerResponse>(), | 356 scoped_ptr<ServiceWorkerResponse>(), |
346 scoped_ptr<storage::BlobDataHandle>()); | 357 scoped_ptr<storage::BlobDataHandle>()); |
347 return; | 358 return; |
348 } | 359 } |
349 | 360 |
350 DCHECK(entryptr); | 361 DCHECK(entryptr); |
351 disk_cache::ScopedEntryPtr entry(*entryptr); | 362 disk_cache::ScopedEntryPtr entry(*entryptr); |
352 | 363 |
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. | 364 // Copy the entry pointer before passing it in base::Bind. |
357 disk_cache::Entry* tmp_entry_ptr = entry.get(); | 365 disk_cache::Entry* tmp_entry_ptr = entry.get(); |
358 | 366 |
359 net::CompletionCallback read_header_callback = | 367 HeadersCallback headers_callback = base::Bind(MatchDidReadHeaderData, |
360 base::Bind(MatchDidReadHeaderData, | 368 request, |
361 request, | 369 callback, |
362 callback, | 370 blob_storage, |
363 blob_storage, | 371 base::Passed(entry.Pass())); |
364 base::Passed(entry.Pass()), | |
365 buffer); | |
366 | 372 |
367 int read_rv = tmp_entry_ptr->ReadData( | 373 ReadHeaders(tmp_entry_ptr, headers_callback); |
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 } | 374 } |
373 | 375 |
374 void MatchDidReadHeaderData( | 376 void MatchDidReadHeaderData( |
375 ServiceWorkerFetchRequest* request, | 377 ServiceWorkerFetchRequest* request, |
376 const ServiceWorkerCache::ResponseCallback& callback, | 378 const ServiceWorkerCache::ResponseCallback& callback, |
377 base::WeakPtr<storage::BlobStorageContext> blob_storage, | 379 base::WeakPtr<storage::BlobStorageContext> blob_storage, |
378 disk_cache::ScopedEntryPtr entry, | 380 disk_cache::ScopedEntryPtr entry, |
379 const scoped_refptr<net::IOBufferWithSize>& buffer, | 381 scoped_ptr<ServiceWorkerRequestResponseHeaders> headers) { |
380 int rv) { | 382 if (!headers) { |
381 if (rv != buffer->size()) { | |
382 callback.Run(ServiceWorkerCache::ErrorTypeStorage, | 383 callback.Run(ServiceWorkerCache::ErrorTypeStorage, |
383 scoped_ptr<ServiceWorkerResponse>(), | 384 scoped_ptr<ServiceWorkerResponse>(), |
384 scoped_ptr<storage::BlobDataHandle>()); | 385 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; | 386 return; |
397 } | 387 } |
398 | 388 |
399 scoped_ptr<ServiceWorkerResponse> response( | 389 scoped_ptr<ServiceWorkerResponse> response( |
400 new ServiceWorkerResponse(request->url, | 390 new ServiceWorkerResponse(request->url, |
401 headers.status_code(), | 391 headers->status_code(), |
402 headers.status_text(), | 392 headers->status_text(), |
403 std::map<std::string, std::string>(), | 393 std::map<std::string, std::string>(), |
404 "")); | 394 "")); |
405 | 395 |
406 for (int i = 0; i < headers.response_headers_size(); ++i) { | 396 for (int i = 0; i < headers->response_headers_size(); ++i) { |
407 const ServiceWorkerRequestResponseHeaders::HeaderMap header = | 397 const ServiceWorkerRequestResponseHeaders::HeaderMap header = |
408 headers.response_headers(i); | 398 headers->response_headers(i); |
409 response->headers.insert(std::make_pair(header.name(), header.value())); | 399 response->headers.insert(std::make_pair(header.name(), header.value())); |
410 } | 400 } |
411 | 401 |
412 // TODO(jkarlin): Insert vary validation here. | 402 // TODO(jkarlin): Insert vary validation here. |
413 | 403 |
414 if (entry->GetDataSize(INDEX_RESPONSE_BODY) == 0) { | 404 if (entry->GetDataSize(INDEX_RESPONSE_BODY) == 0) { |
415 callback.Run(ServiceWorkerCache::ErrorTypeOK, | 405 callback.Run(ServiceWorkerCache::ErrorTypeOK, |
416 response.Pass(), | 406 response.Pass(), |
417 scoped_ptr<storage::BlobDataHandle>()); | 407 scoped_ptr<storage::BlobDataHandle>()); |
418 return; | 408 return; |
419 } | 409 } |
420 | 410 |
421 // Stream the response body into a blob. | 411 // Stream the response body into a blob. |
422 if (!blob_storage) { | 412 if (!blob_storage) { |
423 callback.Run(ServiceWorkerCache::ErrorTypeStorage, | 413 callback.Run(ServiceWorkerCache::ErrorTypeStorage, |
424 scoped_ptr<ServiceWorkerResponse>(), | 414 scoped_ptr<ServiceWorkerResponse>(), |
425 scoped_ptr<storage::BlobDataHandle>()); | 415 scoped_ptr<storage::BlobDataHandle>()); |
426 | |
427 return; | 416 return; |
428 } | 417 } |
429 | 418 |
430 response->blob_uuid = base::GenerateGUID(); | 419 response->blob_uuid = base::GenerateGUID(); |
431 | 420 |
432 scoped_refptr<storage::BlobData> blob_data = | 421 scoped_refptr<storage::BlobData> blob_data = |
433 new storage::BlobData(response->blob_uuid); | 422 new storage::BlobData(response->blob_uuid); |
434 scoped_refptr<net::IOBufferWithSize> response_body_buffer( | 423 scoped_refptr<net::IOBufferWithSize> response_body_buffer( |
435 new net::IOBufferWithSize(kBufferSize)); | 424 new net::IOBufferWithSize(kBufferSize)); |
436 | 425 |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
542 return; | 531 return; |
543 } | 532 } |
544 | 533 |
545 DCHECK(entryptr); | 534 DCHECK(entryptr); |
546 disk_cache::ScopedEntryPtr entry(*entryptr); | 535 disk_cache::ScopedEntryPtr entry(*entryptr); |
547 | 536 |
548 entry->Doom(); | 537 entry->Doom(); |
549 callback.Run(ServiceWorkerCache::ErrorTypeOK); | 538 callback.Run(ServiceWorkerCache::ErrorTypeOK); |
550 } | 539 } |
551 | 540 |
541 void ReadHeaders(disk_cache::Entry* entry, const HeadersCallback& callback) { | |
542 DCHECK(entry); | |
543 | |
544 scoped_refptr<net::IOBufferWithSize> buffer( | |
545 new net::IOBufferWithSize(entry->GetDataSize(INDEX_HEADERS))); | |
546 | |
547 net::CompletionCallback read_header_callback = | |
548 base::Bind(ReadHeadersDidReadHeaderData, entry, callback, buffer); | |
549 | |
550 int read_rv = entry->ReadData( | |
551 INDEX_HEADERS, 0, buffer.get(), buffer->size(), read_header_callback); | |
552 | |
553 if (read_rv != net::ERR_IO_PENDING) | |
554 read_header_callback.Run(read_rv); | |
555 } | |
556 | |
557 void ReadHeadersDidReadHeaderData( | |
558 disk_cache::Entry* entry, | |
559 const HeadersCallback& callback, | |
560 const scoped_refptr<net::IOBufferWithSize>& buffer, | |
561 int rv) { | |
562 if (rv != buffer->size()) { | |
563 callback.Run(scoped_ptr<ServiceWorkerRequestResponseHeaders>()); | |
564 return; | |
565 } | |
566 | |
567 scoped_ptr<ServiceWorkerRequestResponseHeaders> headers( | |
568 new ServiceWorkerRequestResponseHeaders()); | |
569 | |
570 if (!headers->ParseFromArray(buffer->data(), buffer->size())) { | |
571 callback.Run(scoped_ptr<ServiceWorkerRequestResponseHeaders>()); | |
572 return; | |
573 } | |
574 | |
575 callback.Run(headers.Pass()); | |
576 } | |
577 | |
552 void CreateBackendDidCreate(const ServiceWorkerCache::ErrorCallback& callback, | 578 void CreateBackendDidCreate(const ServiceWorkerCache::ErrorCallback& callback, |
553 scoped_ptr<ScopedBackendPtr> backend_ptr, | 579 scoped_ptr<ScopedBackendPtr> backend_ptr, |
554 base::WeakPtr<ServiceWorkerCache> cache, | 580 base::WeakPtr<ServiceWorkerCache> cache, |
555 int rv) { | 581 int rv) { |
556 if (rv != net::OK || !cache) { | 582 if (rv != net::OK || !cache) { |
557 callback.Run(ServiceWorkerCache::ErrorTypeStorage); | 583 callback.Run(ServiceWorkerCache::ErrorTypeStorage); |
558 return; | 584 return; |
559 } | 585 } |
586 | |
560 cache->set_backend(backend_ptr->Pass()); | 587 cache->set_backend(backend_ptr->Pass()); |
561 callback.Run(ServiceWorkerCache::ErrorTypeOK); | 588 callback.Run(ServiceWorkerCache::ErrorTypeOK); |
562 } | 589 } |
563 | 590 |
564 } // namespace | 591 } // namespace |
565 | 592 |
593 // The state needed to pass between ServiceWorkerCache::Keys callbacks. | |
594 struct ServiceWorkerCache::KeysContext { | |
595 KeysContext(const ServiceWorkerCache::RequestsCallback& callback, | |
596 base::WeakPtr<ServiceWorkerCache> cache) | |
597 : original_callback(callback), | |
598 cache(cache), | |
599 out_keys(new ServiceWorkerCache::Requests()), | |
600 backend_iterator(NULL), | |
601 enumerated_entry(NULL) {} | |
602 | |
603 ~KeysContext() { | |
michaeln
2014/08/28 23:49:39
if (enumerated_entry) enumerated_entry->Close(); ?
jkarlin
2014/08/29 19:43:29
Done.
| |
604 for (size_t i = 0, max = entries.size(); i < max; ++i) | |
605 entries[i]->Close(); | |
606 } | |
607 | |
608 // The callback passed to the Keys() function. | |
609 ServiceWorkerCache::RequestsCallback original_callback; | |
610 | |
611 // The ServiceWorkerCache that Keys was called on. | |
612 base::WeakPtr<ServiceWorkerCache> cache; | |
613 | |
614 // The vector of open entries in the backend. | |
615 Entries entries; | |
616 | |
617 // The output of the Keys function. | |
618 scoped_ptr<ServiceWorkerCache::Requests> out_keys; | |
619 | |
620 // Used for enumerating cache entries. | |
621 void* backend_iterator; | |
622 disk_cache::Entry* enumerated_entry; | |
623 }; | |
624 | |
566 // static | 625 // static |
567 scoped_ptr<ServiceWorkerCache> ServiceWorkerCache::CreateMemoryCache( | 626 scoped_ptr<ServiceWorkerCache> ServiceWorkerCache::CreateMemoryCache( |
568 net::URLRequestContext* request_context, | 627 net::URLRequestContext* request_context, |
569 base::WeakPtr<storage::BlobStorageContext> blob_context) { | 628 base::WeakPtr<storage::BlobStorageContext> blob_context) { |
570 return make_scoped_ptr( | 629 return make_scoped_ptr( |
571 new ServiceWorkerCache(base::FilePath(), request_context, blob_context)); | 630 new ServiceWorkerCache(base::FilePath(), request_context, blob_context)); |
572 } | 631 } |
573 | 632 |
574 // static | 633 // static |
575 scoped_ptr<ServiceWorkerCache> ServiceWorkerCache::CreatePersistentCache( | 634 scoped_ptr<ServiceWorkerCache> ServiceWorkerCache::CreatePersistentCache( |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
694 | 753 |
695 net::CompletionCallback open_entry_callback = base::Bind( | 754 net::CompletionCallback open_entry_callback = base::Bind( |
696 DeleteDidOpenEntry, request, callback, base::Passed(entry.Pass())); | 755 DeleteDidOpenEntry, request, callback, base::Passed(entry.Pass())); |
697 | 756 |
698 int rv = | 757 int rv = |
699 backend_->OpenEntry(request->url.spec(), entry_ptr, open_entry_callback); | 758 backend_->OpenEntry(request->url.spec(), entry_ptr, open_entry_callback); |
700 if (rv != net::ERR_IO_PENDING) | 759 if (rv != net::ERR_IO_PENDING) |
701 open_entry_callback.Run(rv); | 760 open_entry_callback.Run(rv); |
702 } | 761 } |
703 | 762 |
763 void ServiceWorkerCache::Keys(const RequestsCallback& callback) { | |
764 DCHECK(backend_); | |
765 | |
766 // 1. Iterate through all of the entries, open them, and add them to a vector. | |
767 // 2. For each open entry: | |
768 // 2.1. Read the headers into a protobuf. | |
769 // 2.2. Copy the protobuf into a ServiceWorkerFetchRequest (a "key"). | |
770 // 2.3. Push the response into a vector of requests to be returned. | |
771 // 3. Return the vector of requests (keys). | |
772 | |
773 // The entries have to be loaded into a vector first because enumeration loops | |
774 // forever if you read data from a cache entry while enumerating. | |
michaeln
2014/08/28 23:49:39
Is this going to be a problem if/when data retriev
jkarlin
2014/08/29 11:09:38
What a fantastic question. I'm going to look into
| |
775 | |
776 scoped_ptr<KeysContext> keys_context( | |
777 new KeysContext(callback, weak_ptr_factory_.GetWeakPtr())); | |
778 | |
779 void** backend_iterator = &keys_context->backend_iterator; | |
780 disk_cache::Entry** enumerated_entry = &keys_context->enumerated_entry; | |
781 | |
782 net::CompletionCallback open_entry_callback = | |
783 base::Bind(KeysDidOpenNextEntry, base::Passed(keys_context.Pass())); | |
784 | |
785 int rv = backend_->OpenNextEntry( | |
786 backend_iterator, enumerated_entry, open_entry_callback); | |
787 | |
788 if (rv != net::ERR_IO_PENDING) | |
789 open_entry_callback.Run(rv); | |
790 } | |
791 | |
704 bool ServiceWorkerCache::HasCreatedBackend() const { | 792 bool ServiceWorkerCache::HasCreatedBackend() const { |
705 return backend_; | 793 return backend_; |
706 } | 794 } |
707 | 795 |
708 ServiceWorkerCache::ServiceWorkerCache( | 796 ServiceWorkerCache::ServiceWorkerCache( |
709 const base::FilePath& path, | 797 const base::FilePath& path, |
710 net::URLRequestContext* request_context, | 798 net::URLRequestContext* request_context, |
711 base::WeakPtr<storage::BlobStorageContext> blob_context) | 799 base::WeakPtr<storage::BlobStorageContext> blob_context) |
712 : path_(path), | 800 : path_(path), |
713 request_context_(request_context), | 801 request_context_(request_context), |
714 blob_storage_context_(blob_context), | 802 blob_storage_context_(blob_context), |
715 weak_ptr_factory_(this) { | 803 weak_ptr_factory_(this) { |
716 } | 804 } |
717 | 805 |
806 // static | |
807 void ServiceWorkerCache::KeysDidOpenNextEntry( | |
808 scoped_ptr<KeysContext> keys_context, | |
809 int rv) { | |
810 if (rv == net::ERR_FAILED) { | |
michaeln
2014/08/28 23:49:39
DCHECK(!enumerated_entry) ?
jkarlin
2014/08/29 19:43:29
Done.
| |
811 // Enumeration is complete, extract the requests from the entries. | |
812 Entries::iterator iter = keys_context->entries.begin(); | |
813 KeysProcessNextEntry(keys_context.Pass(), iter); | |
814 return; | |
815 } | |
816 | |
817 base::WeakPtr<ServiceWorkerCache> cache = keys_context->cache; | |
818 if (rv < 0 || !cache) { | |
819 keys_context->original_callback.Run( | |
820 ErrorTypeStorage, | |
821 scoped_ptr<Requests>()); | |
822 return; | |
823 } | |
824 | |
825 // Store the entry. | |
826 keys_context->entries.push_back(keys_context->enumerated_entry); | |
michaeln
2014/08/28 23:49:39
keys_contenxt->enumerated_entry = NULL; ?
jkarlin
2014/08/29 19:43:29
Done.
| |
827 | |
828 // Enumerate the next entry. | |
829 void** backend_iterator = &keys_context->backend_iterator; | |
830 disk_cache::Entry** enumerated_entry = &keys_context->enumerated_entry; | |
831 | |
832 net::CompletionCallback open_entry_callback = | |
833 base::Bind(KeysDidOpenNextEntry, base::Passed(keys_context.Pass())); | |
834 | |
835 rv = cache->backend_->OpenNextEntry( | |
836 backend_iterator, enumerated_entry, open_entry_callback); | |
837 | |
838 if (rv != net::ERR_IO_PENDING) | |
839 open_entry_callback.Run(rv); | |
840 } | |
841 | |
842 // static | |
843 void ServiceWorkerCache::KeysProcessNextEntry( | |
844 scoped_ptr<KeysContext> keys_context, | |
845 const Entries::iterator& iter) { | |
846 if (iter == keys_context->entries.end()) { | |
847 // All done. Return all of the keys. | |
848 keys_context->original_callback.Run(ErrorTypeOK, | |
849 keys_context->out_keys.Pass()); | |
850 return; | |
851 } | |
852 | |
853 ReadHeaders( | |
854 *iter, | |
855 base::Bind(KeysDidReadHeaders, base::Passed(keys_context.Pass()), iter)); | |
856 } | |
857 | |
858 // static | |
859 void ServiceWorkerCache::KeysDidReadHeaders( | |
860 scoped_ptr<KeysContext> keys_context, | |
861 const Entries::iterator& iter, | |
862 scoped_ptr<ServiceWorkerRequestResponseHeaders> headers) { | |
863 disk_cache::Entry* entry = *iter; | |
864 | |
865 if (headers) { | |
866 keys_context->out_keys->push_back( | |
867 ServiceWorkerFetchRequest(GURL(entry->GetKey()), | |
868 headers->method(), | |
869 std::map<std::string, std::string>(), | |
870 GURL(), | |
871 false)); | |
872 | |
873 std::map<std::string, std::string>& req_headers = | |
874 keys_context->out_keys->back().headers; | |
875 | |
876 for (int i = 0; i < headers->request_headers_size(); ++i) { | |
877 const ServiceWorkerRequestResponseHeaders::HeaderMap header = | |
878 headers->request_headers(i); | |
879 req_headers.insert(std::make_pair(header.name(), header.value())); | |
880 } | |
881 } else { | |
882 entry->Doom(); | |
883 } | |
884 | |
885 KeysProcessNextEntry(keys_context.Pass(), iter + 1); | |
886 } | |
887 | |
718 } // namespace content | 888 } // namespace content |
OLD | NEW |