| 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() { |
| 604 for (size_t i = 0, max = entries.size(); i < max; ++i) |
| 605 entries[i]->Close(); |
| 606 if (enumerated_entry) |
| 607 enumerated_entry->Close(); |
| 608 if (cache && backend_iterator) |
| 609 cache->backend_->EndEnumeration(&backend_iterator); |
| 610 } |
| 611 |
| 612 // The callback passed to the Keys() function. |
| 613 ServiceWorkerCache::RequestsCallback original_callback; |
| 614 |
| 615 // The ServiceWorkerCache that Keys was called on. |
| 616 base::WeakPtr<ServiceWorkerCache> cache; |
| 617 |
| 618 // The vector of open entries in the backend. |
| 619 Entries entries; |
| 620 |
| 621 // The output of the Keys function. |
| 622 scoped_ptr<ServiceWorkerCache::Requests> out_keys; |
| 623 |
| 624 // Used for enumerating cache entries. |
| 625 void* backend_iterator; |
| 626 disk_cache::Entry* enumerated_entry; |
| 627 }; |
| 628 |
| 566 // static | 629 // static |
| 567 scoped_ptr<ServiceWorkerCache> ServiceWorkerCache::CreateMemoryCache( | 630 scoped_ptr<ServiceWorkerCache> ServiceWorkerCache::CreateMemoryCache( |
| 568 net::URLRequestContext* request_context, | 631 net::URLRequestContext* request_context, |
| 569 base::WeakPtr<storage::BlobStorageContext> blob_context) { | 632 base::WeakPtr<storage::BlobStorageContext> blob_context) { |
| 570 return make_scoped_ptr( | 633 return make_scoped_ptr( |
| 571 new ServiceWorkerCache(base::FilePath(), request_context, blob_context)); | 634 new ServiceWorkerCache(base::FilePath(), request_context, blob_context)); |
| 572 } | 635 } |
| 573 | 636 |
| 574 // static | 637 // static |
| 575 scoped_ptr<ServiceWorkerCache> ServiceWorkerCache::CreatePersistentCache( | 638 scoped_ptr<ServiceWorkerCache> ServiceWorkerCache::CreatePersistentCache( |
| (...skipping 28 matching lines...) Expand all Loading... |
| 604 callback, | 667 callback, |
| 605 base::Passed(backend_ptr.Pass()), | 668 base::Passed(backend_ptr.Pass()), |
| 606 weak_ptr_factory_.GetWeakPtr()); | 669 weak_ptr_factory_.GetWeakPtr()); |
| 607 | 670 |
| 608 // TODO(jkarlin): Use the cache MessageLoopProxy that ServiceWorkerCacheCore | 671 // TODO(jkarlin): Use the cache MessageLoopProxy that ServiceWorkerCacheCore |
| 609 // has for disk caches. | 672 // has for disk caches. |
| 610 // TODO(jkarlin): Switch to SimpleCache after it supports APP_CACHE and after | 673 // TODO(jkarlin): Switch to SimpleCache after it supports APP_CACHE and after |
| 611 // debugging why the QuickStressBody unittest fails with it. | 674 // debugging why the QuickStressBody unittest fails with it. |
| 612 int rv = disk_cache::CreateCacheBackend( | 675 int rv = disk_cache::CreateCacheBackend( |
| 613 cache_type, | 676 cache_type, |
| 614 net::CACHE_BACKEND_DEFAULT, | 677 net::CACHE_BACKEND_SIMPLE, |
| 615 path_, | 678 path_, |
| 616 kMaxCacheBytes, | 679 kMaxCacheBytes, |
| 617 false, /* force */ | 680 false, /* force */ |
| 618 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE).get(), | 681 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE).get(), |
| 619 NULL, | 682 NULL, |
| 620 backend, | 683 backend, |
| 621 create_cache_callback); | 684 create_cache_callback); |
| 622 if (rv != net::ERR_IO_PENDING) | 685 if (rv != net::ERR_IO_PENDING) |
| 623 create_cache_callback.Run(rv); | 686 create_cache_callback.Run(rv); |
| 624 } | 687 } |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 694 | 757 |
| 695 net::CompletionCallback open_entry_callback = base::Bind( | 758 net::CompletionCallback open_entry_callback = base::Bind( |
| 696 DeleteDidOpenEntry, request, callback, base::Passed(entry.Pass())); | 759 DeleteDidOpenEntry, request, callback, base::Passed(entry.Pass())); |
| 697 | 760 |
| 698 int rv = | 761 int rv = |
| 699 backend_->OpenEntry(request->url.spec(), entry_ptr, open_entry_callback); | 762 backend_->OpenEntry(request->url.spec(), entry_ptr, open_entry_callback); |
| 700 if (rv != net::ERR_IO_PENDING) | 763 if (rv != net::ERR_IO_PENDING) |
| 701 open_entry_callback.Run(rv); | 764 open_entry_callback.Run(rv); |
| 702 } | 765 } |
| 703 | 766 |
| 767 void ServiceWorkerCache::Keys(const RequestsCallback& callback) { |
| 768 DCHECK(backend_); |
| 769 |
| 770 // 1. Iterate through all of the entries, open them, and add them to a vector. |
| 771 // 2. For each open entry: |
| 772 // 2.1. Read the headers into a protobuf. |
| 773 // 2.2. Copy the protobuf into a ServiceWorkerFetchRequest (a "key"). |
| 774 // 2.3. Push the response into a vector of requests to be returned. |
| 775 // 3. Return the vector of requests (keys). |
| 776 |
| 777 // The entries have to be loaded into a vector first because enumeration loops |
| 778 // forever if you read data from a cache entry while enumerating. |
| 779 |
| 780 scoped_ptr<KeysContext> keys_context( |
| 781 new KeysContext(callback, weak_ptr_factory_.GetWeakPtr())); |
| 782 |
| 783 void** backend_iterator = &keys_context->backend_iterator; |
| 784 disk_cache::Entry** enumerated_entry = &keys_context->enumerated_entry; |
| 785 |
| 786 net::CompletionCallback open_entry_callback = |
| 787 base::Bind(KeysDidOpenNextEntry, base::Passed(keys_context.Pass())); |
| 788 |
| 789 int rv = backend_->OpenNextEntry( |
| 790 backend_iterator, enumerated_entry, open_entry_callback); |
| 791 |
| 792 if (rv != net::ERR_IO_PENDING) |
| 793 open_entry_callback.Run(rv); |
| 794 } |
| 795 |
| 704 bool ServiceWorkerCache::HasCreatedBackend() const { | 796 bool ServiceWorkerCache::HasCreatedBackend() const { |
| 705 return backend_; | 797 return backend_; |
| 706 } | 798 } |
| 707 | 799 |
| 708 ServiceWorkerCache::ServiceWorkerCache( | 800 ServiceWorkerCache::ServiceWorkerCache( |
| 709 const base::FilePath& path, | 801 const base::FilePath& path, |
| 710 net::URLRequestContext* request_context, | 802 net::URLRequestContext* request_context, |
| 711 base::WeakPtr<storage::BlobStorageContext> blob_context) | 803 base::WeakPtr<storage::BlobStorageContext> blob_context) |
| 712 : path_(path), | 804 : path_(path), |
| 713 request_context_(request_context), | 805 request_context_(request_context), |
| 714 blob_storage_context_(blob_context), | 806 blob_storage_context_(blob_context), |
| 715 weak_ptr_factory_(this) { | 807 weak_ptr_factory_(this) { |
| 716 } | 808 } |
| 717 | 809 |
| 810 // static |
| 811 void ServiceWorkerCache::KeysDidOpenNextEntry( |
| 812 scoped_ptr<KeysContext> keys_context, |
| 813 int rv) { |
| 814 if (rv == net::ERR_FAILED) { |
| 815 DCHECK(!keys_context->enumerated_entry); |
| 816 // Enumeration is complete, extract the requests from the entries. |
| 817 Entries::iterator iter = keys_context->entries.begin(); |
| 818 KeysProcessNextEntry(keys_context.Pass(), iter); |
| 819 return; |
| 820 } |
| 821 |
| 822 base::WeakPtr<ServiceWorkerCache> cache = keys_context->cache; |
| 823 if (rv < 0 || !cache) { |
| 824 keys_context->original_callback.Run(ErrorTypeStorage, |
| 825 scoped_ptr<Requests>()); |
| 826 return; |
| 827 } |
| 828 |
| 829 // Store the entry. |
| 830 keys_context->entries.push_back(keys_context->enumerated_entry); |
| 831 keys_context->enumerated_entry = NULL; |
| 832 |
| 833 // Enumerate the next entry. |
| 834 void** backend_iterator = &keys_context->backend_iterator; |
| 835 disk_cache::Entry** enumerated_entry = &keys_context->enumerated_entry; |
| 836 |
| 837 net::CompletionCallback open_entry_callback = |
| 838 base::Bind(KeysDidOpenNextEntry, base::Passed(keys_context.Pass())); |
| 839 |
| 840 rv = cache->backend_->OpenNextEntry( |
| 841 backend_iterator, enumerated_entry, open_entry_callback); |
| 842 |
| 843 if (rv != net::ERR_IO_PENDING) |
| 844 open_entry_callback.Run(rv); |
| 845 } |
| 846 |
| 847 // static |
| 848 void ServiceWorkerCache::KeysProcessNextEntry( |
| 849 scoped_ptr<KeysContext> keys_context, |
| 850 const Entries::iterator& iter) { |
| 851 if (iter == keys_context->entries.end()) { |
| 852 // All done. Return all of the keys. |
| 853 keys_context->original_callback.Run(ErrorTypeOK, |
| 854 keys_context->out_keys.Pass()); |
| 855 return; |
| 856 } |
| 857 |
| 858 ReadHeaders( |
| 859 *iter, |
| 860 base::Bind(KeysDidReadHeaders, base::Passed(keys_context.Pass()), iter)); |
| 861 } |
| 862 |
| 863 // static |
| 864 void ServiceWorkerCache::KeysDidReadHeaders( |
| 865 scoped_ptr<KeysContext> keys_context, |
| 866 const Entries::iterator& iter, |
| 867 scoped_ptr<ServiceWorkerRequestResponseHeaders> headers) { |
| 868 disk_cache::Entry* entry = *iter; |
| 869 |
| 870 if (headers) { |
| 871 keys_context->out_keys->push_back( |
| 872 ServiceWorkerFetchRequest(GURL(entry->GetKey()), |
| 873 headers->method(), |
| 874 std::map<std::string, std::string>(), |
| 875 GURL(), |
| 876 false)); |
| 877 |
| 878 std::map<std::string, std::string>& req_headers = |
| 879 keys_context->out_keys->back().headers; |
| 880 |
| 881 for (int i = 0; i < headers->request_headers_size(); ++i) { |
| 882 const ServiceWorkerRequestResponseHeaders::HeaderMap header = |
| 883 headers->request_headers(i); |
| 884 req_headers.insert(std::make_pair(header.name(), header.value())); |
| 885 } |
| 886 } else { |
| 887 entry->Doom(); |
| 888 } |
| 889 |
| 890 KeysProcessNextEntry(keys_context.Pass(), iter + 1); |
| 891 } |
| 892 |
| 718 } // namespace content | 893 } // namespace content |
| OLD | NEW |