| Index: content/browser/cache_storage/cache_storage_cache.cc
|
| diff --git a/content/browser/cache_storage/cache_storage_cache.cc b/content/browser/cache_storage/cache_storage_cache.cc
|
| index a9f6825ed39ebd1af956dcc581a64d4982492801..5c48906c9be5d90768dcd276d54c571e3c378f64 100644
|
| --- a/content/browser/cache_storage/cache_storage_cache.cc
|
| +++ b/content/browser/cache_storage/cache_storage_cache.cc
|
| @@ -214,33 +214,41 @@ struct CacheStorageCache::PutContext {
|
| DISALLOW_COPY_AND_ASSIGN(PutContext);
|
| };
|
|
|
| -struct CacheStorageCache::QueryCacheResults {
|
| - QueryCacheResults(std::unique_ptr<ServiceWorkerFetchRequest> request,
|
| +struct CacheStorageCache::QueryCacheResult {
|
| + explicit QueryCacheResult(base::Time entry_time) : entry_time(entry_time) {}
|
| +
|
| + std::unique_ptr<ServiceWorkerFetchRequest> request;
|
| + std::unique_ptr<ServiceWorkerResponse> response;
|
| + std::unique_ptr<storage::BlobDataHandle> blob_handle;
|
| + disk_cache::ScopedEntryPtr entry;
|
| + base::Time entry_time;
|
| +};
|
| +
|
| +struct CacheStorageCache::QueryCacheContext {
|
| + QueryCacheContext(std::unique_ptr<ServiceWorkerFetchRequest> request,
|
| const CacheStorageCacheQueryParams& options,
|
| - const QueryCacheResultsCallback& callback)
|
| + const QueryCacheCallback& callback)
|
| : request(std::move(request)),
|
| options(options),
|
| callback(callback),
|
| - out_requests(new Requests),
|
| - out_responses(new Responses),
|
| - out_blob_data_handles(new BlobDataHandles) {}
|
| + matches(base::MakeUnique<QueryCacheResults>()) {}
|
|
|
| + // Input to QueryCache
|
| std::unique_ptr<ServiceWorkerFetchRequest> request;
|
| CacheStorageCacheQueryParams options;
|
| - QueryCacheResultsCallback callback;
|
| + QueryCacheCallback callback;
|
| QueryCacheType query_type;
|
| size_t estimated_out_bytes = 0;
|
|
|
| - std::unique_ptr<Requests> out_requests;
|
| - std::unique_ptr<Responses> out_responses;
|
| - std::unique_ptr<BlobDataHandles> out_blob_data_handles;
|
| - std::vector<disk_cache::ScopedEntryPtr> out_entries;
|
| -
|
| + // Iteration state
|
| std::unique_ptr<disk_cache::Backend::Iterator> backend_iterator;
|
| disk_cache::Entry* enumerated_entry = nullptr;
|
|
|
| + // Output of QueryCache
|
| + std::unique_ptr<std::vector<QueryCacheResult>> matches;
|
| +
|
| private:
|
| - DISALLOW_COPY_AND_ASSIGN(QueryCacheResults);
|
| + DISALLOW_COPY_AND_ASSIGN(QueryCacheContext);
|
| };
|
|
|
| // static
|
| @@ -520,7 +528,7 @@ void CacheStorageCache::QueryCache(
|
| std::unique_ptr<ServiceWorkerFetchRequest> request,
|
| const CacheStorageCacheQueryParams& options,
|
| QueryCacheType query_type,
|
| - const QueryCacheResultsCallback& callback) {
|
| + const QueryCacheCallback& callback) {
|
| DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_);
|
| if (backend_state_ != BACKEND_OPEN) {
|
| callback.Run(CACHE_STORAGE_ERROR_STORAGE,
|
| @@ -530,25 +538,24 @@ void CacheStorageCache::QueryCache(
|
|
|
| if (!options.ignore_method && request && !request->method.empty() &&
|
| request->method != "GET") {
|
| - callback.Run(CACHE_STORAGE_OK, base::MakeUnique<QueryCacheResults>(
|
| - std::move(request), options, callback));
|
| + callback.Run(CACHE_STORAGE_OK, base::MakeUnique<QueryCacheResults>());
|
| return;
|
| }
|
|
|
| ServiceWorkerFetchRequest* request_ptr = request.get();
|
| - std::unique_ptr<QueryCacheResults> query_cache_results(
|
| - new QueryCacheResults(std::move(request), options, callback));
|
| - query_cache_results->query_type = query_type;
|
| + std::unique_ptr<QueryCacheContext> query_cache_context(
|
| + new QueryCacheContext(std::move(request), options, callback));
|
| + query_cache_context->query_type = query_type;
|
|
|
| - if (query_cache_results->request &&
|
| - !query_cache_results->request->url.is_empty() && !options.ignore_search) {
|
| + if (query_cache_context->request &&
|
| + !query_cache_context->request->url.is_empty() && !options.ignore_search) {
|
| // There is no need to scan the entire backend, just open the exact
|
| // URL.
|
| - disk_cache::Entry** entry_ptr = &query_cache_results->enumerated_entry;
|
| + disk_cache::Entry** entry_ptr = &query_cache_context->enumerated_entry;
|
| net::CompletionCallback open_entry_callback =
|
| base::Bind(&CacheStorageCache::QueryCacheDidOpenFastPath,
|
| weak_ptr_factory_.GetWeakPtr(),
|
| - base::Passed(std::move(query_cache_results)));
|
| + base::Passed(std::move(query_cache_context)));
|
| int rv = backend_->OpenEntry(request_ptr->url.spec(), entry_ptr,
|
| open_entry_callback);
|
| if (rv != net::ERR_IO_PENDING)
|
| @@ -556,38 +563,42 @@ void CacheStorageCache::QueryCache(
|
| return;
|
| }
|
|
|
| - query_cache_results->backend_iterator = backend_->CreateIterator();
|
| - QueryCacheOpenNextEntry(std::move(query_cache_results));
|
| + query_cache_context->backend_iterator = backend_->CreateIterator();
|
| + QueryCacheOpenNextEntry(std::move(query_cache_context));
|
| }
|
|
|
| void CacheStorageCache::QueryCacheDidOpenFastPath(
|
| - std::unique_ptr<QueryCacheResults> query_cache_results,
|
| + std::unique_ptr<QueryCacheContext> query_cache_context,
|
| int rv) {
|
| if (rv != net::OK) {
|
| - QueryCacheResults* results = query_cache_results.get();
|
| - results->callback.Run(CACHE_STORAGE_OK, std::move(query_cache_results));
|
| + QueryCacheContext* results = query_cache_context.get();
|
| + results->callback.Run(CACHE_STORAGE_OK,
|
| + std::move(query_cache_context->matches));
|
| return;
|
| }
|
| - QueryCacheFilterEntry(std::move(query_cache_results), rv);
|
| + QueryCacheFilterEntry(std::move(query_cache_context), rv);
|
| }
|
|
|
| void CacheStorageCache::QueryCacheOpenNextEntry(
|
| - std::unique_ptr<QueryCacheResults> query_cache_results) {
|
| - DCHECK_EQ(nullptr, query_cache_results->enumerated_entry);
|
| + std::unique_ptr<QueryCacheContext> query_cache_context) {
|
| + DCHECK_EQ(nullptr, query_cache_context->enumerated_entry);
|
|
|
| - if (!query_cache_results->backend_iterator) {
|
| + if (!query_cache_context->backend_iterator) {
|
| // Iteration is complete.
|
| - QueryCacheResultsCallback callback = query_cache_results->callback;
|
| - callback.Run(CACHE_STORAGE_OK, std::move(query_cache_results));
|
| + std::sort(query_cache_context->matches->begin(),
|
| + query_cache_context->matches->end(), QueryCacheResultCompare);
|
| +
|
| + query_cache_context->callback.Run(CACHE_STORAGE_OK,
|
| + std::move(query_cache_context->matches));
|
| return;
|
| }
|
|
|
| disk_cache::Backend::Iterator& iterator =
|
| - *query_cache_results->backend_iterator;
|
| - disk_cache::Entry** enumerated_entry = &query_cache_results->enumerated_entry;
|
| + *query_cache_context->backend_iterator;
|
| + disk_cache::Entry** enumerated_entry = &query_cache_context->enumerated_entry;
|
| net::CompletionCallback open_entry_callback = base::Bind(
|
| &CacheStorageCache::QueryCacheFilterEntry, weak_ptr_factory_.GetWeakPtr(),
|
| - base::Passed(std::move(query_cache_results)));
|
| + base::Passed(std::move(query_cache_context)));
|
|
|
| int rv = iterator.OpenNextEntry(enumerated_entry, open_entry_callback);
|
|
|
| @@ -596,42 +607,44 @@ void CacheStorageCache::QueryCacheOpenNextEntry(
|
| }
|
|
|
| void CacheStorageCache::QueryCacheFilterEntry(
|
| - std::unique_ptr<QueryCacheResults> query_cache_results,
|
| + std::unique_ptr<QueryCacheContext> query_cache_context,
|
| int rv) {
|
| if (rv == net::ERR_FAILED) {
|
| // This is the indicator that iteration is complete.
|
| - query_cache_results->backend_iterator.reset();
|
| - QueryCacheOpenNextEntry(std::move(query_cache_results));
|
| + query_cache_context->backend_iterator.reset();
|
| + QueryCacheOpenNextEntry(std::move(query_cache_context));
|
| return;
|
| }
|
|
|
| if (rv < 0) {
|
| - QueryCacheResultsCallback callback = query_cache_results->callback;
|
| - callback.Run(CACHE_STORAGE_ERROR_STORAGE, std::move(query_cache_results));
|
| + QueryCacheCallback callback = query_cache_context->callback;
|
| + callback.Run(CACHE_STORAGE_ERROR_STORAGE,
|
| + std::move(query_cache_context->matches));
|
| return;
|
| }
|
|
|
| - disk_cache::ScopedEntryPtr entry(query_cache_results->enumerated_entry);
|
| - query_cache_results->enumerated_entry = nullptr;
|
| + disk_cache::ScopedEntryPtr entry(query_cache_context->enumerated_entry);
|
| + query_cache_context->enumerated_entry = nullptr;
|
|
|
| if (backend_state_ != BACKEND_OPEN) {
|
| - QueryCacheResultsCallback callback = query_cache_results->callback;
|
| - callback.Run(CACHE_STORAGE_ERROR_NOT_FOUND, std::move(query_cache_results));
|
| + QueryCacheCallback callback = query_cache_context->callback;
|
| + callback.Run(CACHE_STORAGE_ERROR_NOT_FOUND,
|
| + std::move(query_cache_context->matches));
|
| return;
|
| }
|
|
|
| - if (query_cache_results->request &&
|
| - !query_cache_results->request->url.is_empty()) {
|
| - GURL requestURL = query_cache_results->request->url;
|
| + if (query_cache_context->request &&
|
| + !query_cache_context->request->url.is_empty()) {
|
| + GURL requestURL = query_cache_context->request->url;
|
| GURL cachedURL = GURL(entry->GetKey());
|
|
|
| - if (query_cache_results->options.ignore_search) {
|
| + if (query_cache_context->options.ignore_search) {
|
| requestURL = RemoveQueryParam(requestURL);
|
| cachedURL = RemoveQueryParam(cachedURL);
|
| }
|
|
|
| if (cachedURL != requestURL) {
|
| - QueryCacheOpenNextEntry(std::move(query_cache_results));
|
| + QueryCacheOpenNextEntry(std::move(query_cache_context));
|
| return;
|
| }
|
| }
|
| @@ -640,81 +653,99 @@ void CacheStorageCache::QueryCacheFilterEntry(
|
| ReadMetadata(entry_ptr,
|
| base::Bind(&CacheStorageCache::QueryCacheDidReadMetadata,
|
| weak_ptr_factory_.GetWeakPtr(),
|
| - base::Passed(std::move(query_cache_results)),
|
| + base::Passed(std::move(query_cache_context)),
|
| base::Passed(std::move(entry))));
|
| }
|
|
|
| void CacheStorageCache::QueryCacheDidReadMetadata(
|
| - std::unique_ptr<QueryCacheResults> query_cache_results,
|
| + std::unique_ptr<QueryCacheContext> query_cache_context,
|
| disk_cache::ScopedEntryPtr entry,
|
| std::unique_ptr<CacheMetadata> metadata) {
|
| if (!metadata) {
|
| entry->Doom();
|
| - QueryCacheOpenNextEntry(std::move(query_cache_results));
|
| + QueryCacheOpenNextEntry(std::move(query_cache_context));
|
| return;
|
| }
|
|
|
| - ServiceWorkerFetchRequest request;
|
| - PopulateRequestFromMetadata(*metadata, GURL(entry->GetKey()), &request);
|
| -
|
| - ServiceWorkerResponse response;
|
| - PopulateResponseMetadata(*metadata, &response);
|
| -
|
| - if (query_cache_results->request &&
|
| - !query_cache_results->options.ignore_vary &&
|
| - !VaryMatches(query_cache_results->request->headers, request.headers,
|
| - response.headers)) {
|
| - QueryCacheOpenNextEntry(std::move(query_cache_results));
|
| + // If the entry was created before we started adding entry times, then
|
| + // default to using the Response object's time for sorting purposes.
|
| + int64_t entry_time = metadata->has_entry_time()
|
| + ? metadata->entry_time()
|
| + : metadata->response().response_time();
|
| +
|
| + query_cache_context->matches->push_back(
|
| + QueryCacheResult(base::Time::FromInternalValue(entry_time)));
|
| + QueryCacheResult* match = &query_cache_context->matches->back();
|
| + match->request = base::MakeUnique<ServiceWorkerFetchRequest>();
|
| + match->response = base::MakeUnique<ServiceWorkerResponse>();
|
| + PopulateRequestFromMetadata(*metadata, GURL(entry->GetKey()),
|
| + match->request.get());
|
| + PopulateResponseMetadata(*metadata, match->response.get());
|
| +
|
| + if (query_cache_context->request &&
|
| + !query_cache_context->options.ignore_vary &&
|
| + !VaryMatches(query_cache_context->request->headers,
|
| + match->request->headers, match->response->headers)) {
|
| + query_cache_context->matches->pop_back();
|
| + QueryCacheOpenNextEntry(std::move(query_cache_context));
|
| return;
|
| }
|
|
|
| - if (query_cache_results->query_type == QueryCacheType::CACHE_ENTRIES) {
|
| - query_cache_results->out_entries.push_back(std::move(entry));
|
| - QueryCacheOpenNextEntry(std::move(query_cache_results));
|
| + if (query_cache_context->query_type == QueryCacheType::CACHE_ENTRIES) {
|
| + match->request.reset();
|
| + match->response.reset();
|
| + match->entry = std::move(entry);
|
| + QueryCacheOpenNextEntry(std::move(query_cache_context));
|
| return;
|
| }
|
|
|
| - query_cache_results->estimated_out_bytes += request.EstimatedStructSize();
|
| - if (query_cache_results->estimated_out_bytes > max_query_size_bytes_) {
|
| - query_cache_results->callback.Run(CACHE_STORAGE_ERROR_QUERY_TOO_LARGE,
|
| + query_cache_context->estimated_out_bytes +=
|
| + match->request->EstimatedStructSize();
|
| + if (query_cache_context->estimated_out_bytes > max_query_size_bytes_) {
|
| + query_cache_context->callback.Run(CACHE_STORAGE_ERROR_QUERY_TOO_LARGE,
|
| std::unique_ptr<QueryCacheResults>());
|
| return;
|
| }
|
|
|
| - query_cache_results->out_requests->push_back(request);
|
| - if (query_cache_results->query_type == QueryCacheType::REQUESTS) {
|
| - QueryCacheOpenNextEntry(std::move(query_cache_results));
|
| + if (query_cache_context->query_type == QueryCacheType::REQUESTS) {
|
| + match->response.reset();
|
| + QueryCacheOpenNextEntry(std::move(query_cache_context));
|
| return;
|
| }
|
|
|
| DCHECK_EQ(QueryCacheType::REQUESTS_AND_RESPONSES,
|
| - query_cache_results->query_type);
|
| + query_cache_context->query_type);
|
|
|
| - query_cache_results->estimated_out_bytes += response.EstimatedStructSize();
|
| - if (query_cache_results->estimated_out_bytes > max_query_size_bytes_) {
|
| - query_cache_results->callback.Run(CACHE_STORAGE_ERROR_QUERY_TOO_LARGE,
|
| + query_cache_context->estimated_out_bytes +=
|
| + match->response->EstimatedStructSize();
|
| + if (query_cache_context->estimated_out_bytes > max_query_size_bytes_) {
|
| + query_cache_context->callback.Run(CACHE_STORAGE_ERROR_QUERY_TOO_LARGE,
|
| std::unique_ptr<QueryCacheResults>());
|
| return;
|
| }
|
|
|
| if (entry->GetDataSize(INDEX_RESPONSE_BODY) == 0) {
|
| - query_cache_results->out_responses->push_back(response);
|
| - QueryCacheOpenNextEntry(std::move(query_cache_results));
|
| + QueryCacheOpenNextEntry(std::move(query_cache_context));
|
| return;
|
| }
|
|
|
| if (!blob_storage_context_) {
|
| - query_cache_results->callback.Run(CACHE_STORAGE_ERROR_STORAGE,
|
| - std::unique_ptr<QueryCacheResults>());
|
| + query_cache_context->callback.Run(CACHE_STORAGE_ERROR_STORAGE,
|
| + base::MakeUnique<QueryCacheResults>());
|
| return;
|
| }
|
|
|
| std::unique_ptr<storage::BlobDataHandle> blob_data_handle =
|
| - PopulateResponseBody(std::move(entry), &response);
|
| + PopulateResponseBody(std::move(entry), match->response.get());
|
| + match->blob_handle = std::move(blob_data_handle);
|
| +
|
| + QueryCacheOpenNextEntry(std::move(query_cache_context));
|
| +}
|
|
|
| - query_cache_results->out_responses->push_back(response);
|
| - query_cache_results->out_blob_data_handles->push_back(*blob_data_handle);
|
| - QueryCacheOpenNextEntry(std::move(query_cache_results));
|
| +// static
|
| +bool CacheStorageCache::QueryCacheResultCompare(const QueryCacheResult& lhs,
|
| + const QueryCacheResult& rhs) {
|
| + return lhs.entry_time < rhs.entry_time;
|
| }
|
|
|
| void CacheStorageCache::MatchImpl(
|
| @@ -747,15 +778,8 @@ void CacheStorageCache::MatchDidMatchAll(
|
| std::unique_ptr<ServiceWorkerResponse> response =
|
| base::MakeUnique<ServiceWorkerResponse>(match_all_responses->at(0));
|
|
|
| - std::unique_ptr<storage::BlobDataHandle> data_handle;
|
| - if (response->blob_size > 0) {
|
| - // NOTE: This assumes that MatchAll returns the handles in the same order
|
| - // as the responses.
|
| - data_handle =
|
| - base::MakeUnique<storage::BlobDataHandle>(match_all_handles->at(0));
|
| - }
|
| -
|
| - callback.Run(CACHE_STORAGE_OK, std::move(response), std::move(data_handle));
|
| + callback.Run(CACHE_STORAGE_OK, std::move(response),
|
| + std::move(match_all_handles->at(0)));
|
| }
|
|
|
| void CacheStorageCache::MatchAllImpl(
|
| @@ -785,8 +809,19 @@ void CacheStorageCache::MatchAllDidQueryCache(
|
| return;
|
| }
|
|
|
| - callback.Run(CACHE_STORAGE_OK, std::move(query_cache_results->out_responses),
|
| - std::move(query_cache_results->out_blob_data_handles));
|
| + std::unique_ptr<Responses> out_responses = base::MakeUnique<Responses>();
|
| + std::unique_ptr<BlobDataHandles> out_handles =
|
| + base::MakeUnique<BlobDataHandles>();
|
| + out_responses->reserve(query_cache_results->size());
|
| + out_handles->reserve(query_cache_results->size());
|
| +
|
| + for (auto& result : *query_cache_results) {
|
| + out_responses->push_back(*result.response);
|
| + out_handles->push_back(std::move(result.blob_handle));
|
| + }
|
| +
|
| + callback.Run(CACHE_STORAGE_OK, std::move(out_responses),
|
| + std::move(out_handles));
|
| }
|
|
|
| void CacheStorageCache::WriteSideDataDidGetQuota(
|
| @@ -1011,6 +1046,7 @@ void CacheStorageCache::PutDidCreateEntry(
|
| }
|
|
|
| CacheMetadata metadata;
|
| + metadata.set_entry_time(base::Time::Now().ToInternalValue());
|
| CacheRequest* request_metadata = metadata.mutable_request();
|
| request_metadata->set_method(put_context->request->method);
|
| for (ServiceWorkerHeaderMap::const_iterator it =
|
| @@ -1195,14 +1231,14 @@ void CacheStorageCache::DeleteDidQueryCache(
|
| return;
|
| }
|
|
|
| - if (query_cache_results->out_entries.empty()) {
|
| + if (query_cache_results->empty()) {
|
| callback.Run(CACHE_STORAGE_ERROR_NOT_FOUND);
|
| return;
|
| }
|
|
|
| - for (auto& entry : query_cache_results->out_entries) {
|
| + for (auto& result : *query_cache_results) {
|
| + disk_cache::ScopedEntryPtr entry = std::move(result.entry);
|
| entry->Doom();
|
| - entry.reset();
|
| }
|
|
|
| UpdateCacheSize();
|
| @@ -1233,7 +1269,12 @@ void CacheStorageCache::KeysDidQueryCache(
|
| return;
|
| }
|
|
|
| - callback.Run(CACHE_STORAGE_OK, std::move(query_cache_results->out_requests));
|
| + std::unique_ptr<Requests> out_requests = base::MakeUnique<Requests>();
|
| + out_requests->reserve(query_cache_results->size());
|
| + for (const auto& result : *query_cache_results)
|
| + out_requests->push_back(*result.request);
|
| +
|
| + callback.Run(CACHE_STORAGE_OK, std::move(out_requests));
|
| }
|
|
|
| void CacheStorageCache::CloseImpl(const base::Closure& callback) {
|
|
|