blob: 1e5217876ea2e4ad15b7da5d8ff6842cc268998f [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/cache_storage/cache_storage_cache_entry_handler.h"
#include "base/guid.h"
#include "base/optional.h"
#include "content/browser/cache_storage/cache_storage_cache.h"
#include "content/browser/cache_storage/cache_storage_manager.h"
#include "storage/browser/blob/blob_data_builder.h"
#include "storage/browser/blob/blob_impl.h"
#include "storage/browser/blob/blob_storage_context.h"
#include "third_party/blink/public/common/blob/blob_utils.h"
namespace content {
CacheStorageCacheEntryHandler::BlobDataHandle::BlobDataHandle(
base::WeakPtr<CacheStorageCacheEntryHandler> entry_handler,
CacheStorageCacheHandle cache_handle,
disk_cache::ScopedEntryPtr entry)
: entry_handler_(std::move(entry_handler)),
cache_handle_(std::move(cache_handle)),
entry_(std::move(entry)) {}
bool CacheStorageCacheEntryHandler::BlobDataHandle::IsValid() {
return entry_ != nullptr;
}
void CacheStorageCacheEntryHandler::BlobDataHandle::Invalidate() {
cache_handle_ = base::nullopt;
entry_handler_ = nullptr;
entry_ = nullptr;
}
CacheStorageCacheEntryHandler::BlobDataHandle::~BlobDataHandle() {
if (entry_handler_)
entry_handler_->EraseBlobDataHandle(this);
}
PutContext::PutContext(std::unique_ptr<ServiceWorkerFetchRequest> request,
blink::mojom::FetchAPIResponsePtr response,
blink::mojom::BlobPtr blob,
uint64_t blob_size,
blink::mojom::BlobPtr side_data_blob,
uint64_t side_data_blob_size)
: request(std::move(request)),
response(std::move(response)),
blob(std::move(blob)),
blob_size(blob_size),
side_data_blob(std::move(side_data_blob)),
side_data_blob_size(side_data_blob_size) {}
PutContext::~PutContext() = default;
// Default implemetation of CacheStorageCacheEntryHandler.
class CacheStorageCacheEntryHandlerImpl : public CacheStorageCacheEntryHandler {
public:
CacheStorageCacheEntryHandlerImpl(
base::WeakPtr<storage::BlobStorageContext> blob_context)
: CacheStorageCacheEntryHandler(std::move(blob_context)) {}
~CacheStorageCacheEntryHandlerImpl() override = default;
std::unique_ptr<PutContext> CreatePutContext(
std::unique_ptr<ServiceWorkerFetchRequest> request,
blink::mojom::FetchAPIResponsePtr response) override {
blink::mojom::BlobPtr blob;
uint64_t blob_size = blink::BlobUtils::kUnknownSize;
blink::mojom::BlobPtr side_data_blob;
uint64_t side_data_blob_size = blink::BlobUtils::kUnknownSize;
if (response->blob) {
blob.Bind(std::move(response->blob->blob));
blob_size = response->blob->size;
}
if (response->side_data_blob) {
side_data_blob.Bind(std::move(response->side_data_blob->blob));
side_data_blob_size = response->side_data_blob->size;
}
return std::make_unique<PutContext>(
std::move(request), std::move(response), std::move(blob), blob_size,
std::move(side_data_blob), side_data_blob_size);
}
void PopulateResponseBody(CacheStorageCacheHandle handle,
disk_cache::ScopedEntryPtr entry,
blink::mojom::FetchAPIResponse* response) override {
// Create a blob with the response body data.
response->blob = blink::mojom::SerializedBlob::New();
response->blob->size =
entry->GetDataSize(CacheStorageCache::INDEX_RESPONSE_BODY);
response->blob->uuid = base::GenerateGUID();
auto blob_data =
std::make_unique<storage::BlobDataBuilder>(response->blob->uuid);
disk_cache::Entry* temp_entry = entry.get();
auto data_handle =
base::MakeRefCounted<CacheStorageCacheEntryHandler::BlobDataHandle>(
weak_ptr_factory_.GetWeakPtr(), std::move(handle),
std::move(entry));
blob_data_handles_.insert(data_handle.get());
blob_data->AppendDiskCacheEntryWithSideData(
std::move(data_handle), temp_entry,
CacheStorageCache::INDEX_RESPONSE_BODY,
CacheStorageCache::INDEX_SIDE_DATA);
auto blob_handle = blob_context_->AddFinishedBlob(std::move(blob_data));
storage::BlobImpl::Create(std::move(blob_handle),
MakeRequest(&response->blob->blob));
}
void PopulateRequestBody(CacheStorageCacheHandle handle,
disk_cache::ScopedEntryPtr entry,
blink::mojom::FetchAPIRequest* request) override {}
};
CacheStorageCacheEntryHandler::CacheStorageCacheEntryHandler(
base::WeakPtr<storage::BlobStorageContext> blob_context)
: blob_context_(blob_context), weak_ptr_factory_(this) {}
CacheStorageCacheEntryHandler::~CacheStorageCacheEntryHandler() = default;
void CacheStorageCacheEntryHandler::InvalidateBlobDataHandles() {
// Calling Invalidate() can cause the CacheStorageCacheEntryHandler to be
// destroyed. Be careful not to touch |this| after calling Invalidate().
std::set<BlobDataHandle*> handles = std::move(blob_data_handles_);
for (auto* handle : handles)
handle->Invalidate();
}
void CacheStorageCacheEntryHandler::EraseBlobDataHandle(
BlobDataHandle* handle) {
DCHECK_NE(blob_data_handles_.count(handle), 0u);
blob_data_handles_.erase(handle);
}
// static
std::unique_ptr<CacheStorageCacheEntryHandler>
CacheStorageCacheEntryHandler::CreateCacheEntryHandler(
CacheStorageOwner owner,
base::WeakPtr<storage::BlobStorageContext> blob_context) {
return std::make_unique<CacheStorageCacheEntryHandlerImpl>(
std::move(blob_context));
}
} // namespace content