16e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 26e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 36e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// found in the LICENSE file. 46e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 56e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "content/browser/service_worker/service_worker_cache.h" 66e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 76e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include <string> 86e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 96e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/files/file_path.h" 101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/guid.h" 111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/message_loop/message_loop_proxy.h" 121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/strings/string_util.h" 131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/browser/service_worker/service_worker_cache.pb.h" 141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/public/browser/browser_thread.h" 151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "net/base/io_buffer.h" 161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "net/base/net_errors.h" 171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "net/disk_cache/disk_cache.h" 186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "net/url_request/url_request_context.h" 191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/blob/blob_data_handle.h" 201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/blob/blob_storage_context.h" 211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/blob/blob_url_request_job_factory.h" 226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)namespace content { 246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace { 261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccitypedef scoped_ptr<disk_cache::Backend> ScopedBackendPtr; 281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccitypedef base::Callback<void(bool)> BoolCallback; 291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccitypedef base::Callback<void(disk_cache::ScopedEntryPtr, bool)> 301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EntryBoolCallback; 311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccitypedef base::Callback<void(scoped_ptr<ServiceWorkerRequestResponseHeaders>)> 321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci HeadersCallback; 331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccienum EntryIndex { INDEX_HEADERS = 0, INDEX_RESPONSE_BODY }; 351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// The maximum size of an individual cache. Ultimately cache size is controlled 371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// per-origin. 381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst int kMaxCacheBytes = 512 * 1024 * 1024; 391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Buffer size for cache and blob reading/writing. 411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst int kBufferSize = 1024 * 512; 421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccistruct ResponseReadContext { 441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ResponseReadContext(scoped_refptr<net::IOBufferWithSize> buff, 451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_refptr<storage::BlobData> blob) 461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci : buffer(buff), blob_data(blob), total_bytes_read(0) {} 471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_refptr<net::IOBufferWithSize> buffer; 491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_refptr<storage::BlobData> blob_data; 501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int total_bytes_read; 511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DISALLOW_COPY_AND_ASSIGN(ResponseReadContext); 531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}; 541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Streams data from a blob and writes it to a given disk_cache::Entry. 561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass BlobReader : public net::URLRequest::Delegate { 571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci public: 581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci typedef base::Callback<void(disk_cache::ScopedEntryPtr, bool)> 591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EntryBoolCallback; 601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci BlobReader(disk_cache::ScopedEntryPtr entry) 621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci : cache_entry_offset_(0), 631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci buffer_(new net::IOBufferWithSize(kBufferSize)), 641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci weak_ptr_factory_(this) { 651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(entry); 661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci entry_ = entry.Pass(); 671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void StreamBlobToCache(net::URLRequestContext* request_context, 701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<storage::BlobDataHandle> blob_data_handle, 711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const EntryBoolCallback& callback) { 721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback_ = callback; 731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci blob_request_ = storage::BlobProtocolHandler::CreateBlobRequest( 741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci blob_data_handle.Pass(), request_context, this); 751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci blob_request_->Start(); 761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // net::URLRequest::Delegate overrides for reading blobs. 791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual void OnReceivedRedirect(net::URLRequest* request, 801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const net::RedirectInfo& redirect_info, 811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool* defer_redirect) OVERRIDE { 821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NOTREACHED(); 831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual void OnAuthRequired(net::URLRequest* request, 851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci net::AuthChallengeInfo* auth_info) OVERRIDE { 861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NOTREACHED(); 871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual void OnCertificateRequested( 891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci net::URLRequest* request, 901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci net::SSLCertRequestInfo* cert_request_info) OVERRIDE { 911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NOTREACHED(); 921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual void OnSSLCertificateError(net::URLRequest* request, 941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const net::SSLInfo& ssl_info, 951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool fatal) OVERRIDE { 961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NOTREACHED(); 971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual void OnBeforeNetworkStart(net::URLRequest* request, 991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool* defer) OVERRIDE { 1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NOTREACHED(); 1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual void OnResponseStarted(net::URLRequest* request) OVERRIDE { 1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!request->status().is_success()) { 1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback_.Run(entry_.Pass(), false); 1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ReadFromBlob(); 1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual void ReadFromBlob() { 1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int bytes_read = 0; 1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool done = 1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci blob_request_->Read(buffer_.get(), buffer_->size(), &bytes_read); 1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (done) 1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci OnReadCompleted(blob_request_.get(), bytes_read); 1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual void OnReadCompleted(net::URLRequest* request, 1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int bytes_read) OVERRIDE { 1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!request->status().is_success()) { 1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback_.Run(entry_.Pass(), false); 1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (bytes_read == 0) { 1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback_.Run(entry_.Pass(), true); 1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci net::CompletionCallback cache_write_callback = 1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&BlobReader::DidWriteDataToEntry, 1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci weak_ptr_factory_.GetWeakPtr(), 1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bytes_read); 1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int rv = entry_->WriteData(INDEX_RESPONSE_BODY, 1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci cache_entry_offset_, 1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci buffer_.get(), 1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bytes_read, 1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci cache_write_callback, 1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci true /* truncate */); 1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (rv != net::ERR_IO_PENDING) 1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci cache_write_callback.Run(rv); 1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void DidWriteDataToEntry(int expected_bytes, int rv) { 1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (rv != expected_bytes) { 1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback_.Run(entry_.Pass(), false); 1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci cache_entry_offset_ += rv; 1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ReadFromBlob(); 1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci private: 1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int cache_entry_offset_; 1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci disk_cache::ScopedEntryPtr entry_; 1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<net::URLRequest> blob_request_; 1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EntryBoolCallback callback_; 1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_refptr<net::IOBufferWithSize> buffer_; 1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::WeakPtrFactory<BlobReader> weak_ptr_factory_; 1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}; 1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Put callbacks 1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid PutDidCreateEntry(scoped_ptr<ServiceWorkerFetchRequest> request, 1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<ServiceWorkerResponse> response, 1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const ServiceWorkerCache::ErrorCallback& callback, 1691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<disk_cache::Entry*> entryptr, 1701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<storage::BlobDataHandle> blob_data_handle, 1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci net::URLRequestContext* request_context, 1721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int rv); 1731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid PutDidWriteHeaders(scoped_ptr<ServiceWorkerResponse> response, 1741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const ServiceWorkerCache::ErrorCallback& callback, 1751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci disk_cache::ScopedEntryPtr entry, 1761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<storage::BlobDataHandle> blob_data_handle, 1771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci net::URLRequestContext* request_context, 1781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int expected_bytes, 1791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int rv); 1801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid PutDidWriteBlobToCache(const ServiceWorkerCache::ErrorCallback& callback, 1811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<BlobReader> blob_reader, 1821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci disk_cache::ScopedEntryPtr entry, 1831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool success); 1841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Match callbacks 1861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid MatchDidOpenEntry(scoped_ptr<ServiceWorkerFetchRequest> request, 1871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const ServiceWorkerCache::ResponseCallback& callback, 1881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::WeakPtr<storage::BlobStorageContext> blob_storage, 1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<disk_cache::Entry*> entryptr, 1901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int rv); 1911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid MatchDidReadHeaderData( 1921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<ServiceWorkerFetchRequest> request, 1931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const ServiceWorkerCache::ResponseCallback& callback, 1941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::WeakPtr<storage::BlobStorageContext> blob_storage, 1951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci disk_cache::ScopedEntryPtr entry, 1961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<ServiceWorkerRequestResponseHeaders> headers); 1971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid MatchDidReadResponseBodyData( 1981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<ServiceWorkerFetchRequest> request, 1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const ServiceWorkerCache::ResponseCallback& callback, 2001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::WeakPtr<storage::BlobStorageContext> blob_storage, 2011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci disk_cache::ScopedEntryPtr entry, 2021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<ServiceWorkerResponse> response, 2031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<ResponseReadContext> response_context, 2041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int rv); 2051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid MatchDoneWithBody(scoped_ptr<ServiceWorkerFetchRequest> request, 2061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const ServiceWorkerCache::ResponseCallback& callback, 2071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::WeakPtr<storage::BlobStorageContext> blob_storage, 2081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<ServiceWorkerResponse> response, 2091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<ResponseReadContext> response_context); 2101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Delete callbacks 2121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid DeleteDidOpenEntry(scoped_ptr<ServiceWorkerFetchRequest> request, 2131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const ServiceWorkerCache::ErrorCallback& callback, 2141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<disk_cache::Entry*> entryptr, 2151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int rv); 2161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Copy headers out of a cache entry and into a protobuf. The callback is 2181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// guaranteed to be run. 2191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ReadHeaders(disk_cache::Entry* entry, const HeadersCallback& callback); 2201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ReadHeadersDidReadHeaderData( 2211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci disk_cache::Entry* entry, 2221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const HeadersCallback& callback, 2231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const scoped_refptr<net::IOBufferWithSize>& buffer, 2241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int rv); 2251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// CreateBackend callbacks 2271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid CreateBackendDidCreate(const ServiceWorkerCache::ErrorCallback& callback, 2281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<ScopedBackendPtr> backend_ptr, 2291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::WeakPtr<ServiceWorkerCache> cache, 2301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int rv); 2311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid PutDidCreateEntry(scoped_ptr<ServiceWorkerFetchRequest> request, 2331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<ServiceWorkerResponse> response, 2341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const ServiceWorkerCache::ErrorCallback& callback, 2351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<disk_cache::Entry*> entryptr, 2361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<storage::BlobDataHandle> blob_data_handle, 2371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci net::URLRequestContext* request_context, 2381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int rv) { 2391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (rv != net::OK) { 2401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback.Run(ServiceWorkerCache::ErrorTypeExists); 2411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 2421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(entryptr); 2451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci disk_cache::ScopedEntryPtr entry(*entryptr); 2461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ServiceWorkerRequestResponseHeaders headers; 2481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci headers.set_method(request->method); 2491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci headers.set_status_code(response->status_code); 2511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci headers.set_status_text(response->status_text); 2521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for (ServiceWorkerHeaderMap::const_iterator it = request->headers.begin(); 2531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci it != request->headers.end(); 2541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ++it) { 2551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ServiceWorkerRequestResponseHeaders::HeaderMap* header_map = 2561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci headers.add_request_headers(); 2571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci header_map->set_name(it->first); 2581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci header_map->set_value(it->second); 2591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for (ServiceWorkerHeaderMap::const_iterator it = response->headers.begin(); 2621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci it != response->headers.end(); 2631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ++it) { 2641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ServiceWorkerRequestResponseHeaders::HeaderMap* header_map = 2651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci headers.add_response_headers(); 2661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci header_map->set_name(it->first); 2671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci header_map->set_value(it->second); 2681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<std::string> serialized(new std::string()); 2711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!headers.SerializeToString(serialized.get())) { 2721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback.Run(ServiceWorkerCache::ErrorTypeStorage); 2731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 2741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_refptr<net::StringIOBuffer> buffer( 2771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new net::StringIOBuffer(serialized.Pass())); 2781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Get a temporary copy of the entry pointer before passing it in base::Bind. 2801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci disk_cache::Entry* tmp_entry_ptr = entry.get(); 2811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci net::CompletionCallback write_headers_callback = 2831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(PutDidWriteHeaders, 2841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Passed(response.Pass()), 2851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback, 2861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Passed(entry.Pass()), 2871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Passed(blob_data_handle.Pass()), 2881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci request_context, 2891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci buffer->size()); 2901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci rv = tmp_entry_ptr->WriteData(INDEX_HEADERS, 2921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 0 /* offset */, 2931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci buffer.get(), 2941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci buffer->size(), 2951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci write_headers_callback, 2961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci true /* truncate */); 2971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (rv != net::ERR_IO_PENDING) 2991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci write_headers_callback.Run(rv); 3001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 3011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid PutDidWriteHeaders(scoped_ptr<ServiceWorkerResponse> response, 3031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const ServiceWorkerCache::ErrorCallback& callback, 3041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci disk_cache::ScopedEntryPtr entry, 3051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<storage::BlobDataHandle> blob_data_handle, 3061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci net::URLRequestContext* request_context, 3071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int expected_bytes, 3081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int rv) { 3091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (rv != expected_bytes) { 3101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci entry->Doom(); 3111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback.Run(ServiceWorkerCache::ErrorTypeStorage); 3121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 3131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 3141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // The metadata is written, now for the response content. The data is streamed 3161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // from the blob into the cache entry. 3171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (response->blob_uuid.empty()) { 3191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback.Run(ServiceWorkerCache::ErrorTypeOK); 3201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 3211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 3221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(blob_data_handle); 3241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<BlobReader> reader(new BlobReader(entry.Pass())); 3261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci BlobReader* reader_ptr = reader.get(); 3271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci reader_ptr->StreamBlobToCache( 3291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci request_context, 3301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci blob_data_handle.Pass(), 3311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind( 3321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PutDidWriteBlobToCache, callback, base::Passed(reader.Pass()))); 3331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 3341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid PutDidWriteBlobToCache(const ServiceWorkerCache::ErrorCallback& callback, 3361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<BlobReader> blob_reader, 3371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci disk_cache::ScopedEntryPtr entry, 3381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool success) { 3391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!success) { 3401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci entry->Doom(); 3411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback.Run(ServiceWorkerCache::ErrorTypeStorage); 3421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 3431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 3441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback.Run(ServiceWorkerCache::ErrorTypeOK); 3461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 3471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid MatchDidOpenEntry(scoped_ptr<ServiceWorkerFetchRequest> request, 3491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const ServiceWorkerCache::ResponseCallback& callback, 3501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::WeakPtr<storage::BlobStorageContext> blob_storage, 3511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<disk_cache::Entry*> entryptr, 3521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int rv) { 3531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (rv != net::OK) { 3541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback.Run(ServiceWorkerCache::ErrorTypeNotFound, 3551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<ServiceWorkerResponse>(), 3561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<storage::BlobDataHandle>()); 3571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 3581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 3591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(entryptr); 3611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci disk_cache::ScopedEntryPtr entry(*entryptr); 3621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Copy the entry pointer before passing it in base::Bind. 3641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci disk_cache::Entry* tmp_entry_ptr = entry.get(); 3651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci HeadersCallback headers_callback = base::Bind(MatchDidReadHeaderData, 3671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Passed(request.Pass()), 3681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback, 3691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci blob_storage, 3701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Passed(entry.Pass())); 3711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ReadHeaders(tmp_entry_ptr, headers_callback); 3731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 3741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool VaryMatches(const ServiceWorkerHeaderMap& request, 3761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const ServiceWorkerHeaderMap& cached_request, 3771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const ServiceWorkerHeaderMap& response) { 3781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ServiceWorkerHeaderMap::const_iterator vary_iter = response.find("vary"); 3791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (vary_iter == response.end()) 3801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return true; 3811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::vector<std::string> vary_keys; 3831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Tokenize(vary_iter->second, ",", &vary_keys); 3841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for (std::vector<std::string>::const_iterator it = vary_keys.begin(); 3851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci it != vary_keys.end(); 3861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ++it) { 3871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::string trimmed; 3881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::TrimWhitespaceASCII(*it, base::TRIM_ALL, &trimmed); 3891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (trimmed == "*") 3901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return false; 3911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ServiceWorkerHeaderMap::const_iterator request_iter = request.find(trimmed); 3931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ServiceWorkerHeaderMap::const_iterator cached_request_iter = 3941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci cached_request.find(trimmed); 3951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // If the header exists in one but not the other, no match. 3971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if ((request_iter == request.end()) != 3981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci (cached_request_iter == cached_request.end())) 3991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return false; 4001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // If the header exists in one, it exists in both. Verify that the values 4021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // are equal. 4031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (request_iter != request.end() && 4041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci request_iter->second != cached_request_iter->second) 4051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return false; 4061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 4071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return true; 4091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 4101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid MatchDidReadHeaderData( 4121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<ServiceWorkerFetchRequest> request, 4131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const ServiceWorkerCache::ResponseCallback& callback, 4141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::WeakPtr<storage::BlobStorageContext> blob_storage, 4151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci disk_cache::ScopedEntryPtr entry, 4161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<ServiceWorkerRequestResponseHeaders> headers) { 4171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!headers) { 4181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback.Run(ServiceWorkerCache::ErrorTypeStorage, 4191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<ServiceWorkerResponse>(), 4201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<storage::BlobDataHandle>()); 4211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 4221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 4231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<ServiceWorkerResponse> response( 4251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new ServiceWorkerResponse(request->url, 4261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci headers->status_code(), 4271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci headers->status_text(), 4281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ServiceWorkerHeaderMap(), 4291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci "")); 4301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for (int i = 0; i < headers->response_headers_size(); ++i) { 4321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const ServiceWorkerRequestResponseHeaders::HeaderMap header = 4331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci headers->response_headers(i); 4341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci response->headers.insert(std::make_pair(header.name(), header.value())); 4351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 4361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ServiceWorkerHeaderMap cached_request_headers; 4381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for (int i = 0; i < headers->request_headers_size(); ++i) { 4391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const ServiceWorkerRequestResponseHeaders::HeaderMap header = 4401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci headers->request_headers(i); 4411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci cached_request_headers[header.name()] = header.value(); 4421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 4431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!VaryMatches( 4451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci request->headers, cached_request_headers, response->headers)) { 4461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback.Run(ServiceWorkerCache::ErrorTypeNotFound, 4471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<ServiceWorkerResponse>(), 4481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<storage::BlobDataHandle>()); 4491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 4501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 4511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (entry->GetDataSize(INDEX_RESPONSE_BODY) == 0) { 4531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback.Run(ServiceWorkerCache::ErrorTypeOK, 4541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci response.Pass(), 4551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<storage::BlobDataHandle>()); 4561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 4571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 4581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Stream the response body into a blob. 4601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!blob_storage) { 4611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback.Run(ServiceWorkerCache::ErrorTypeStorage, 4621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<ServiceWorkerResponse>(), 4631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<storage::BlobDataHandle>()); 4641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 4651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 4661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci response->blob_uuid = base::GenerateGUID(); 4681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_refptr<storage::BlobData> blob_data = 4701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new storage::BlobData(response->blob_uuid); 4711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_refptr<net::IOBufferWithSize> response_body_buffer( 4721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new net::IOBufferWithSize(kBufferSize)); 4731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<ResponseReadContext> read_context( 4751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new ResponseReadContext(response_body_buffer, blob_data)); 4761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Copy the entry pointer before passing it in base::Bind. 4781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci disk_cache::Entry* tmp_entry_ptr = entry.get(); 4791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci net::CompletionCallback read_callback = 4811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(MatchDidReadResponseBodyData, 4821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Passed(request.Pass()), 4831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback, 4841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci blob_storage, 4851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Passed(entry.Pass()), 4861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Passed(response.Pass()), 4871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Passed(read_context.Pass())); 4881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int read_rv = tmp_entry_ptr->ReadData(INDEX_RESPONSE_BODY, 4901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 0, 4911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci response_body_buffer.get(), 4921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci response_body_buffer->size(), 4931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci read_callback); 4941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (read_rv != net::ERR_IO_PENDING) 4961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci read_callback.Run(read_rv); 4971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 4981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid MatchDidReadResponseBodyData( 5001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<ServiceWorkerFetchRequest> request, 5011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const ServiceWorkerCache::ResponseCallback& callback, 5021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::WeakPtr<storage::BlobStorageContext> blob_storage, 5031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci disk_cache::ScopedEntryPtr entry, 5041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<ServiceWorkerResponse> response, 5051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<ResponseReadContext> response_context, 5061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int rv) { 5071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (rv < 0) { 5081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback.Run(ServiceWorkerCache::ErrorTypeStorage, 5091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<ServiceWorkerResponse>(), 5101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<storage::BlobDataHandle>()); 5111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 5121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 5131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 5141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (rv == 0) { 5151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MatchDoneWithBody(request.Pass(), 5161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback, 5171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci blob_storage, 5181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci response.Pass(), 5191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci response_context.Pass()); 5201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 5211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 5221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 5231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // TODO(jkarlin): This copying of the the entire cache response into memory is 5241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // awful. Create a new interface around SimpleCache that provides access the 5251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // data directly from the file. See bug http://crbug.com/403493. 5261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci response_context->blob_data->AppendData(response_context->buffer->data(), rv); 5271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci response_context->total_bytes_read += rv; 5281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int total_bytes_read = response_context->total_bytes_read; 5291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 5301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Grab some pointers before passing them in bind. 5311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci net::IOBufferWithSize* buffer = response_context->buffer.get(); 5321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci disk_cache::Entry* tmp_entry_ptr = entry.get(); 5331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 5341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci net::CompletionCallback read_callback = 5351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(MatchDidReadResponseBodyData, 5361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Passed(request.Pass()), 5371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback, 5381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci blob_storage, 5391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Passed(entry.Pass()), 5401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Passed(response.Pass()), 5411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Passed(response_context.Pass())); 5421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 5431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int read_rv = tmp_entry_ptr->ReadData(INDEX_RESPONSE_BODY, 5441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci total_bytes_read, 5451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci buffer, 5461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci buffer->size(), 5471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci read_callback); 5481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 5491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (read_rv != net::ERR_IO_PENDING) 5501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci read_callback.Run(read_rv); 5511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 5521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 5531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid MatchDoneWithBody(scoped_ptr<ServiceWorkerFetchRequest> request, 5541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const ServiceWorkerCache::ResponseCallback& callback, 5551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::WeakPtr<storage::BlobStorageContext> blob_storage, 5561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<ServiceWorkerResponse> response, 5571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<ResponseReadContext> response_context) { 5581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!blob_storage) { 5591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback.Run(ServiceWorkerCache::ErrorTypeStorage, 5601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<ServiceWorkerResponse>(), 5611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<storage::BlobDataHandle>()); 5621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 5631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 5641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 5651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<storage::BlobDataHandle> blob_data_handle( 5661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci blob_storage->AddFinishedBlob(response_context->blob_data.get())); 5671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 5681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback.Run(ServiceWorkerCache::ErrorTypeOK, 5691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci response.Pass(), 5701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci blob_data_handle.Pass()); 5711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 5721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 5731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid DeleteDidOpenEntry(scoped_ptr<ServiceWorkerFetchRequest> request, 5741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const ServiceWorkerCache::ErrorCallback& callback, 5751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<disk_cache::Entry*> entryptr, 5761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int rv) { 5771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (rv != net::OK) { 5781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback.Run(ServiceWorkerCache::ErrorTypeNotFound); 5791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 5801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 5811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 5821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(entryptr); 5831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci disk_cache::ScopedEntryPtr entry(*entryptr); 5841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 5851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci entry->Doom(); 5861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback.Run(ServiceWorkerCache::ErrorTypeOK); 5871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 5881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 5891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ReadHeaders(disk_cache::Entry* entry, const HeadersCallback& callback) { 5901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(entry); 5911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 5921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_refptr<net::IOBufferWithSize> buffer( 5931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new net::IOBufferWithSize(entry->GetDataSize(INDEX_HEADERS))); 5941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 5951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci net::CompletionCallback read_header_callback = 5961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(ReadHeadersDidReadHeaderData, entry, callback, buffer); 5971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 5981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int read_rv = entry->ReadData( 5991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci INDEX_HEADERS, 0, buffer.get(), buffer->size(), read_header_callback); 6001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 6011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (read_rv != net::ERR_IO_PENDING) 6021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci read_header_callback.Run(read_rv); 6031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 6041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 6051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ReadHeadersDidReadHeaderData( 6061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci disk_cache::Entry* entry, 6071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const HeadersCallback& callback, 6081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const scoped_refptr<net::IOBufferWithSize>& buffer, 6091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int rv) { 6101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (rv != buffer->size()) { 6111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback.Run(scoped_ptr<ServiceWorkerRequestResponseHeaders>()); 6121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 6131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 6141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 6151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<ServiceWorkerRequestResponseHeaders> headers( 6161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new ServiceWorkerRequestResponseHeaders()); 6171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 6181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!headers->ParseFromArray(buffer->data(), buffer->size())) { 6191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback.Run(scoped_ptr<ServiceWorkerRequestResponseHeaders>()); 6201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 6211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 6221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 6231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback.Run(headers.Pass()); 6241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 6251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 6261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid CreateBackendDidCreate(const ServiceWorkerCache::ErrorCallback& callback, 6271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<ScopedBackendPtr> backend_ptr, 6281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::WeakPtr<ServiceWorkerCache> cache, 6291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int rv) { 6301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (rv != net::OK || !cache) { 6311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback.Run(ServiceWorkerCache::ErrorTypeStorage); 6321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 6331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 6341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 6351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci cache->set_backend(backend_ptr->Pass()); 6361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback.Run(ServiceWorkerCache::ErrorTypeOK); 6371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 6381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 6391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} // namespace 6401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 6411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// The state needed to pass between ServiceWorkerCache::Keys callbacks. 6421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccistruct ServiceWorkerCache::KeysContext { 6431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci KeysContext(const ServiceWorkerCache::RequestsCallback& callback, 6441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::WeakPtr<ServiceWorkerCache> cache) 6451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci : original_callback(callback), 6461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci cache(cache), 6471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci out_keys(new ServiceWorkerCache::Requests()), 6481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci enumerated_entry(NULL) {} 6491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 6501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ~KeysContext() { 6511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for (size_t i = 0, max = entries.size(); i < max; ++i) 6521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci entries[i]->Close(); 6531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (enumerated_entry) 6541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci enumerated_entry->Close(); 6551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 6561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 6571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // The callback passed to the Keys() function. 6581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ServiceWorkerCache::RequestsCallback original_callback; 6591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 6601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // The ServiceWorkerCache that Keys was called on. 6611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::WeakPtr<ServiceWorkerCache> cache; 6621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 6631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // The vector of open entries in the backend. 6641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Entries entries; 6651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 6661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // The output of the Keys function. 6671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<ServiceWorkerCache::Requests> out_keys; 6681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 6691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Used for enumerating cache entries. 6701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<disk_cache::Backend::Iterator> backend_iterator; 6711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci disk_cache::Entry* enumerated_entry; 6721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}; 6731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 6746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// static 6751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciscoped_refptr<ServiceWorkerCache> ServiceWorkerCache::CreateMemoryCache( 6766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) net::URLRequestContext* request_context, 67703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) base::WeakPtr<storage::BlobStorageContext> blob_context) { 6781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return make_scoped_refptr( 6791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new ServiceWorkerCache(base::FilePath(), request_context, blob_context)); 6806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 6816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 6826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// static 6831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciscoped_refptr<ServiceWorkerCache> ServiceWorkerCache::CreatePersistentCache( 6846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const base::FilePath& path, 6856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) net::URLRequestContext* request_context, 68603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) base::WeakPtr<storage::BlobStorageContext> blob_context) { 6871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return make_scoped_refptr( 6881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new ServiceWorkerCache(path, request_context, blob_context)); 6896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 6906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 6911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciServiceWorkerCache::~ServiceWorkerCache() { 6926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 6936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 6946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)base::WeakPtr<ServiceWorkerCache> ServiceWorkerCache::AsWeakPtr() { 6956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return weak_ptr_factory_.GetWeakPtr(); 6966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 6976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 6981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ServiceWorkerCache::Put(scoped_ptr<ServiceWorkerFetchRequest> request, 6991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<ServiceWorkerResponse> response, 7001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const ErrorCallback& callback) { 7011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<storage::BlobDataHandle> blob_data_handle; 7021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 7031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!response->blob_uuid.empty()) { 7041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!blob_storage_context_) { 7051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback.Run(ErrorTypeStorage); 7061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 7071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 7081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci blob_data_handle = 7091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci blob_storage_context_->GetBlobDataFromUUID(response->blob_uuid); 7101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!blob_data_handle) { 7111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback.Run(ErrorTypeStorage); 7121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 7131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 7141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 7151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 7161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Closure continuation = base::Bind(&ServiceWorkerCache::PutImpl, 7171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci weak_ptr_factory_.GetWeakPtr(), 7181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Passed(request.Pass()), 7191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Passed(response.Pass()), 7201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Passed(blob_data_handle.Pass()), 7211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback); 7221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 7231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!initialized_) { 7241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Init(continuation); 7251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 7261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 7271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 7281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci continuation.Run(); 7291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 7301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 7311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ServiceWorkerCache::Match(scoped_ptr<ServiceWorkerFetchRequest> request, 7321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const ResponseCallback& callback) { 7331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!initialized_) { 7341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Init(base::Bind(&ServiceWorkerCache::Match, 7351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci weak_ptr_factory_.GetWeakPtr(), 7361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Passed(request.Pass()), 7371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback)); 7381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 7391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 7401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!backend_) { 7411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback.Run(ErrorTypeStorage, 7421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<ServiceWorkerResponse>(), 7431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<storage::BlobDataHandle>()); 7441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 7451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 7461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 7471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<disk_cache::Entry*> entry(new disk_cache::Entry*); 7481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 7491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci disk_cache::Entry** entry_ptr = entry.get(); 7501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 7511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ServiceWorkerFetchRequest* request_ptr = request.get(); 7521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 7531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci net::CompletionCallback open_entry_callback = 7541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(MatchDidOpenEntry, 7551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Passed(request.Pass()), 7561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback, 7571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci blob_storage_context_, 7581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Passed(entry.Pass())); 7591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 7601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int rv = backend_->OpenEntry( 7611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci request_ptr->url.spec(), entry_ptr, open_entry_callback); 7621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (rv != net::ERR_IO_PENDING) 7631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci open_entry_callback.Run(rv); 7641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 7651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 7661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ServiceWorkerCache::Delete(scoped_ptr<ServiceWorkerFetchRequest> request, 7671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const ErrorCallback& callback) { 7681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!initialized_) { 7691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Init(base::Bind(&ServiceWorkerCache::Delete, 7701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci weak_ptr_factory_.GetWeakPtr(), 7711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Passed(request.Pass()), 7721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback)); 7731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 7741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 7751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!backend_) { 7761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback.Run(ErrorTypeStorage); 7771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 7781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 7791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 7801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<disk_cache::Entry*> entry(new disk_cache::Entry*); 7811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 7821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci disk_cache::Entry** entry_ptr = entry.get(); 7831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 7841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ServiceWorkerFetchRequest* request_ptr = request.get(); 7851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 7861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci net::CompletionCallback open_entry_callback = 7871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(DeleteDidOpenEntry, 7881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Passed(request.Pass()), 7891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback, 7901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Passed(entry.Pass())); 7911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 7921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int rv = backend_->OpenEntry( 7931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci request_ptr->url.spec(), entry_ptr, open_entry_callback); 7941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (rv != net::ERR_IO_PENDING) 7951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci open_entry_callback.Run(rv); 7961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 7971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 7981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ServiceWorkerCache::Keys(const RequestsCallback& callback) { 7991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!initialized_) { 8001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Init(base::Bind( 8011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci &ServiceWorkerCache::Keys, weak_ptr_factory_.GetWeakPtr(), callback)); 8021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 8031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 8041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!backend_) { 8051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback.Run(ErrorTypeStorage, scoped_ptr<Requests>()); 8061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 8071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 8081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 8091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // 1. Iterate through all of the entries, open them, and add them to a vector. 8101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // 2. For each open entry: 8111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // 2.1. Read the headers into a protobuf. 8121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // 2.2. Copy the protobuf into a ServiceWorkerFetchRequest (a "key"). 8131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // 2.3. Push the response into a vector of requests to be returned. 8141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // 3. Return the vector of requests (keys). 8151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 8161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // The entries have to be loaded into a vector first because enumeration loops 8171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // forever if you read data from a cache entry while enumerating. 8181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 8191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<KeysContext> keys_context( 8201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new KeysContext(callback, weak_ptr_factory_.GetWeakPtr())); 8211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 8221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci keys_context->backend_iterator = backend_->CreateIterator(); 8231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci disk_cache::Backend::Iterator& iterator = *keys_context->backend_iterator; 8241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci disk_cache::Entry** enumerated_entry = &keys_context->enumerated_entry; 8251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 8261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci net::CompletionCallback open_entry_callback = 8271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(KeysDidOpenNextEntry, base::Passed(keys_context.Pass())); 8281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 8291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int rv = iterator.OpenNextEntry(enumerated_entry, open_entry_callback); 8301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 8311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (rv != net::ERR_IO_PENDING) 8321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci open_entry_callback.Run(rv); 8331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 8341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 8351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ServiceWorkerCache::Close() { 8361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci backend_.reset(); 8371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 8381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 8396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)ServiceWorkerCache::ServiceWorkerCache( 8406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const base::FilePath& path, 8416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) net::URLRequestContext* request_context, 84203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) base::WeakPtr<storage::BlobStorageContext> blob_context) 8436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) : path_(path), 8446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) request_context_(request_context), 8456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) blob_storage_context_(blob_context), 8461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci initialized_(false), 8476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) weak_ptr_factory_(this) { 8486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 8496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 8501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ServiceWorkerCache::PutImpl( 8511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<ServiceWorkerFetchRequest> request, 8521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<ServiceWorkerResponse> response, 8531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<storage::BlobDataHandle> blob_data_handle, 8541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const ErrorCallback& callback) { 8551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!backend_) { 8561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback.Run(ErrorTypeStorage); 8571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 8581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 8591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 8601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<disk_cache::Entry*> entry(new disk_cache::Entry*); 8611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 8621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci disk_cache::Entry** entry_ptr = entry.get(); 8631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 8641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ServiceWorkerFetchRequest* request_ptr = request.get(); 8651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 8661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci net::CompletionCallback create_entry_callback = 8671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(PutDidCreateEntry, 8681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Passed(request.Pass()), 8691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Passed(response.Pass()), 8701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback, 8711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Passed(entry.Pass()), 8721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Passed(blob_data_handle.Pass()), 8731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci request_context_); 8741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 8751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int rv = backend_->CreateEntry( 8761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci request_ptr->url.spec(), entry_ptr, create_entry_callback); 8771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 8781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (rv != net::ERR_IO_PENDING) 8791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci create_entry_callback.Run(rv); 8801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 8811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 8821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// static 8831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ServiceWorkerCache::KeysDidOpenNextEntry( 8841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<KeysContext> keys_context, 8851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int rv) { 8861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (rv == net::ERR_FAILED) { 8871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(!keys_context->enumerated_entry); 8881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Enumeration is complete, extract the requests from the entries. 8891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Entries::iterator iter = keys_context->entries.begin(); 8901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci KeysProcessNextEntry(keys_context.Pass(), iter); 8911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 8921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 8931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 8941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::WeakPtr<ServiceWorkerCache> cache = keys_context->cache; 8951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (rv < 0 || !cache) { 8961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci keys_context->original_callback.Run(ErrorTypeStorage, 8971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<Requests>()); 8981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 8991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 9001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 9011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!cache->backend_) { 9021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci keys_context->original_callback.Run(ErrorTypeNotFound, 9031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<Requests>()); 9041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 9051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 9061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 9071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Store the entry. 9081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci keys_context->entries.push_back(keys_context->enumerated_entry); 9091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci keys_context->enumerated_entry = NULL; 9101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 9111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Enumerate the next entry. 9121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci disk_cache::Backend::Iterator& iterator = *keys_context->backend_iterator; 9131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci disk_cache::Entry** enumerated_entry = &keys_context->enumerated_entry; 9141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci net::CompletionCallback open_entry_callback = 9151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(KeysDidOpenNextEntry, base::Passed(keys_context.Pass())); 9161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 9171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci rv = iterator.OpenNextEntry(enumerated_entry, open_entry_callback); 9181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 9191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (rv != net::ERR_IO_PENDING) 9201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci open_entry_callback.Run(rv); 9211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 9221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 9231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// static 9241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ServiceWorkerCache::KeysProcessNextEntry( 9251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<KeysContext> keys_context, 9261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const Entries::iterator& iter) { 9271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (iter == keys_context->entries.end()) { 9281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // All done. Return all of the keys. 9291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci keys_context->original_callback.Run(ErrorTypeOK, 9301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci keys_context->out_keys.Pass()); 9311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 9321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 9331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 9341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ReadHeaders( 9351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci *iter, 9361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(KeysDidReadHeaders, base::Passed(keys_context.Pass()), iter)); 9371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 9381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 9391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// static 9401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ServiceWorkerCache::KeysDidReadHeaders( 9411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<KeysContext> keys_context, 9421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const Entries::iterator& iter, 9431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<ServiceWorkerRequestResponseHeaders> headers) { 9441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci disk_cache::Entry* entry = *iter; 9451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 9461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (headers) { 9471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci keys_context->out_keys->push_back( 9481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ServiceWorkerFetchRequest(GURL(entry->GetKey()), 9491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci headers->method(), 9501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ServiceWorkerHeaderMap(), 9511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GURL(), 9521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci false)); 9531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 9541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ServiceWorkerHeaderMap& req_headers = 9551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci keys_context->out_keys->back().headers; 9561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 9571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for (int i = 0; i < headers->request_headers_size(); ++i) { 9581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const ServiceWorkerRequestResponseHeaders::HeaderMap header = 9591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci headers->request_headers(i); 9601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci req_headers.insert(std::make_pair(header.name(), header.value())); 9611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 9621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else { 9631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci entry->Doom(); 9641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 9651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 9661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci KeysProcessNextEntry(keys_context.Pass(), iter + 1); 9671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 9681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 9691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ServiceWorkerCache::CreateBackend(const ErrorCallback& callback) { 9701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(!backend_); 9711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 9721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Use APP_CACHE as opposed to DISK_CACHE to prevent cache eviction. 9731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci net::CacheType cache_type = 9741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci path_.empty() ? net::MEMORY_CACHE : net::APP_CACHE; 9751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 9761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<ScopedBackendPtr> backend_ptr(new ScopedBackendPtr()); 9771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 9781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Temporary pointer so that backend_ptr can be Pass()'d in Bind below. 9791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ScopedBackendPtr* backend = backend_ptr.get(); 9801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 9811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci net::CompletionCallback create_cache_callback = 9821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(CreateBackendDidCreate, 9831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback, 9841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Passed(backend_ptr.Pass()), 9851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci weak_ptr_factory_.GetWeakPtr()); 9861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 9871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // TODO(jkarlin): Use the cache MessageLoopProxy that ServiceWorkerCacheCore 9881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // has for disk caches. 9891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int rv = disk_cache::CreateCacheBackend( 9901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci cache_type, 9911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci net::CACHE_BACKEND_SIMPLE, 9921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci path_, 9931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci kMaxCacheBytes, 9941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci false, /* force */ 9951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE).get(), 9961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NULL, 9971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci backend, 9981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci create_cache_callback); 9991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (rv != net::ERR_IO_PENDING) 10001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci create_cache_callback.Run(rv); 10011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 10021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 10031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ServiceWorkerCache::Init(const base::Closure& callback) { 10041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci init_callbacks_.push_back(callback); 10051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 10061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // If this isn't the first call to Init then return as the initialization 10071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // has already started. 10081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (init_callbacks_.size() > 1u) 10091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 10101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 10111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci CreateBackend(base::Bind(&ServiceWorkerCache::InitDone, 10121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci weak_ptr_factory_.GetWeakPtr())); 10131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 10141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 10151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ServiceWorkerCache::InitDone(ErrorType error) { 10161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci initialized_ = true; 10171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for (std::vector<base::Closure>::iterator it = init_callbacks_.begin(); 10181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci it != init_callbacks_.end(); 10191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ++it) { 10201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci it->Run(); 10211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 10221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci init_callbacks_.clear(); 10236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 10246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 10256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} // namespace content 1026