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 |