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

Side by Side Diff: content/browser/cache_storage/cache_storage_cache.cc

Issue 1248003004: CacheStorage: Implement Cache.matchAll() (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 4 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/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"
11 #include "base/guid.h" 11 #include "base/guid.h"
12 #include "base/memory/scoped_vector.h"
12 #include "base/metrics/histogram_macros.h" 13 #include "base/metrics/histogram_macros.h"
13 #include "base/strings/string_split.h" 14 #include "base/strings/string_split.h"
14 #include "base/strings/string_util.h" 15 #include "base/strings/string_util.h"
15 #include "content/browser/cache_storage/cache_storage.pb.h" 16 #include "content/browser/cache_storage/cache_storage.pb.h"
16 #include "content/browser/cache_storage/cache_storage_blob_to_disk_cache.h" 17 #include "content/browser/cache_storage/cache_storage_blob_to_disk_cache.h"
17 #include "content/browser/cache_storage/cache_storage_scheduler.h" 18 #include "content/browser/cache_storage/cache_storage_scheduler.h"
18 #include "content/public/browser/browser_thread.h" 19 #include "content/public/browser/browser_thread.h"
19 #include "content/public/common/referrer.h" 20 #include "content/public/common/referrer.h"
20 #include "net/base/completion_callback.h" 21 #include "net/base/completion_callback.h"
21 #include "net/base/io_buffer.h" 22 #include "net/base/io_buffer.h"
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
171 if (!metadata->ParseFromArray(buffer->data(), buffer->size())) { 172 if (!metadata->ParseFromArray(buffer->data(), buffer->size())) {
172 callback.Run(scoped_ptr<CacheMetadata>()); 173 callback.Run(scoped_ptr<CacheMetadata>());
173 return; 174 return;
174 } 175 }
175 176
176 callback.Run(metadata.Pass()); 177 callback.Run(metadata.Pass());
177 } 178 }
178 179
179 } // namespace 180 } // namespace
180 181
182 // The state needed to pass between CacheStorageCache::MatchAll callbacks.
183 struct CacheStorageCache::MatchAllContext {
184 explicit MatchAllContext(const CacheStorageCache::ResponsesCallback& callback)
185 : original_callback(callback), enumerated_entry(nullptr) {}
186
187 ~MatchAllContext() {
188 for (disk_cache::Entry* entry_ptr : entries)
189 entry_ptr->Close();
190 if (enumerated_entry)
191 enumerated_entry->Close();
192 }
193
194 // The callback passed to the MatchAll() function.
195 CacheStorageCache::ResponsesCallback original_callback;
196
197 // The list of open entries in the backend.
198 std::list<disk_cache::Entry*> entries;
199
200 // The outputs of the MatchAll function.
201 std::vector<ServiceWorkerResponse> out_responses;
202 ScopedVector<storage::BlobDataHandle> out_blob_data_handles;
203
204 // Used for enumerating cache entries.
205 scoped_ptr<disk_cache::Backend::Iterator> backend_iterator;
206 disk_cache::Entry* enumerated_entry;
207
208 private:
209 DISALLOW_COPY_AND_ASSIGN(MatchAllContext);
210 };
211
181 // The state needed to pass between CacheStorageCache::Keys callbacks. 212 // The state needed to pass between CacheStorageCache::Keys callbacks.
182 struct CacheStorageCache::KeysContext { 213 struct CacheStorageCache::KeysContext {
183 explicit KeysContext(const CacheStorageCache::RequestsCallback& callback) 214 explicit KeysContext(const CacheStorageCache::RequestsCallback& callback)
184 : original_callback(callback), 215 : original_callback(callback),
185 out_keys(new CacheStorageCache::Requests()), 216 out_keys(new CacheStorageCache::Requests()),
186 enumerated_entry(NULL) {} 217 enumerated_entry(NULL) {}
187 218
188 ~KeysContext() { 219 ~KeysContext() {
189 for (size_t i = 0, max = entries.size(); i < max; ++i) 220 for (size_t i = 0, max = entries.size(); i < max; ++i)
190 entries[i]->Close(); 221 entries[i]->Close();
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 } 311 }
281 312
282 ResponseCallback pending_callback = 313 ResponseCallback pending_callback =
283 base::Bind(&CacheStorageCache::PendingResponseCallback, 314 base::Bind(&CacheStorageCache::PendingResponseCallback,
284 weak_ptr_factory_.GetWeakPtr(), callback); 315 weak_ptr_factory_.GetWeakPtr(), callback);
285 scheduler_->ScheduleOperation( 316 scheduler_->ScheduleOperation(
286 base::Bind(&CacheStorageCache::MatchImpl, weak_ptr_factory_.GetWeakPtr(), 317 base::Bind(&CacheStorageCache::MatchImpl, weak_ptr_factory_.GetWeakPtr(),
287 base::Passed(request.Pass()), pending_callback)); 318 base::Passed(request.Pass()), pending_callback));
288 } 319 }
289 320
321 void CacheStorageCache::MatchAll(const ResponsesCallback& callback) {
322 if (!LazyInitialize()) {
323 callback.Run(CACHE_STORAGE_ERROR_STORAGE,
324 std::vector<ServiceWorkerResponse>(),
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 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 589
543 disk_cache::Entry* temp_entry = entry.get(); 590 disk_cache::Entry* temp_entry = entry.get();
544 blob_data.AppendDiskCacheEntry( 591 blob_data.AppendDiskCacheEntry(
545 new CacheStorageCacheDataHandle(this, entry.Pass()), temp_entry, 592 new CacheStorageCacheDataHandle(this, entry.Pass()), temp_entry,
546 INDEX_RESPONSE_BODY); 593 INDEX_RESPONSE_BODY);
547 scoped_ptr<storage::BlobDataHandle> blob_data_handle( 594 scoped_ptr<storage::BlobDataHandle> blob_data_handle(
548 blob_storage_context_->AddFinishedBlob(&blob_data)); 595 blob_storage_context_->AddFinishedBlob(&blob_data));
549 callback.Run(CACHE_STORAGE_OK, response.Pass(), blob_data_handle.Pass()); 596 callback.Run(CACHE_STORAGE_OK, response.Pass(), blob_data_handle.Pass());
550 } 597 }
551 598
599 void CacheStorageCache::MatchAllImpl(const ResponsesCallback& callback) {
600 DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_);
601 if (backend_state_ != BACKEND_OPEN) {
602 callback.Run(CACHE_STORAGE_ERROR_STORAGE,
603 std::vector<ServiceWorkerResponse>(),
604 ScopedVector<storage::BlobDataHandle>());
605 return;
606 }
607
608 scoped_ptr<MatchAllContext> context(new MatchAllContext(callback));
609
610 context->backend_iterator = backend_->CreateIterator();
611 disk_cache::Backend::Iterator& iterator = *context->backend_iterator;
612 disk_cache::Entry** enumerated_entry = &context->enumerated_entry;
613
614 net::CompletionCallback open_entry_callback =
615 base::Bind(&CacheStorageCache::MatchAllDidOpenNextEntry,
616 weak_ptr_factory_.GetWeakPtr(), base::Passed(context.Pass()));
617
618 int rv = iterator.OpenNextEntry(enumerated_entry, open_entry_callback);
619
620 if (rv != net::ERR_IO_PENDING)
621 open_entry_callback.Run(rv);
622 }
623
624 void CacheStorageCache::MatchAllDidOpenNextEntry(
jkarlin 2015/08/04 13:25:07 This method should go, instead make a common utili
nhiroki 2015/08/05 08:03:04 Done.
625 scoped_ptr<MatchAllContext> context,
626 int rv) {
627 if (rv == net::ERR_FAILED) {
628 DCHECK(!context->enumerated_entry);
629 // Enumeration is complete, extract the requests from the entries.
630 MatchAllProcessNextEntry(context.Pass());
631 return;
632 }
633
634 if (rv < 0) {
635 context->original_callback.Run(CACHE_STORAGE_ERROR_STORAGE,
636 std::vector<ServiceWorkerResponse>(),
637 ScopedVector<storage::BlobDataHandle>());
638 return;
639 }
640
641 if (backend_state_ != BACKEND_OPEN) {
642 context->original_callback.Run(CACHE_STORAGE_ERROR_NOT_FOUND,
643 std::vector<ServiceWorkerResponse>(),
644 ScopedVector<storage::BlobDataHandle>());
645 return;
646 }
647
648 // Store the entry.
649 context->entries.push_back(context->enumerated_entry);
650 context->enumerated_entry = nullptr;
651
652 // Enumerate the next entry.
653 disk_cache::Backend::Iterator& iterator = *context->backend_iterator;
654 disk_cache::Entry** enumerated_entry = &context->enumerated_entry;
655 net::CompletionCallback open_entry_callback =
656 base::Bind(&CacheStorageCache::MatchAllDidOpenNextEntry,
657 weak_ptr_factory_.GetWeakPtr(), base::Passed(context.Pass()));
658
659 rv = iterator.OpenNextEntry(enumerated_entry, open_entry_callback);
660
661 if (rv != net::ERR_IO_PENDING)
662 open_entry_callback.Run(rv);
663 }
664
665 void CacheStorageCache::MatchAllProcessNextEntry(
666 scoped_ptr<MatchAllContext> context) {
667 if (context->entries.empty()) {
668 // All done. Return all of the responses.
669 context->original_callback.Run(CACHE_STORAGE_OK, context->out_responses,
670 context->out_blob_data_handles.Pass());
671 return;
672 }
673
674 disk_cache::ScopedEntryPtr entry(context->entries.front());
675 context->entries.pop_front();
676 disk_cache::Entry* entry_ptr = entry.get();
677 ReadMetadata(
678 entry_ptr,
679 base::Bind(&CacheStorageCache::MatchAllDidReadMetadata,
680 weak_ptr_factory_.GetWeakPtr(), base::Passed(context.Pass()),
681 base::Passed(entry.Pass())));
682 }
683
684 void CacheStorageCache::MatchAllDidReadMetadata(
685 scoped_ptr<MatchAllContext> context,
686 disk_cache::ScopedEntryPtr entry,
687 scoped_ptr<CacheMetadata> metadata) {
688 if (!metadata) {
689 entry->Doom();
690 MatchAllProcessNextEntry(context.Pass());
691 return;
692 }
693
694 ServiceWorkerResponse response(
jkarlin 2015/08/04 13:25:07 The code below should be combined with MatchDidRea
nhiroki 2015/08/05 08:03:04 Done.
695 GURL(metadata->response().url()), metadata->response().status_code(),
696 metadata->response().status_text(),
697 ProtoResponseTypeToWebResponseType(metadata->response().response_type()),
698 ServiceWorkerHeaderMap(), "", 0, GURL(),
699 blink::WebServiceWorkerResponseErrorUnknown);
700
701 for (int i = 0; i < metadata->response().headers_size(); ++i) {
702 const CacheHeaderMap header = metadata->response().headers(i);
703 DCHECK_EQ(std::string::npos, header.name().find('\0'));
704 DCHECK_EQ(std::string::npos, header.value().find('\0'));
705 response.headers.insert(std::make_pair(header.name(), header.value()));
706 }
707
708 ServiceWorkerHeaderMap cached_request_headers;
709 for (int i = 0; i < metadata->request().headers_size(); ++i) {
710 const CacheHeaderMap header = metadata->request().headers(i);
711 DCHECK_EQ(std::string::npos, header.name().find('\0'));
712 DCHECK_EQ(std::string::npos, header.value().find('\0'));
713 cached_request_headers[header.name()] = header.value();
714 }
715
716 if (entry->GetDataSize(INDEX_RESPONSE_BODY) == 0) {
717 context->out_responses.push_back(response);
718 context->out_blob_data_handles.push_back(nullptr);
719 MatchAllProcessNextEntry(context.Pass());
720 return;
721 }
722
723 if (!blob_storage_context_) {
724 entry->Doom();
725 MatchAllProcessNextEntry(context.Pass());
726 return;
727 }
728
729 // Create a blob with the response body data.
730 response.blob_size = entry->GetDataSize(INDEX_RESPONSE_BODY);
731 response.blob_uuid = base::GenerateGUID();
732 storage::BlobDataBuilder blob_data(response.blob_uuid);
733
734 disk_cache::Entry* entry_ptr = entry.get();
735 blob_data.AppendDiskCacheEntry(
736 new CacheStorageCacheDataHandle(this, entry.Pass()), entry_ptr,
737 INDEX_RESPONSE_BODY);
738 scoped_ptr<storage::BlobDataHandle> blob_data_handle(
739 blob_storage_context_->AddFinishedBlob(&blob_data));
740
741 context->out_responses.push_back(response);
742 context->out_blob_data_handles.push_back(blob_data_handle.release());
743 MatchAllProcessNextEntry(context.Pass());
744 }
745
552 void CacheStorageCache::Put(const CacheStorageBatchOperation& operation, 746 void CacheStorageCache::Put(const CacheStorageBatchOperation& operation,
553 const ErrorCallback& callback) { 747 const ErrorCallback& callback) {
554 DCHECK(BACKEND_OPEN == backend_state_ || initializing_); 748 DCHECK(BACKEND_OPEN == backend_state_ || initializing_);
555 DCHECK_EQ(CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT, operation.operation_type); 749 DCHECK_EQ(CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT, operation.operation_type);
556 750
557 scoped_ptr<ServiceWorkerFetchRequest> request(new ServiceWorkerFetchRequest( 751 scoped_ptr<ServiceWorkerFetchRequest> request(new ServiceWorkerFetchRequest(
558 operation.request.url, operation.request.method, 752 operation.request.url, operation.request.method,
559 operation.request.headers, operation.request.referrer, 753 operation.request.headers, operation.request.referrer,
560 operation.request.is_reload)); 754 operation.request.is_reload));
561 755
(...skipping 494 matching lines...) Expand 10 before | Expand all | Expand 10 after
1056 CacheStorageError error, 1250 CacheStorageError error,
1057 scoped_ptr<ServiceWorkerResponse> response, 1251 scoped_ptr<ServiceWorkerResponse> response,
1058 scoped_ptr<storage::BlobDataHandle> blob_data_handle) { 1252 scoped_ptr<storage::BlobDataHandle> blob_data_handle) {
1059 base::WeakPtr<CacheStorageCache> cache = weak_ptr_factory_.GetWeakPtr(); 1253 base::WeakPtr<CacheStorageCache> cache = weak_ptr_factory_.GetWeakPtr();
1060 1254
1061 callback.Run(error, response.Pass(), blob_data_handle.Pass()); 1255 callback.Run(error, response.Pass(), blob_data_handle.Pass());
1062 if (cache) 1256 if (cache)
1063 scheduler_->CompleteOperationAndRunNext(); 1257 scheduler_->CompleteOperationAndRunNext();
1064 } 1258 }
1065 1259
1260 void CacheStorageCache::PendingResponsesCallback(
1261 const ResponsesCallback& callback,
1262 CacheStorageError error,
1263 const std::vector<ServiceWorkerResponse>& responses,
1264 ScopedVector<storage::BlobDataHandle> blob_data_handles) {
1265 base::WeakPtr<CacheStorageCache> cache = weak_ptr_factory_.GetWeakPtr();
1266
1267 callback.Run(error, responses, blob_data_handles.Pass());
1268 if (cache)
1269 scheduler_->CompleteOperationAndRunNext();
1270 }
1271
1066 void CacheStorageCache::PendingRequestsCallback( 1272 void CacheStorageCache::PendingRequestsCallback(
1067 const RequestsCallback& callback, 1273 const RequestsCallback& callback,
1068 CacheStorageError error, 1274 CacheStorageError error,
1069 scoped_ptr<Requests> requests) { 1275 scoped_ptr<Requests> requests) {
1070 base::WeakPtr<CacheStorageCache> cache = weak_ptr_factory_.GetWeakPtr(); 1276 base::WeakPtr<CacheStorageCache> cache = weak_ptr_factory_.GetWeakPtr();
1071 1277
1072 callback.Run(error, requests.Pass()); 1278 callback.Run(error, requests.Pass());
1073 if (cache) 1279 if (cache)
1074 scheduler_->CompleteOperationAndRunNext(); 1280 scheduler_->CompleteOperationAndRunNext();
1075 } 1281 }
1076 1282
1077 } // namespace content 1283 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698