Commit b5ca81a3 authored by jkarlin's avatar jkarlin Committed by Commit bot

Initial implementation of ServiceWorkerCache Put and Match functions.

Note that the Match() function copies the data into a memory blob.  This is of course only for demo purposes. This will soon be changed to use a streaming API. See bug 403493.

BUG=392621

Review URL: https://codereview.chromium.org/465463002

Cr-Commit-Position: refs/heads/master@{#291834}
parent 80bc5e3c
......@@ -8,28 +8,44 @@
#include "base/callback.h"
#include "base/files/file_path.h"
#include "base/memory/weak_ptr.h"
#include "content/common/service_worker/service_worker_types.h"
#include "net/base/completion_callback.h"
#include "net/disk_cache/disk_cache.h"
namespace net {
class URLRequestContext;
class IOBufferWithSize;
}
namespace storage {
class BlobData;
class BlobDataHandle;
class BlobStorageContext;
}
namespace content {
class ChromeBlobStorageContext;
// TODO(jkarlin): Fill this in with a real Cache implementation as
// specified in
// https://slightlyoff.github.io/ServiceWorker/spec/service_worker/index.html.
// TODO(jkarlin): Unload cache backend from memory once the cache object is no
// longer referenced in javascript.
// Represents a ServiceWorker Cache as seen in
// https://slightlyoff.github.io/ServiceWorker/spec/service_worker/index.html.
// InitializeIfNeeded must be called before calling the other public members.
class ServiceWorkerCache {
class CONTENT_EXPORT ServiceWorkerCache {
public:
enum ErrorType {
ErrorTypeOK = 0,
ErrorTypeExists,
ErrorTypeStorage,
ErrorTypeNotFound
};
enum EntryIndex { INDEX_HEADERS = 0, INDEX_RESPONSE_BODY };
typedef base::Callback<void(ErrorType)> ErrorCallback;
typedef base::Callback<void(ErrorType,
scoped_ptr<ServiceWorkerResponse>,
scoped_ptr<storage::BlobDataHandle>)>
ResponseCallback;
static scoped_ptr<ServiceWorkerCache> CreateMemoryCache(
const std::string& name,
net::URLRequestContext* request_context,
......@@ -44,9 +60,34 @@ class ServiceWorkerCache {
// Loads the backend and calls the callback with the result (true for
// success). This must be called before member functions that require a
// backend are called.
void CreateBackend(const base::Callback<void(bool)>& callback);
// backend are called. The callback will always be called.
void CreateBackend(const ErrorCallback& callback);
// Returns ErrorTypeNotFound if not found. The callback will always be called.
// |request| must remain valid until the callback is called.
void Match(ServiceWorkerFetchRequest* request,
const ResponseCallback& callback);
// Puts the request and response object in the cache. The response body (if
// present) is stored in the cache, but not the request body. Returns
// ErrorTypeOK on success. The callback will always be called. |request| and
// |response| must remain valid until the callback is called.
void Put(ServiceWorkerFetchRequest* request,
ServiceWorkerResponse* response,
const ErrorCallback& callback);
// Returns ErrorNotFound if not found. Otherwise deletes and returns
// ErrorTypeOK. The callback will always be called. |request| must remain
// valid until the callback is called.
void Delete(ServiceWorkerFetchRequest* request,
const ErrorCallback& callback);
// Call to determine if CreateBackend must be called.
bool HasCreatedBackend() const;
void set_backend(scoped_ptr<disk_cache::Backend> backend) {
backend_ = backend.Pass();
}
void set_name(const std::string& name) { name_ = name; }
const std::string& name() const { return name_; }
int32 id() const { return id_; }
......@@ -60,6 +101,7 @@ class ServiceWorkerCache {
net::URLRequestContext* request_context,
base::WeakPtr<storage::BlobStorageContext> blob_context);
scoped_ptr<disk_cache::Backend> backend_;
base::FilePath path_;
std::string name_;
net::URLRequestContext* request_context_;
......
......@@ -11,7 +11,20 @@ package content;
message ServiceWorkerCacheStorageIndex {
message Cache {
required string name = 1;
required int32 size = 2;
optional int32 DEPRECATED_size = 2;
optional int64 size = 3;
}
repeated Cache cache = 1;
}
message ServiceWorkerRequestResponseHeaders {
message HeaderMap {
required string name = 1;
required string value = 2;
}
required string method = 1;
required int32 status_code = 2;
required string status_text = 3;
repeated HeaderMap request_headers = 4;
repeated HeaderMap response_headers = 5;
}
......@@ -63,7 +63,7 @@ class ServiceWorkerCacheStorage::CacheLoader
friend class base::RefCountedThreadSafe<
ServiceWorkerCacheStorage::CacheLoader>;
virtual ~CacheLoader() {};
virtual ~CacheLoader() {}
virtual void LoadCacheImpl(const std::string&) {}
scoped_refptr<base::SequencedTaskRunner> cache_task_runner_;
......@@ -342,11 +342,11 @@ class ServiceWorkerCacheStorage::SimpleCacheLoader
DCHECK_CURRENTLY_ON(BrowserThread::IO);
ServiceWorkerCacheStorageIndex index;
index.ParseFromString(serialized);
for (int i = 0, max = index.cache_size(); i < max; ++i) {
const ServiceWorkerCacheStorageIndex::Cache& cache = index.cache(i);
names->push_back(cache.name());
if (index.ParseFromString(serialized)) {
for (int i = 0, max = index.cache_size(); i < max; ++i) {
const ServiceWorkerCacheStorageIndex::Cache& cache = index.cache(i);
names->push_back(cache.name());
}
}
// TODO(jkarlin): Delete caches that are in the directory and not returned
......@@ -446,6 +446,9 @@ void ServiceWorkerCacheStorage::GetCache(
return;
}
if (cache->HasCreatedBackend())
return callback.Run(cache->id(), CACHE_STORAGE_ERROR_NO_ERROR);
cache->CreateBackend(base::Bind(&ServiceWorkerCacheStorage::DidCreateBackend,
weak_factory_.GetWeakPtr(),
cache->AsWeakPtr(),
......@@ -533,15 +536,16 @@ void ServiceWorkerCacheStorage::EnumerateCaches(
void ServiceWorkerCacheStorage::DidCreateBackend(
base::WeakPtr<ServiceWorkerCache> cache,
const CacheAndErrorCallback& callback,
bool success) {
ServiceWorkerCache::ErrorType error) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!success || !cache) {
if (error != ServiceWorkerCache::ErrorTypeOK || !cache) {
// TODO(jkarlin): This should delete the directory and try again in case
// the cache is simply corrupt.
callback.Run(0, CACHE_STORAGE_ERROR_STORAGE);
return;
}
callback.Run(cache->id(), CACHE_STORAGE_ERROR_NO_ERROR);
}
......@@ -672,6 +676,7 @@ void ServiceWorkerCacheStorage::CreateCacheDidWriteIndex(
callback.Run(false, CACHE_STORAGE_ERROR_STORAGE);
return;
}
cache->CreateBackend(base::Bind(&ServiceWorkerCacheStorage::DidCreateBackend,
weak_factory_.GetWeakPtr(),
cache,
......
......@@ -12,6 +12,7 @@
#include "base/files/file_path.h"
#include "base/id_map.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/service_worker/service_worker_cache.h"
namespace base {
class SequencedTaskRunner;
......@@ -26,7 +27,6 @@ class BlobStorageContext;
}
namespace content {
class ServiceWorkerCache;
// TODO(jkarlin): Constrain the total bytes used per origin.
......@@ -108,7 +108,7 @@ class ServiceWorkerCacheStorage {
void DidCreateBackend(base::WeakPtr<ServiceWorkerCache> cache,
const CacheAndErrorCallback& callback,
bool success);
ServiceWorkerCache::ErrorType error);
void AddCacheToMaps(scoped_ptr<ServiceWorkerCache> cache);
......
......@@ -589,6 +589,7 @@
'browser/service_worker/embedded_worker_instance_unittest.cc',
'browser/service_worker/embedded_worker_test_helper.cc',
'browser/service_worker/embedded_worker_test_helper.h',
'browser/service_worker/service_worker_cache_unittest.cc',
'browser/service_worker/service_worker_cache_storage_manager_unittest.cc',
'browser/service_worker/service_worker_context_unittest.cc',
'browser/service_worker/service_worker_controllee_request_handler_unittest.cc',
......
......@@ -46,6 +46,13 @@ StringIOBuffer::StringIOBuffer(const std::string& s)
data_ = const_cast<char*>(string_data_.data());
}
StringIOBuffer::StringIOBuffer(scoped_ptr<std::string> s)
: IOBuffer(static_cast<char*>(NULL)) {
CHECK_LT(s->size(), static_cast<size_t>(INT_MAX));
string_data_.swap(*s.get());
data_ = const_cast<char*>(string_data_.data());
}
StringIOBuffer::~StringIOBuffer() {
// We haven't allocated the buffer, so remove it before the base class
// destructor tries to delete[] it.
......
......@@ -114,6 +114,7 @@ class NET_EXPORT IOBufferWithSize : public IOBuffer {
class NET_EXPORT StringIOBuffer : public IOBuffer {
public:
explicit StringIOBuffer(const std::string& s);
explicit StringIOBuffer(scoped_ptr<std::string> s);
int size() const { return static_cast<int>(string_data_.size()); }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment