| 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/cache_storage/cache_storage_cache.h" | 5 #include "content/browser/cache_storage/cache_storage_cache.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/barrier_closure.h" | 9 #include "base/barrier_closure.h" |
| 10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 171 if (!metadata->ParseFromArray(buffer->data(), buffer->size())) { | 171 if (!metadata->ParseFromArray(buffer->data(), buffer->size())) { |
| 172 callback.Run(scoped_ptr<CacheMetadata>()); | 172 callback.Run(scoped_ptr<CacheMetadata>()); |
| 173 return; | 173 return; |
| 174 } | 174 } |
| 175 | 175 |
| 176 callback.Run(metadata.Pass()); | 176 callback.Run(metadata.Pass()); |
| 177 } | 177 } |
| 178 | 178 |
| 179 } // namespace | 179 } // namespace |
| 180 | 180 |
| 181 // The state needed to pass between CacheStorageCache::Keys callbacks. | 181 // The state needed to iterate all entries in the cache. |
| 182 struct CacheStorageCache::KeysContext { | 182 struct CacheStorageCache::OpenAllEntriesContext { |
| 183 explicit KeysContext(const CacheStorageCache::RequestsCallback& callback) | 183 OpenAllEntriesContext() : enumerated_entry(nullptr) {} |
| 184 : original_callback(callback), | 184 ~OpenAllEntriesContext() { |
| 185 out_keys(new CacheStorageCache::Requests()), | 185 for (size_t i = 0, max = entries.size(); i < max; ++i) { |
| 186 enumerated_entry(NULL) {} | 186 if (entries[i]) |
| 187 | 187 entries[i]->Close(); |
| 188 ~KeysContext() { | 188 } |
| 189 for (size_t i = 0, max = entries.size(); i < max; ++i) | |
| 190 entries[i]->Close(); | |
| 191 if (enumerated_entry) | 189 if (enumerated_entry) |
| 192 enumerated_entry->Close(); | 190 enumerated_entry->Close(); |
| 193 } | 191 } |
| 194 | 192 |
| 195 // The callback passed to the Keys() function. | |
| 196 CacheStorageCache::RequestsCallback original_callback; | |
| 197 | |
| 198 // The vector of open entries in the backend. | 193 // The vector of open entries in the backend. |
| 199 Entries entries; | 194 Entries entries; |
| 200 | 195 |
| 201 // The output of the Keys function. | |
| 202 scoped_ptr<CacheStorageCache::Requests> out_keys; | |
| 203 | |
| 204 // Used for enumerating cache entries. | 196 // Used for enumerating cache entries. |
| 205 scoped_ptr<disk_cache::Backend::Iterator> backend_iterator; | 197 scoped_ptr<disk_cache::Backend::Iterator> backend_iterator; |
| 206 disk_cache::Entry* enumerated_entry; | 198 disk_cache::Entry* enumerated_entry; |
| 207 | 199 |
| 208 private: | 200 private: |
| 201 DISALLOW_COPY_AND_ASSIGN(OpenAllEntriesContext); |
| 202 }; |
| 203 |
| 204 // The state needed to pass between CacheStorageCache::MatchAll callbacks. |
| 205 struct CacheStorageCache::MatchAllContext { |
| 206 explicit MatchAllContext(const CacheStorageCache::ResponsesCallback& callback) |
| 207 : original_callback(callback), out_responses(new Responses) {} |
| 208 ~MatchAllContext() {} |
| 209 |
| 210 // The callback passed to the MatchAll() function. |
| 211 CacheStorageCache::ResponsesCallback original_callback; |
| 212 |
| 213 // The outputs of the MatchAll function. |
| 214 scoped_ptr<Responses> out_responses; |
| 215 ScopedVector<storage::BlobDataHandle> out_blob_data_handles; |
| 216 |
| 217 // The context holding open entries. |
| 218 scoped_ptr<OpenAllEntriesContext> entries_context; |
| 219 |
| 220 private: |
| 221 DISALLOW_COPY_AND_ASSIGN(MatchAllContext); |
| 222 }; |
| 223 |
| 224 // The state needed to pass between CacheStorageCache::Keys callbacks. |
| 225 struct CacheStorageCache::KeysContext { |
| 226 explicit KeysContext(const CacheStorageCache::RequestsCallback& callback) |
| 227 : original_callback(callback), |
| 228 out_keys(new CacheStorageCache::Requests()) {} |
| 229 ~KeysContext() {} |
| 230 |
| 231 // The callback passed to the Keys() function. |
| 232 CacheStorageCache::RequestsCallback original_callback; |
| 233 |
| 234 // The output of the Keys function. |
| 235 scoped_ptr<CacheStorageCache::Requests> out_keys; |
| 236 |
| 237 // The context holding open entries. |
| 238 scoped_ptr<OpenAllEntriesContext> entries_context; |
| 239 |
| 240 private: |
| 209 DISALLOW_COPY_AND_ASSIGN(KeysContext); | 241 DISALLOW_COPY_AND_ASSIGN(KeysContext); |
| 210 }; | 242 }; |
| 211 | 243 |
| 212 // The state needed to pass between CacheStorageCache::Put callbacks. | 244 // The state needed to pass between CacheStorageCache::Put callbacks. |
| 213 struct CacheStorageCache::PutContext { | 245 struct CacheStorageCache::PutContext { |
| 214 PutContext( | 246 PutContext( |
| 215 const GURL& origin, | 247 const GURL& origin, |
| 216 scoped_ptr<ServiceWorkerFetchRequest> request, | 248 scoped_ptr<ServiceWorkerFetchRequest> request, |
| 217 scoped_ptr<ServiceWorkerResponse> response, | 249 scoped_ptr<ServiceWorkerResponse> response, |
| 218 scoped_ptr<storage::BlobDataHandle> blob_data_handle, | 250 scoped_ptr<storage::BlobDataHandle> blob_data_handle, |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 280 } | 312 } |
| 281 | 313 |
| 282 ResponseCallback pending_callback = | 314 ResponseCallback pending_callback = |
| 283 base::Bind(&CacheStorageCache::PendingResponseCallback, | 315 base::Bind(&CacheStorageCache::PendingResponseCallback, |
| 284 weak_ptr_factory_.GetWeakPtr(), callback); | 316 weak_ptr_factory_.GetWeakPtr(), callback); |
| 285 scheduler_->ScheduleOperation( | 317 scheduler_->ScheduleOperation( |
| 286 base::Bind(&CacheStorageCache::MatchImpl, weak_ptr_factory_.GetWeakPtr(), | 318 base::Bind(&CacheStorageCache::MatchImpl, weak_ptr_factory_.GetWeakPtr(), |
| 287 base::Passed(request.Pass()), pending_callback)); | 319 base::Passed(request.Pass()), pending_callback)); |
| 288 } | 320 } |
| 289 | 321 |
| 322 void CacheStorageCache::MatchAll(const ResponsesCallback& callback) { |
| 323 if (!LazyInitialize()) { |
| 324 callback.Run(CACHE_STORAGE_ERROR_STORAGE, scoped_ptr<Responses>(), |
| 325 ScopedVector<storage::BlobDataHandle>()); |
| 326 return; |
| 327 } |
| 328 |
| 329 ResponsesCallback pending_callback = |
| 330 base::Bind(&CacheStorageCache::PendingResponsesCallback, |
| 331 weak_ptr_factory_.GetWeakPtr(), callback); |
| 332 scheduler_->ScheduleOperation(base::Bind(&CacheStorageCache::MatchAllImpl, |
| 333 weak_ptr_factory_.GetWeakPtr(), |
| 334 pending_callback)); |
| 335 } |
| 336 |
| 290 void CacheStorageCache::BatchOperation( | 337 void CacheStorageCache::BatchOperation( |
| 291 const std::vector<CacheStorageBatchOperation>& operations, | 338 const std::vector<CacheStorageBatchOperation>& operations, |
| 292 const ErrorCallback& callback) { | 339 const ErrorCallback& callback) { |
| 293 if (!LazyInitialize()) { | 340 if (!LazyInitialize()) { |
| 294 callback.Run(CACHE_STORAGE_ERROR_STORAGE); | 341 callback.Run(CACHE_STORAGE_ERROR_STORAGE); |
| 295 return; | 342 return; |
| 296 } | 343 } |
| 297 | 344 |
| 298 scoped_ptr<ErrorCallback> callback_copy(new ErrorCallback(callback)); | 345 scoped_ptr<ErrorCallback> callback_copy(new ErrorCallback(callback)); |
| 299 ErrorCallback* callback_ptr = callback_copy.get(); | 346 ErrorCallback* callback_ptr = callback_copy.get(); |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 425 case BACKEND_CLOSED: | 472 case BACKEND_CLOSED: |
| 426 return false; | 473 return false; |
| 427 case BACKEND_OPEN: | 474 case BACKEND_OPEN: |
| 428 DCHECK(backend_); | 475 DCHECK(backend_); |
| 429 return true; | 476 return true; |
| 430 } | 477 } |
| 431 NOTREACHED(); | 478 NOTREACHED(); |
| 432 return false; | 479 return false; |
| 433 } | 480 } |
| 434 | 481 |
| 482 void CacheStorageCache::OpenAllEntries(const OpenAllEntriesCallback& callback) { |
| 483 scoped_ptr<OpenAllEntriesContext> entries_context(new OpenAllEntriesContext); |
| 484 entries_context->backend_iterator = backend_->CreateIterator(); |
| 485 disk_cache::Backend::Iterator& iterator = *entries_context->backend_iterator; |
| 486 disk_cache::Entry** enumerated_entry = &entries_context->enumerated_entry; |
| 487 |
| 488 net::CompletionCallback open_entry_callback = base::Bind( |
| 489 &CacheStorageCache::DidOpenNextEntry, weak_ptr_factory_.GetWeakPtr(), |
| 490 base::Passed(entries_context.Pass()), callback); |
| 491 |
| 492 int rv = iterator.OpenNextEntry(enumerated_entry, open_entry_callback); |
| 493 |
| 494 if (rv != net::ERR_IO_PENDING) |
| 495 open_entry_callback.Run(rv); |
| 496 } |
| 497 |
| 498 void CacheStorageCache::DidOpenNextEntry( |
| 499 scoped_ptr<OpenAllEntriesContext> entries_context, |
| 500 const OpenAllEntriesCallback& callback, |
| 501 int rv) { |
| 502 if (rv == net::ERR_FAILED) { |
| 503 DCHECK(!entries_context->enumerated_entry); |
| 504 // Enumeration is complete, extract the requests from the entries. |
| 505 callback.Run(entries_context.Pass(), CACHE_STORAGE_OK); |
| 506 return; |
| 507 } |
| 508 |
| 509 if (rv < 0) { |
| 510 callback.Run(entries_context.Pass(), CACHE_STORAGE_ERROR_STORAGE); |
| 511 return; |
| 512 } |
| 513 |
| 514 if (backend_state_ != BACKEND_OPEN) { |
| 515 callback.Run(entries_context.Pass(), CACHE_STORAGE_ERROR_NOT_FOUND); |
| 516 return; |
| 517 } |
| 518 |
| 519 // Store the entry. |
| 520 entries_context->entries.push_back(entries_context->enumerated_entry); |
| 521 entries_context->enumerated_entry = nullptr; |
| 522 |
| 523 // Enumerate the next entry. |
| 524 disk_cache::Backend::Iterator& iterator = *entries_context->backend_iterator; |
| 525 disk_cache::Entry** enumerated_entry = &entries_context->enumerated_entry; |
| 526 net::CompletionCallback open_entry_callback = base::Bind( |
| 527 &CacheStorageCache::DidOpenNextEntry, weak_ptr_factory_.GetWeakPtr(), |
| 528 base::Passed(entries_context.Pass()), callback); |
| 529 |
| 530 rv = iterator.OpenNextEntry(enumerated_entry, open_entry_callback); |
| 531 |
| 532 if (rv != net::ERR_IO_PENDING) |
| 533 open_entry_callback.Run(rv); |
| 534 } |
| 535 |
| 435 void CacheStorageCache::MatchImpl(scoped_ptr<ServiceWorkerFetchRequest> request, | 536 void CacheStorageCache::MatchImpl(scoped_ptr<ServiceWorkerFetchRequest> request, |
| 436 const ResponseCallback& callback) { | 537 const ResponseCallback& callback) { |
| 437 DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_); | 538 DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_); |
| 438 if (backend_state_ != BACKEND_OPEN) { | 539 if (backend_state_ != BACKEND_OPEN) { |
| 439 callback.Run(CACHE_STORAGE_ERROR_STORAGE, | 540 callback.Run(CACHE_STORAGE_ERROR_STORAGE, |
| 440 scoped_ptr<ServiceWorkerResponse>(), | 541 scoped_ptr<ServiceWorkerResponse>(), |
| 441 scoped_ptr<storage::BlobDataHandle>()); | 542 scoped_ptr<storage::BlobDataHandle>()); |
| 442 return; | 543 return; |
| 443 } | 544 } |
| 444 | 545 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 482 const ResponseCallback& callback, | 583 const ResponseCallback& callback, |
| 483 disk_cache::ScopedEntryPtr entry, | 584 disk_cache::ScopedEntryPtr entry, |
| 484 scoped_ptr<CacheMetadata> metadata) { | 585 scoped_ptr<CacheMetadata> metadata) { |
| 485 if (!metadata) { | 586 if (!metadata) { |
| 486 callback.Run(CACHE_STORAGE_ERROR_STORAGE, | 587 callback.Run(CACHE_STORAGE_ERROR_STORAGE, |
| 487 scoped_ptr<ServiceWorkerResponse>(), | 588 scoped_ptr<ServiceWorkerResponse>(), |
| 488 scoped_ptr<storage::BlobDataHandle>()); | 589 scoped_ptr<storage::BlobDataHandle>()); |
| 489 return; | 590 return; |
| 490 } | 591 } |
| 491 | 592 |
| 492 scoped_ptr<ServiceWorkerResponse> response(new ServiceWorkerResponse( | 593 scoped_ptr<ServiceWorkerResponse> response(new ServiceWorkerResponse); |
| 493 request->url, metadata->response().status_code(), | 594 PopulateResponseMetadata(*metadata, response.get()); |
| 494 metadata->response().status_text(), | |
| 495 ProtoResponseTypeToWebResponseType(metadata->response().response_type()), | |
| 496 ServiceWorkerHeaderMap(), "", 0, GURL(), | |
| 497 blink::WebServiceWorkerResponseErrorUnknown)); | |
| 498 | |
| 499 if (metadata->response().has_url()) | |
| 500 response->url = GURL(metadata->response().url()); | |
| 501 | |
| 502 for (int i = 0; i < metadata->response().headers_size(); ++i) { | |
| 503 const CacheHeaderMap header = metadata->response().headers(i); | |
| 504 DCHECK_EQ(std::string::npos, header.name().find('\0')); | |
| 505 DCHECK_EQ(std::string::npos, header.value().find('\0')); | |
| 506 response->headers.insert(std::make_pair(header.name(), header.value())); | |
| 507 } | |
| 508 | 595 |
| 509 ServiceWorkerHeaderMap cached_request_headers; | 596 ServiceWorkerHeaderMap cached_request_headers; |
| 510 for (int i = 0; i < metadata->request().headers_size(); ++i) { | 597 for (int i = 0; i < metadata->request().headers_size(); ++i) { |
| 511 const CacheHeaderMap header = metadata->request().headers(i); | 598 const CacheHeaderMap header = metadata->request().headers(i); |
| 512 DCHECK_EQ(std::string::npos, header.name().find('\0')); | 599 DCHECK_EQ(std::string::npos, header.name().find('\0')); |
| 513 DCHECK_EQ(std::string::npos, header.value().find('\0')); | 600 DCHECK_EQ(std::string::npos, header.value().find('\0')); |
| 514 cached_request_headers[header.name()] = header.value(); | 601 cached_request_headers[header.name()] = header.value(); |
| 515 } | 602 } |
| 516 | 603 |
| 517 if (!VaryMatches(request->headers, cached_request_headers, | 604 if (!VaryMatches(request->headers, cached_request_headers, |
| (...skipping 10 matching lines...) Expand all Loading... |
| 528 return; | 615 return; |
| 529 } | 616 } |
| 530 | 617 |
| 531 if (!blob_storage_context_) { | 618 if (!blob_storage_context_) { |
| 532 callback.Run(CACHE_STORAGE_ERROR_STORAGE, | 619 callback.Run(CACHE_STORAGE_ERROR_STORAGE, |
| 533 scoped_ptr<ServiceWorkerResponse>(), | 620 scoped_ptr<ServiceWorkerResponse>(), |
| 534 scoped_ptr<storage::BlobDataHandle>()); | 621 scoped_ptr<storage::BlobDataHandle>()); |
| 535 return; | 622 return; |
| 536 } | 623 } |
| 537 | 624 |
| 538 // Create a blob with the response body data. | 625 scoped_ptr<storage::BlobDataHandle> blob_data_handle = |
| 539 response->blob_size = entry->GetDataSize(INDEX_RESPONSE_BODY); | 626 PopulateResponseBody(entry.Pass(), response.get()); |
| 540 response->blob_uuid = base::GenerateGUID(); | 627 callback.Run(CACHE_STORAGE_OK, response.Pass(), blob_data_handle.Pass()); |
| 541 storage::BlobDataBuilder blob_data(response->blob_uuid); | 628 } |
| 542 | 629 |
| 543 disk_cache::Entry* temp_entry = entry.get(); | 630 void CacheStorageCache::MatchAllImpl(const ResponsesCallback& callback) { |
| 544 blob_data.AppendDiskCacheEntry( | 631 DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_); |
| 545 new CacheStorageCacheDataHandle(this, entry.Pass()), temp_entry, | 632 if (backend_state_ != BACKEND_OPEN) { |
| 546 INDEX_RESPONSE_BODY); | 633 callback.Run(CACHE_STORAGE_ERROR_STORAGE, scoped_ptr<Responses>(), |
| 547 scoped_ptr<storage::BlobDataHandle> blob_data_handle( | 634 ScopedVector<storage::BlobDataHandle>()); |
| 548 blob_storage_context_->AddFinishedBlob(&blob_data)); | 635 return; |
| 549 callback.Run(CACHE_STORAGE_OK, response.Pass(), blob_data_handle.Pass()); | 636 } |
| 637 |
| 638 OpenAllEntries(base::Bind(&CacheStorageCache::MatchAllDidOpenAllEntries, |
| 639 weak_ptr_factory_.GetWeakPtr(), callback)); |
| 640 } |
| 641 |
| 642 void CacheStorageCache::MatchAllDidOpenAllEntries( |
| 643 const ResponsesCallback& callback, |
| 644 scoped_ptr<OpenAllEntriesContext> entries_context, |
| 645 CacheStorageError error) { |
| 646 if (error != CACHE_STORAGE_OK) { |
| 647 callback.Run(error, scoped_ptr<Responses>(), |
| 648 ScopedVector<storage::BlobDataHandle>()); |
| 649 return; |
| 650 } |
| 651 |
| 652 scoped_ptr<MatchAllContext> context(new MatchAllContext(callback)); |
| 653 context->entries_context.swap(entries_context); |
| 654 Entries::iterator iter = context->entries_context->entries.begin(); |
| 655 MatchAllProcessNextEntry(context.Pass(), iter); |
| 656 } |
| 657 |
| 658 void CacheStorageCache::MatchAllProcessNextEntry( |
| 659 scoped_ptr<MatchAllContext> context, |
| 660 const Entries::iterator& iter) { |
| 661 if (iter == context->entries_context->entries.end()) { |
| 662 // All done. Return all of the responses. |
| 663 context->original_callback.Run(CACHE_STORAGE_OK, |
| 664 context->out_responses.Pass(), |
| 665 context->out_blob_data_handles.Pass()); |
| 666 return; |
| 667 } |
| 668 |
| 669 ReadMetadata(*iter, base::Bind(&CacheStorageCache::MatchAllDidReadMetadata, |
| 670 weak_ptr_factory_.GetWeakPtr(), |
| 671 base::Passed(context.Pass()), iter)); |
| 672 } |
| 673 |
| 674 void CacheStorageCache::MatchAllDidReadMetadata( |
| 675 scoped_ptr<MatchAllContext> context, |
| 676 const Entries::iterator& iter, |
| 677 scoped_ptr<CacheMetadata> metadata) { |
| 678 // Move ownership of the entry from the context. |
| 679 disk_cache::ScopedEntryPtr entry(*iter); |
| 680 *iter = nullptr; |
| 681 |
| 682 if (!metadata) { |
| 683 entry->Doom(); |
| 684 MatchAllProcessNextEntry(context.Pass(), iter + 1); |
| 685 return; |
| 686 } |
| 687 |
| 688 ServiceWorkerResponse response; |
| 689 PopulateResponseMetadata(*metadata, &response); |
| 690 |
| 691 if (entry->GetDataSize(INDEX_RESPONSE_BODY) == 0) { |
| 692 context->out_responses->push_back(response); |
| 693 context->out_blob_data_handles.push_back(nullptr); |
| 694 MatchAllProcessNextEntry(context.Pass(), iter + 1); |
| 695 return; |
| 696 } |
| 697 |
| 698 if (!blob_storage_context_) { |
| 699 context->original_callback.Run(CACHE_STORAGE_ERROR_STORAGE, |
| 700 scoped_ptr<Responses>(), |
| 701 ScopedVector<storage::BlobDataHandle>()); |
| 702 return; |
| 703 } |
| 704 |
| 705 scoped_ptr<storage::BlobDataHandle> blob_data_handle = |
| 706 PopulateResponseBody(entry.Pass(), &response); |
| 707 |
| 708 context->out_responses->push_back(response); |
| 709 context->out_blob_data_handles.push_back(blob_data_handle.release()); |
| 710 MatchAllProcessNextEntry(context.Pass(), iter + 1); |
| 550 } | 711 } |
| 551 | 712 |
| 552 void CacheStorageCache::Put(const CacheStorageBatchOperation& operation, | 713 void CacheStorageCache::Put(const CacheStorageBatchOperation& operation, |
| 553 const ErrorCallback& callback) { | 714 const ErrorCallback& callback) { |
| 554 DCHECK(BACKEND_OPEN == backend_state_ || initializing_); | 715 DCHECK(BACKEND_OPEN == backend_state_ || initializing_); |
| 555 DCHECK_EQ(CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT, operation.operation_type); | 716 DCHECK_EQ(CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT, operation.operation_type); |
| 556 | 717 |
| 557 scoped_ptr<ServiceWorkerFetchRequest> request(new ServiceWorkerFetchRequest( | 718 scoped_ptr<ServiceWorkerFetchRequest> request(new ServiceWorkerFetchRequest( |
| 558 operation.request.url, operation.request.method, | 719 operation.request.url, operation.request.method, |
| 559 operation.request.headers, operation.request.referrer, | 720 operation.request.headers, operation.request.referrer, |
| (...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 853 // 1. Iterate through all of the entries, open them, and add them to a vector. | 1014 // 1. Iterate through all of the entries, open them, and add them to a vector. |
| 854 // 2. For each open entry: | 1015 // 2. For each open entry: |
| 855 // 2.1. Read the headers into a protobuf. | 1016 // 2.1. Read the headers into a protobuf. |
| 856 // 2.2. Copy the protobuf into a ServiceWorkerFetchRequest (a "key"). | 1017 // 2.2. Copy the protobuf into a ServiceWorkerFetchRequest (a "key"). |
| 857 // 2.3. Push the response into a vector of requests to be returned. | 1018 // 2.3. Push the response into a vector of requests to be returned. |
| 858 // 3. Return the vector of requests (keys). | 1019 // 3. Return the vector of requests (keys). |
| 859 | 1020 |
| 860 // The entries have to be loaded into a vector first because enumeration loops | 1021 // The entries have to be loaded into a vector first because enumeration loops |
| 861 // forever if you read data from a cache entry while enumerating. | 1022 // forever if you read data from a cache entry while enumerating. |
| 862 | 1023 |
| 863 scoped_ptr<KeysContext> keys_context(new KeysContext(callback)); | 1024 OpenAllEntries(base::Bind(&CacheStorageCache::KeysDidOpenAllEntries, |
| 864 | 1025 weak_ptr_factory_.GetWeakPtr(), callback)); |
| 865 keys_context->backend_iterator = backend_->CreateIterator(); | |
| 866 disk_cache::Backend::Iterator& iterator = *keys_context->backend_iterator; | |
| 867 disk_cache::Entry** enumerated_entry = &keys_context->enumerated_entry; | |
| 868 | |
| 869 net::CompletionCallback open_entry_callback = base::Bind( | |
| 870 &CacheStorageCache::KeysDidOpenNextEntry, weak_ptr_factory_.GetWeakPtr(), | |
| 871 base::Passed(keys_context.Pass())); | |
| 872 | |
| 873 int rv = iterator.OpenNextEntry(enumerated_entry, open_entry_callback); | |
| 874 | |
| 875 if (rv != net::ERR_IO_PENDING) | |
| 876 open_entry_callback.Run(rv); | |
| 877 } | 1026 } |
| 878 | 1027 |
| 879 void CacheStorageCache::KeysDidOpenNextEntry( | 1028 void CacheStorageCache::KeysDidOpenAllEntries( |
| 880 scoped_ptr<KeysContext> keys_context, | 1029 const RequestsCallback& callback, |
| 881 int rv) { | 1030 scoped_ptr<OpenAllEntriesContext> entries_context, |
| 882 if (rv == net::ERR_FAILED) { | 1031 CacheStorageError error) { |
| 883 DCHECK(!keys_context->enumerated_entry); | 1032 if (error != CACHE_STORAGE_OK) { |
| 884 // Enumeration is complete, extract the requests from the entries. | 1033 callback.Run(error, scoped_ptr<Requests>()); |
| 885 Entries::iterator iter = keys_context->entries.begin(); | |
| 886 KeysProcessNextEntry(keys_context.Pass(), iter); | |
| 887 return; | 1034 return; |
| 888 } | 1035 } |
| 889 | 1036 |
| 890 if (rv < 0) { | 1037 scoped_ptr<KeysContext> keys_context(new KeysContext(callback)); |
| 891 keys_context->original_callback.Run(CACHE_STORAGE_ERROR_STORAGE, | 1038 keys_context->entries_context.swap(entries_context); |
| 892 scoped_ptr<Requests>()); | 1039 Entries::iterator iter = keys_context->entries_context->entries.begin(); |
| 893 return; | 1040 KeysProcessNextEntry(keys_context.Pass(), iter); |
| 894 } | |
| 895 | |
| 896 if (backend_state_ != BACKEND_OPEN) { | |
| 897 keys_context->original_callback.Run(CACHE_STORAGE_ERROR_NOT_FOUND, | |
| 898 scoped_ptr<Requests>()); | |
| 899 return; | |
| 900 } | |
| 901 | |
| 902 // Store the entry. | |
| 903 keys_context->entries.push_back(keys_context->enumerated_entry); | |
| 904 keys_context->enumerated_entry = NULL; | |
| 905 | |
| 906 // Enumerate the next entry. | |
| 907 disk_cache::Backend::Iterator& iterator = *keys_context->backend_iterator; | |
| 908 disk_cache::Entry** enumerated_entry = &keys_context->enumerated_entry; | |
| 909 net::CompletionCallback open_entry_callback = base::Bind( | |
| 910 &CacheStorageCache::KeysDidOpenNextEntry, weak_ptr_factory_.GetWeakPtr(), | |
| 911 base::Passed(keys_context.Pass())); | |
| 912 | |
| 913 rv = iterator.OpenNextEntry(enumerated_entry, open_entry_callback); | |
| 914 | |
| 915 if (rv != net::ERR_IO_PENDING) | |
| 916 open_entry_callback.Run(rv); | |
| 917 } | 1041 } |
| 918 | 1042 |
| 919 void CacheStorageCache::KeysProcessNextEntry( | 1043 void CacheStorageCache::KeysProcessNextEntry( |
| 920 scoped_ptr<KeysContext> keys_context, | 1044 scoped_ptr<KeysContext> keys_context, |
| 921 const Entries::iterator& iter) { | 1045 const Entries::iterator& iter) { |
| 922 if (iter == keys_context->entries.end()) { | 1046 if (iter == keys_context->entries_context->entries.end()) { |
| 923 // All done. Return all of the keys. | 1047 // All done. Return all of the keys. |
| 924 keys_context->original_callback.Run(CACHE_STORAGE_OK, | 1048 keys_context->original_callback.Run(CACHE_STORAGE_OK, |
| 925 keys_context->out_keys.Pass()); | 1049 keys_context->out_keys.Pass()); |
| 926 return; | 1050 return; |
| 927 } | 1051 } |
| 928 | 1052 |
| 929 ReadMetadata(*iter, base::Bind(&CacheStorageCache::KeysDidReadMetadata, | 1053 ReadMetadata(*iter, base::Bind(&CacheStorageCache::KeysDidReadMetadata, |
| 930 weak_ptr_factory_.GetWeakPtr(), | 1054 weak_ptr_factory_.GetWeakPtr(), |
| 931 base::Passed(keys_context.Pass()), iter)); | 1055 base::Passed(keys_context.Pass()), iter)); |
| 932 } | 1056 } |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1056 CacheStorageError error, | 1180 CacheStorageError error, |
| 1057 scoped_ptr<ServiceWorkerResponse> response, | 1181 scoped_ptr<ServiceWorkerResponse> response, |
| 1058 scoped_ptr<storage::BlobDataHandle> blob_data_handle) { | 1182 scoped_ptr<storage::BlobDataHandle> blob_data_handle) { |
| 1059 base::WeakPtr<CacheStorageCache> cache = weak_ptr_factory_.GetWeakPtr(); | 1183 base::WeakPtr<CacheStorageCache> cache = weak_ptr_factory_.GetWeakPtr(); |
| 1060 | 1184 |
| 1061 callback.Run(error, response.Pass(), blob_data_handle.Pass()); | 1185 callback.Run(error, response.Pass(), blob_data_handle.Pass()); |
| 1062 if (cache) | 1186 if (cache) |
| 1063 scheduler_->CompleteOperationAndRunNext(); | 1187 scheduler_->CompleteOperationAndRunNext(); |
| 1064 } | 1188 } |
| 1065 | 1189 |
| 1190 void CacheStorageCache::PendingResponsesCallback( |
| 1191 const ResponsesCallback& callback, |
| 1192 CacheStorageError error, |
| 1193 scoped_ptr<Responses> responses, |
| 1194 ScopedVector<storage::BlobDataHandle> blob_data_handles) { |
| 1195 base::WeakPtr<CacheStorageCache> cache = weak_ptr_factory_.GetWeakPtr(); |
| 1196 |
| 1197 callback.Run(error, responses.Pass(), blob_data_handles.Pass()); |
| 1198 if (cache) |
| 1199 scheduler_->CompleteOperationAndRunNext(); |
| 1200 } |
| 1201 |
| 1066 void CacheStorageCache::PendingRequestsCallback( | 1202 void CacheStorageCache::PendingRequestsCallback( |
| 1067 const RequestsCallback& callback, | 1203 const RequestsCallback& callback, |
| 1068 CacheStorageError error, | 1204 CacheStorageError error, |
| 1069 scoped_ptr<Requests> requests) { | 1205 scoped_ptr<Requests> requests) { |
| 1070 base::WeakPtr<CacheStorageCache> cache = weak_ptr_factory_.GetWeakPtr(); | 1206 base::WeakPtr<CacheStorageCache> cache = weak_ptr_factory_.GetWeakPtr(); |
| 1071 | 1207 |
| 1072 callback.Run(error, requests.Pass()); | 1208 callback.Run(error, requests.Pass()); |
| 1073 if (cache) | 1209 if (cache) |
| 1074 scheduler_->CompleteOperationAndRunNext(); | 1210 scheduler_->CompleteOperationAndRunNext(); |
| 1075 } | 1211 } |
| 1076 | 1212 |
| 1213 void CacheStorageCache::PopulateResponseMetadata( |
| 1214 const CacheMetadata& metadata, |
| 1215 ServiceWorkerResponse* response) { |
| 1216 *response = ServiceWorkerResponse( |
| 1217 GURL(metadata.response().url()), metadata.response().status_code(), |
| 1218 metadata.response().status_text(), |
| 1219 ProtoResponseTypeToWebResponseType(metadata.response().response_type()), |
| 1220 ServiceWorkerHeaderMap(), "", 0, GURL(), |
| 1221 blink::WebServiceWorkerResponseErrorUnknown); |
| 1222 |
| 1223 for (int i = 0; i < metadata.response().headers_size(); ++i) { |
| 1224 const CacheHeaderMap header = metadata.response().headers(i); |
| 1225 DCHECK_EQ(std::string::npos, header.name().find('\0')); |
| 1226 DCHECK_EQ(std::string::npos, header.value().find('\0')); |
| 1227 response->headers.insert(std::make_pair(header.name(), header.value())); |
| 1228 } |
| 1229 } |
| 1230 |
| 1231 scoped_ptr<storage::BlobDataHandle> CacheStorageCache::PopulateResponseBody( |
| 1232 disk_cache::ScopedEntryPtr entry, |
| 1233 ServiceWorkerResponse* response) { |
| 1234 DCHECK(blob_storage_context_); |
| 1235 |
| 1236 // Create a blob with the response body data. |
| 1237 response->blob_size = entry->GetDataSize(INDEX_RESPONSE_BODY); |
| 1238 response->blob_uuid = base::GenerateGUID(); |
| 1239 storage::BlobDataBuilder blob_data(response->blob_uuid); |
| 1240 |
| 1241 disk_cache::Entry* temp_entry = entry.get(); |
| 1242 blob_data.AppendDiskCacheEntry( |
| 1243 new CacheStorageCacheDataHandle(this, entry.Pass()), temp_entry, |
| 1244 INDEX_RESPONSE_BODY); |
| 1245 return blob_storage_context_->AddFinishedBlob(&blob_data); |
| 1246 } |
| 1247 |
| 1077 } // namespace content | 1248 } // namespace content |
| OLD | NEW |