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

Unified Diff: content/browser/service_worker/service_worker_cache.cc

Issue 658583006: [ServiceWorkerCache] Make ServiceWorkerCache::Put guarantee callback like the header says (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 6 years, 2 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/browser/service_worker/service_worker_cache.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/browser/service_worker/service_worker_cache.cc
diff --git a/content/browser/service_worker/service_worker_cache.cc b/content/browser/service_worker/service_worker_cache.cc
index d893f019c610f9c159f704305e06ae0239c0779e..0882e9c6f890f7b92d3a9ac0c862c0d2262bf66c 100644
--- a/content/browser/service_worker/service_worker_cache.cc
+++ b/content/browser/service_worker/service_worker_cache.cc
@@ -94,167 +94,6 @@ struct ResponseReadContext {
DISALLOW_COPY_AND_ASSIGN(ResponseReadContext);
};
-// Streams data from a blob and writes it to a given disk_cache::Entry.
-class BlobReader : public net::URLRequest::Delegate {
- public:
- typedef base::Callback<void(disk_cache::ScopedEntryPtr, bool)>
- EntryAndBoolCallback;
-
- BlobReader()
- : cache_entry_offset_(0),
- buffer_(new net::IOBufferWithSize(kBufferSize)),
- weak_ptr_factory_(this) {}
-
- // |entry| is passed to the callback once complete.
- void StreamBlobToCache(disk_cache::ScopedEntryPtr entry,
- net::URLRequestContext* request_context,
- scoped_ptr<storage::BlobDataHandle> blob_data_handle,
- const EntryAndBoolCallback& callback) {
- DCHECK(entry);
- entry_ = entry.Pass();
- callback_ = callback;
- blob_request_ = storage::BlobProtocolHandler::CreateBlobRequest(
- blob_data_handle.Pass(), request_context, this);
- blob_request_->Start();
- }
-
- // net::URLRequest::Delegate overrides for reading blobs.
- void OnReceivedRedirect(net::URLRequest* request,
- const net::RedirectInfo& redirect_info,
- bool* defer_redirect) override {
- NOTREACHED();
- }
- void OnAuthRequired(net::URLRequest* request,
- net::AuthChallengeInfo* auth_info) override {
- NOTREACHED();
- }
- void OnCertificateRequested(
- net::URLRequest* request,
- net::SSLCertRequestInfo* cert_request_info) override {
- NOTREACHED();
- }
- void OnSSLCertificateError(net::URLRequest* request,
- const net::SSLInfo& ssl_info,
- bool fatal) override {
- NOTREACHED();
- }
- void OnBeforeNetworkStart(net::URLRequest* request, bool* defer) override {
- NOTREACHED();
- }
-
- void OnResponseStarted(net::URLRequest* request) override {
- if (!request->status().is_success()) {
- callback_.Run(entry_.Pass(), false);
- return;
- }
- ReadFromBlob();
- }
-
- virtual void ReadFromBlob() {
- int bytes_read = 0;
- bool done =
- blob_request_->Read(buffer_.get(), buffer_->size(), &bytes_read);
- if (done)
- OnReadCompleted(blob_request_.get(), bytes_read);
- }
-
- void OnReadCompleted(net::URLRequest* request, int bytes_read) override {
- if (!request->status().is_success()) {
- callback_.Run(entry_.Pass(), false);
- return;
- }
-
- if (bytes_read == 0) {
- callback_.Run(entry_.Pass(), true);
- return;
- }
-
- net::CompletionCallback cache_write_callback =
- base::Bind(&BlobReader::DidWriteDataToEntry,
- weak_ptr_factory_.GetWeakPtr(),
- bytes_read);
-
- int rv = entry_->WriteData(INDEX_RESPONSE_BODY,
- cache_entry_offset_,
- buffer_.get(),
- bytes_read,
- cache_write_callback,
- true /* truncate */);
- if (rv != net::ERR_IO_PENDING)
- cache_write_callback.Run(rv);
- }
-
- void DidWriteDataToEntry(int expected_bytes, int rv) {
- if (rv != expected_bytes) {
- callback_.Run(entry_.Pass(), false);
- return;
- }
-
- cache_entry_offset_ += rv;
- ReadFromBlob();
- }
-
- private:
- int cache_entry_offset_;
- disk_cache::ScopedEntryPtr entry_;
- scoped_ptr<net::URLRequest> blob_request_;
- EntryAndBoolCallback callback_;
- scoped_refptr<net::IOBufferWithSize> buffer_;
- base::WeakPtrFactory<BlobReader> weak_ptr_factory_;
-};
-
-// The state needed to pass between ServiceWorkerCache::Put callbacks.
-struct PutContext {
- PutContext(
- const GURL& origin,
- scoped_ptr<ServiceWorkerFetchRequest> request,
- scoped_ptr<ServiceWorkerResponse> response,
- scoped_ptr<storage::BlobDataHandle> blob_data_handle,
- const ServiceWorkerCache::ResponseCallback& callback,
- net::URLRequestContext* request_context,
- const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy)
- : origin(origin),
- request(request.Pass()),
- response(response.Pass()),
- blob_data_handle(blob_data_handle.Pass()),
- callback(callback),
- request_context(request_context),
- quota_manager_proxy(quota_manager_proxy),
- cache_entry(NULL) {}
- ~PutContext() {
- if (cache_entry)
- cache_entry->Close();
- }
-
- // Input parameters to the Put function.
- GURL origin;
- scoped_ptr<ServiceWorkerFetchRequest> request;
- scoped_ptr<ServiceWorkerResponse> response;
- scoped_ptr<storage::BlobDataHandle> blob_data_handle;
- ServiceWorkerCache::ResponseCallback callback;
- net::URLRequestContext* request_context;
- scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy;
-
- // This isn't a scoped_ptr because the disk_cache needs an Entry** as input to
- // CreateEntry.
- disk_cache::Entry* cache_entry;
-
- // The BlobDataHandle for the output ServiceWorkerResponse.
- scoped_ptr<storage::BlobDataHandle> out_blob_data_handle;
-
- DISALLOW_COPY_AND_ASSIGN(PutContext);
-};
-
-// Put callbacks
-void PutDidCreateEntry(scoped_ptr<PutContext> put_context, int rv);
-void PutDidWriteHeaders(scoped_ptr<PutContext> put_context,
- int expected_bytes,
- int rv);
-void PutDidWriteBlobToCache(scoped_ptr<PutContext> put_context,
- scoped_ptr<BlobReader> blob_reader,
- disk_cache::ScopedEntryPtr entry,
- bool success);
-
// Match callbacks
void MatchDidOpenEntry(scoped_ptr<ServiceWorkerFetchRequest> request,
const ServiceWorkerCache::ResponseCallback& callback,
@@ -305,148 +144,6 @@ void CreateBackendDidCreate(const ServiceWorkerCache::ErrorCallback& callback,
base::WeakPtr<ServiceWorkerCache> cache,
int rv);
-void PutDidCreateEntry(scoped_ptr<PutContext> put_context, int rv) {
- if (rv != net::OK) {
- put_context->callback.Run(ServiceWorkerCache::ErrorTypeExists,
- scoped_ptr<ServiceWorkerResponse>(),
- scoped_ptr<storage::BlobDataHandle>());
- return;
- }
-
- DCHECK(put_context->cache_entry);
-
- ServiceWorkerCacheMetadata metadata;
- ServiceWorkerCacheRequest* request_metadata = metadata.mutable_request();
- request_metadata->set_method(put_context->request->method);
- for (ServiceWorkerHeaderMap::const_iterator it =
- put_context->request->headers.begin();
- it != put_context->request->headers.end();
- ++it) {
- ServiceWorkerCacheHeaderMap* header_map = request_metadata->add_headers();
- header_map->set_name(it->first);
- header_map->set_value(it->second);
- }
-
- ServiceWorkerCacheResponse* response_metadata = metadata.mutable_response();
- response_metadata->set_status_code(put_context->response->status_code);
- response_metadata->set_status_text(put_context->response->status_text);
- response_metadata->set_response_type(
- WebResponseTypeToProtoResponseType(put_context->response->response_type));
- for (ServiceWorkerHeaderMap::const_iterator it =
- put_context->response->headers.begin();
- it != put_context->response->headers.end();
- ++it) {
- ServiceWorkerCacheHeaderMap* header_map = response_metadata->add_headers();
- header_map->set_name(it->first);
- header_map->set_value(it->second);
- }
-
- scoped_ptr<std::string> serialized(new std::string());
- if (!metadata.SerializeToString(serialized.get())) {
- put_context->callback.Run(ServiceWorkerCache::ErrorTypeStorage,
- scoped_ptr<ServiceWorkerResponse>(),
- scoped_ptr<storage::BlobDataHandle>());
- return;
- }
-
- scoped_refptr<net::StringIOBuffer> buffer(
- new net::StringIOBuffer(serialized.Pass()));
-
- // Get a temporary copy of the entry pointer before passing it in base::Bind.
- disk_cache::Entry* tmp_entry_ptr = put_context->cache_entry;
-
- net::CompletionCallback write_headers_callback = base::Bind(
- PutDidWriteHeaders, base::Passed(put_context.Pass()), buffer->size());
-
- rv = tmp_entry_ptr->WriteData(INDEX_HEADERS,
- 0 /* offset */,
- buffer.get(),
- buffer->size(),
- write_headers_callback,
- true /* truncate */);
-
- if (rv != net::ERR_IO_PENDING)
- write_headers_callback.Run(rv);
-}
-
-void PutDidWriteHeaders(scoped_ptr<PutContext> put_context,
- int expected_bytes,
- int rv) {
- if (rv != expected_bytes) {
- put_context->cache_entry->Doom();
- put_context->callback.Run(ServiceWorkerCache::ErrorTypeStorage,
- scoped_ptr<ServiceWorkerResponse>(),
- scoped_ptr<storage::BlobDataHandle>());
- return;
- }
-
- // The metadata is written, now for the response content. The data is streamed
- // from the blob into the cache entry.
-
- if (put_context->response->blob_uuid.empty()) {
- if (put_context->quota_manager_proxy.get()) {
- put_context->quota_manager_proxy->NotifyStorageModified(
- storage::QuotaClient::kServiceWorkerCache,
- put_context->origin,
- storage::kStorageTypeTemporary,
- put_context->cache_entry->GetDataSize(INDEX_HEADERS));
- }
-
- put_context->callback.Run(ServiceWorkerCache::ErrorTypeOK,
- put_context->response.Pass(),
- scoped_ptr<storage::BlobDataHandle>());
- return;
- }
-
- DCHECK(put_context->blob_data_handle);
-
- disk_cache::ScopedEntryPtr entry(put_context->cache_entry);
- put_context->cache_entry = NULL;
- scoped_ptr<BlobReader> reader(new BlobReader());
- BlobReader* reader_ptr = reader.get();
-
- // Grab some pointers before passing put_context in Bind.
- net::URLRequestContext* request_context = put_context->request_context;
- scoped_ptr<storage::BlobDataHandle> blob_data_handle =
- put_context->blob_data_handle.Pass();
-
- reader_ptr->StreamBlobToCache(entry.Pass(),
- request_context,
- blob_data_handle.Pass(),
- base::Bind(PutDidWriteBlobToCache,
- base::Passed(put_context.Pass()),
- base::Passed(reader.Pass())));
-}
-
-void PutDidWriteBlobToCache(scoped_ptr<PutContext> put_context,
- scoped_ptr<BlobReader> blob_reader,
- disk_cache::ScopedEntryPtr entry,
- bool success) {
- DCHECK(entry);
- put_context->cache_entry = entry.release();
-
- if (!success) {
- put_context->cache_entry->Doom();
- put_context->callback.Run(ServiceWorkerCache::ErrorTypeStorage,
- scoped_ptr<ServiceWorkerResponse>(),
- scoped_ptr<storage::BlobDataHandle>());
- return;
- }
-
- if (put_context->quota_manager_proxy.get()) {
- put_context->quota_manager_proxy->NotifyStorageModified(
- storage::QuotaClient::kServiceWorkerCache,
- put_context->origin,
- storage::kStorageTypeTemporary,
- put_context->cache_entry->GetDataSize(INDEX_HEADERS) +
- put_context->cache_entry->GetDataSize(INDEX_RESPONSE_BODY));
- }
-
- put_context->callback.Run(ServiceWorkerCache::ErrorTypeOK,
- put_context->response.Pass(),
- put_context->out_blob_data_handle.Pass());
-}
-
void MatchDidOpenEntry(scoped_ptr<ServiceWorkerFetchRequest> request,
const ServiceWorkerCache::ResponseCallback& callback,
base::WeakPtr<storage::BlobStorageContext> blob_storage,
@@ -728,31 +425,140 @@ void ReadMetadataDidReadMetadata(
return;
}
- scoped_ptr<ServiceWorkerCacheMetadata> metadata(
- new ServiceWorkerCacheMetadata());
+ scoped_ptr<ServiceWorkerCacheMetadata> metadata(
+ new ServiceWorkerCacheMetadata());
+
+ if (!metadata->ParseFromArray(buffer->data(), buffer->size())) {
+ callback.Run(scoped_ptr<ServiceWorkerCacheMetadata>());
+ return;
+ }
+
+ callback.Run(metadata.Pass());
+}
+
+void CreateBackendDidCreate(const ServiceWorkerCache::ErrorCallback& callback,
+ scoped_ptr<ScopedBackendPtr> backend_ptr,
+ base::WeakPtr<ServiceWorkerCache> cache,
+ int rv) {
+ if (rv != net::OK || !cache) {
+ callback.Run(ServiceWorkerCache::ErrorTypeStorage);
+ return;
+ }
+
+ cache->set_backend(backend_ptr->Pass());
+ callback.Run(ServiceWorkerCache::ErrorTypeOK);
+}
+
+} // namespace
+
+// Streams data from a blob and writes it to a given disk_cache::Entry.
+class ServiceWorkerCache::BlobReader : public net::URLRequest::Delegate {
+ public:
+ typedef base::Callback<void(disk_cache::ScopedEntryPtr, bool)>
+ EntryAndBoolCallback;
+
+ BlobReader()
+ : cache_entry_offset_(0),
+ buffer_(new net::IOBufferWithSize(kBufferSize)),
+ weak_ptr_factory_(this) {}
+
+ // |entry| is passed to the callback once complete.
+ void StreamBlobToCache(disk_cache::ScopedEntryPtr entry,
+ net::URLRequestContext* request_context,
+ scoped_ptr<storage::BlobDataHandle> blob_data_handle,
+ const EntryAndBoolCallback& callback) {
+ DCHECK(entry);
+ entry_ = entry.Pass();
+ callback_ = callback;
+ blob_request_ = storage::BlobProtocolHandler::CreateBlobRequest(
+ blob_data_handle.Pass(), request_context, this);
+ blob_request_->Start();
+ }
+
+ // net::URLRequest::Delegate overrides for reading blobs.
+ void OnReceivedRedirect(net::URLRequest* request,
+ const net::RedirectInfo& redirect_info,
+ bool* defer_redirect) override {
+ NOTREACHED();
+ }
+ void OnAuthRequired(net::URLRequest* request,
+ net::AuthChallengeInfo* auth_info) override {
+ NOTREACHED();
+ }
+ void OnCertificateRequested(
+ net::URLRequest* request,
+ net::SSLCertRequestInfo* cert_request_info) override {
+ NOTREACHED();
+ }
+ void OnSSLCertificateError(net::URLRequest* request,
+ const net::SSLInfo& ssl_info,
+ bool fatal) override {
+ NOTREACHED();
+ }
+ void OnBeforeNetworkStart(net::URLRequest* request, bool* defer) override {
+ NOTREACHED();
+ }
+
+ void OnResponseStarted(net::URLRequest* request) override {
+ if (!request->status().is_success()) {
+ callback_.Run(entry_.Pass(), false);
+ return;
+ }
+ ReadFromBlob();
+ }
+
+ virtual void ReadFromBlob() {
+ int bytes_read = 0;
+ bool done =
+ blob_request_->Read(buffer_.get(), buffer_->size(), &bytes_read);
+ if (done)
+ OnReadCompleted(blob_request_.get(), bytes_read);
+ }
+
+ void OnReadCompleted(net::URLRequest* request, int bytes_read) override {
+ if (!request->status().is_success()) {
+ callback_.Run(entry_.Pass(), false);
+ return;
+ }
+
+ if (bytes_read == 0) {
+ callback_.Run(entry_.Pass(), true);
+ return;
+ }
- if (!metadata->ParseFromArray(buffer->data(), buffer->size())) {
- callback.Run(scoped_ptr<ServiceWorkerCacheMetadata>());
- return;
+ net::CompletionCallback cache_write_callback =
+ base::Bind(&BlobReader::DidWriteDataToEntry,
+ weak_ptr_factory_.GetWeakPtr(),
+ bytes_read);
+
+ int rv = entry_->WriteData(INDEX_RESPONSE_BODY,
+ cache_entry_offset_,
+ buffer_.get(),
+ bytes_read,
+ cache_write_callback,
+ true /* truncate */);
+ if (rv != net::ERR_IO_PENDING)
+ cache_write_callback.Run(rv);
}
- callback.Run(metadata.Pass());
-}
+ void DidWriteDataToEntry(int expected_bytes, int rv) {
+ if (rv != expected_bytes) {
+ callback_.Run(entry_.Pass(), false);
+ return;
+ }
-void CreateBackendDidCreate(const ServiceWorkerCache::ErrorCallback& callback,
- scoped_ptr<ScopedBackendPtr> backend_ptr,
- base::WeakPtr<ServiceWorkerCache> cache,
- int rv) {
- if (rv != net::OK || !cache) {
- callback.Run(ServiceWorkerCache::ErrorTypeStorage);
- return;
+ cache_entry_offset_ += rv;
+ ReadFromBlob();
}
- cache->set_backend(backend_ptr->Pass());
- callback.Run(ServiceWorkerCache::ErrorTypeOK);
-}
-
-} // namespace
+ private:
+ int cache_entry_offset_;
+ disk_cache::ScopedEntryPtr entry_;
+ scoped_ptr<net::URLRequest> blob_request_;
+ EntryAndBoolCallback callback_;
+ scoped_refptr<net::IOBufferWithSize> buffer_;
+ base::WeakPtrFactory<BlobReader> weak_ptr_factory_;
+};
// The state needed to pass between ServiceWorkerCache::Keys callbacks.
struct ServiceWorkerCache::KeysContext {
@@ -789,6 +595,51 @@ struct ServiceWorkerCache::KeysContext {
DISALLOW_COPY_AND_ASSIGN(KeysContext);
};
+// The state needed to pass between ServiceWorkerCache::Put callbacks.
+struct ServiceWorkerCache::PutContext {
+ PutContext(
+ const GURL& origin,
+ scoped_ptr<ServiceWorkerFetchRequest> request,
+ scoped_ptr<ServiceWorkerResponse> response,
+ scoped_ptr<storage::BlobDataHandle> blob_data_handle,
+ const ServiceWorkerCache::ResponseCallback& callback,
+ base::WeakPtr<ServiceWorkerCache> cache,
+ net::URLRequestContext* request_context,
+ const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy)
+ : origin(origin),
+ request(request.Pass()),
+ response(response.Pass()),
+ blob_data_handle(blob_data_handle.Pass()),
+ callback(callback),
+ cache(cache),
+ request_context(request_context),
+ quota_manager_proxy(quota_manager_proxy),
+ cache_entry(NULL) {}
+ ~PutContext() {
+ if (cache_entry)
+ cache_entry->Close();
+ }
+
+ // Input parameters to the Put function.
+ GURL origin;
+ scoped_ptr<ServiceWorkerFetchRequest> request;
+ scoped_ptr<ServiceWorkerResponse> response;
+ scoped_ptr<storage::BlobDataHandle> blob_data_handle;
+ ServiceWorkerCache::ResponseCallback callback;
+ base::WeakPtr<ServiceWorkerCache> cache;
+ net::URLRequestContext* request_context;
+ scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy;
+
+ // This isn't a scoped_ptr because the disk_cache needs an Entry** as input to
+ // CreateEntry.
+ disk_cache::Entry* cache_entry;
+
+ // The BlobDataHandle for the output ServiceWorkerResponse.
+ scoped_ptr<storage::BlobDataHandle> out_blob_data_handle;
+
+ DISALLOW_COPY_AND_ASSIGN(PutContext);
+};
+
// static
scoped_refptr<ServiceWorkerCache> ServiceWorkerCache::CreateMemoryCache(
const GURL& origin,
@@ -842,12 +693,25 @@ void ServiceWorkerCache::Put(scoped_ptr<ServiceWorkerFetchRequest> request,
}
}
+ scoped_ptr<PutContext> put_context(
+ new PutContext(origin_,
+ request.Pass(),
+ response.Pass(),
+ blob_data_handle.Pass(),
+ callback,
+ weak_ptr_factory_.GetWeakPtr(),
+ request_context_,
+ quota_manager_proxy_));
+
+ if (put_context->blob_data_handle) {
+ // Grab another handle to the blob for the callback response.
+ put_context->out_blob_data_handle =
+ blob_storage_context_->GetBlobDataFromUUID(
+ put_context->response->blob_uuid);
+ }
+
base::Closure continuation = base::Bind(&ServiceWorkerCache::PutImpl,
- weak_ptr_factory_.GetWeakPtr(),
- base::Passed(request.Pass()),
- base::Passed(response.Pass()),
- base::Passed(blob_data_handle.Pass()),
- callback);
+ base::Passed(put_context.Pass()));
if (!initialized_) {
Init(continuation);
@@ -1011,44 +875,174 @@ ServiceWorkerCache::ServiceWorkerCache(
weak_ptr_factory_(this) {
}
-void ServiceWorkerCache::PutImpl(
- scoped_ptr<ServiceWorkerFetchRequest> request,
- scoped_ptr<ServiceWorkerResponse> response,
- scoped_ptr<storage::BlobDataHandle> blob_data_handle,
- const ResponseCallback& callback) {
- if (!backend_) {
- callback.Run(ErrorTypeStorage,
- scoped_ptr<ServiceWorkerResponse>(),
- scoped_ptr<storage::BlobDataHandle>());
+// static
+void ServiceWorkerCache::PutImpl(scoped_ptr<PutContext> put_context) {
+ if (!put_context->cache || !put_context->cache->backend_) {
+ put_context->callback.Run(ErrorTypeStorage,
+ scoped_ptr<ServiceWorkerResponse>(),
+ scoped_ptr<storage::BlobDataHandle>());
return;
}
- scoped_ptr<PutContext> put_context(new PutContext(origin_,
- request.Pass(),
- response.Pass(),
- blob_data_handle.Pass(),
- callback,
- request_context_,
- quota_manager_proxy_));
-
- if (put_context->blob_data_handle) {
- // Grab another handle to the blob for the callback response.
- put_context->out_blob_data_handle =
- blob_storage_context_->GetBlobDataFromUUID(
- put_context->response->blob_uuid);
- }
-
disk_cache::Entry** entry_ptr = &put_context->cache_entry;
ServiceWorkerFetchRequest* request_ptr = put_context->request.get();
+ disk_cache::Backend* backend_ptr = put_context->cache->backend_.get();
net::CompletionCallback create_entry_callback =
base::Bind(PutDidCreateEntry, base::Passed(put_context.Pass()));
- int rv = backend_->CreateEntry(
+ int create_rv = backend_ptr->CreateEntry(
request_ptr->url.spec(), entry_ptr, create_entry_callback);
+ if (create_rv != net::ERR_IO_PENDING)
+ create_entry_callback.Run(create_rv);
+}
+
+// static
+void ServiceWorkerCache::PutDidCreateEntry(scoped_ptr<PutContext> put_context,
+ int rv) {
+ if (rv != net::OK) {
+ put_context->callback.Run(ServiceWorkerCache::ErrorTypeExists,
+ scoped_ptr<ServiceWorkerResponse>(),
+ scoped_ptr<storage::BlobDataHandle>());
+ return;
+ }
+
+ DCHECK(put_context->cache_entry);
+
+ ServiceWorkerCacheMetadata metadata;
+ ServiceWorkerCacheRequest* request_metadata = metadata.mutable_request();
+ request_metadata->set_method(put_context->request->method);
+ for (ServiceWorkerHeaderMap::const_iterator it =
+ put_context->request->headers.begin();
+ it != put_context->request->headers.end();
+ ++it) {
+ ServiceWorkerCacheHeaderMap* header_map = request_metadata->add_headers();
+ header_map->set_name(it->first);
+ header_map->set_value(it->second);
+ }
+
+ ServiceWorkerCacheResponse* response_metadata = metadata.mutable_response();
+ response_metadata->set_status_code(put_context->response->status_code);
+ response_metadata->set_status_text(put_context->response->status_text);
+ response_metadata->set_response_type(
+ WebResponseTypeToProtoResponseType(put_context->response->response_type));
+ for (ServiceWorkerHeaderMap::const_iterator it =
+ put_context->response->headers.begin();
+ it != put_context->response->headers.end();
+ ++it) {
+ ServiceWorkerCacheHeaderMap* header_map = response_metadata->add_headers();
+ header_map->set_name(it->first);
+ header_map->set_value(it->second);
+ }
+
+ scoped_ptr<std::string> serialized(new std::string());
+ if (!metadata.SerializeToString(serialized.get())) {
+ put_context->callback.Run(ServiceWorkerCache::ErrorTypeStorage,
+ scoped_ptr<ServiceWorkerResponse>(),
+ scoped_ptr<storage::BlobDataHandle>());
+ return;
+ }
+
+ scoped_refptr<net::StringIOBuffer> buffer(
+ new net::StringIOBuffer(serialized.Pass()));
+
+ // Get a temporary copy of the entry pointer before passing it in base::Bind.
+ disk_cache::Entry* tmp_entry_ptr = put_context->cache_entry;
+
+ net::CompletionCallback write_headers_callback = base::Bind(
+ PutDidWriteHeaders, base::Passed(put_context.Pass()), buffer->size());
+
+ rv = tmp_entry_ptr->WriteData(INDEX_HEADERS,
+ 0 /* offset */,
+ buffer.get(),
+ buffer->size(),
+ write_headers_callback,
+ true /* truncate */);
+
if (rv != net::ERR_IO_PENDING)
- create_entry_callback.Run(rv);
+ write_headers_callback.Run(rv);
+}
+
+// static
+void ServiceWorkerCache::PutDidWriteHeaders(scoped_ptr<PutContext> put_context,
+ int expected_bytes,
+ int rv) {
+ if (rv != expected_bytes) {
+ put_context->cache_entry->Doom();
+ put_context->callback.Run(ServiceWorkerCache::ErrorTypeStorage,
+ scoped_ptr<ServiceWorkerResponse>(),
+ scoped_ptr<storage::BlobDataHandle>());
+ return;
+ }
+
+ // The metadata is written, now for the response content. The data is streamed
+ // from the blob into the cache entry.
+
+ if (put_context->response->blob_uuid.empty()) {
+ if (put_context->quota_manager_proxy.get()) {
+ put_context->quota_manager_proxy->NotifyStorageModified(
+ storage::QuotaClient::kServiceWorkerCache,
+ put_context->origin,
+ storage::kStorageTypeTemporary,
+ put_context->cache_entry->GetDataSize(INDEX_HEADERS));
+ }
+
+ put_context->callback.Run(ServiceWorkerCache::ErrorTypeOK,
+ put_context->response.Pass(),
+ scoped_ptr<storage::BlobDataHandle>());
+ return;
+ }
+
+ DCHECK(put_context->blob_data_handle);
+
+ disk_cache::ScopedEntryPtr entry(put_context->cache_entry);
+ put_context->cache_entry = NULL;
+ scoped_ptr<BlobReader> reader(new BlobReader());
+ BlobReader* reader_ptr = reader.get();
+
+ // Grab some pointers before passing put_context in Bind.
+ net::URLRequestContext* request_context = put_context->request_context;
+ scoped_ptr<storage::BlobDataHandle> blob_data_handle =
+ put_context->blob_data_handle.Pass();
+
+ reader_ptr->StreamBlobToCache(entry.Pass(),
+ request_context,
+ blob_data_handle.Pass(),
+ base::Bind(PutDidWriteBlobToCache,
+ base::Passed(put_context.Pass()),
+ base::Passed(reader.Pass())));
+}
+
+// static
+void ServiceWorkerCache::PutDidWriteBlobToCache(
+ scoped_ptr<PutContext> put_context,
+ scoped_ptr<BlobReader> blob_reader,
+ disk_cache::ScopedEntryPtr entry,
+ bool success) {
+ DCHECK(entry);
+ put_context->cache_entry = entry.release();
+
+ if (!success) {
+ put_context->cache_entry->Doom();
+ put_context->callback.Run(ServiceWorkerCache::ErrorTypeStorage,
+ scoped_ptr<ServiceWorkerResponse>(),
+ scoped_ptr<storage::BlobDataHandle>());
+ return;
+ }
+
+ if (put_context->quota_manager_proxy.get()) {
+ put_context->quota_manager_proxy->NotifyStorageModified(
+ storage::QuotaClient::kServiceWorkerCache,
+ put_context->origin,
+ storage::kStorageTypeTemporary,
+ put_context->cache_entry->GetDataSize(INDEX_HEADERS) +
+ put_context->cache_entry->GetDataSize(INDEX_RESPONSE_BODY));
+ }
+
+ put_context->callback.Run(ServiceWorkerCache::ErrorTypeOK,
+ put_context->response.Pass(),
+ put_context->out_blob_data_handle.Pass());
}
// static
« no previous file with comments | « content/browser/service_worker/service_worker_cache.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698