Commit b54ef54a authored by michaeln@chromium.org's avatar michaeln@chromium.org

Store the service worker script and its imports on first load... kinda

The resource data is put into an in-memory instance of a net::DiskCache for now. That cache will be used for (some) subsequent starts of the worker in the current browsing session, but will not be used across browser restarts. The next step is to have the registration job store the resource ids with the registration data on disk and to also put the resource data to disk.

BUG=364318

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@271253 0039d316-1c4b-4281-b951-d872f2087c98
parent 857f47cd
......@@ -4,9 +4,12 @@
#include "content/browser/service_worker/service_worker_context_request_handler.h"
#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_provider_host.h"
#include "content/browser/service_worker/service_worker_read_from_cache_job.h"
#include "content/browser/service_worker/service_worker_storage.h"
#include "content/browser/service_worker/service_worker_version.h"
#include "content/browser/service_worker/service_worker_write_to_cache_job.h"
#include "net/url_request/url_request.h"
namespace content {
......@@ -26,7 +29,11 @@ ServiceWorkerContextRequestHandler::~ServiceWorkerContextRequestHandler() {
net::URLRequestJob* ServiceWorkerContextRequestHandler::MaybeCreateJob(
net::URLRequest* request,
net::NetworkDelegate* network_delegate) {
if (!provider_host_ || !version_)
if (!provider_host_ || !version_ || !context_)
return NULL;
// We currently have no use case for hijacking a redirected request.
if (request->url_chain().size() > 1)
return NULL;
// We only use the script cache for main script loading and
......@@ -40,8 +47,11 @@ net::URLRequestJob* ServiceWorkerContextRequestHandler::MaybeCreateJob(
}
if (ShouldAddToScriptCache(request->url())) {
return NULL;
// TODO(michaeln): return new ServiceWorkerWriteToCacheJob();
int64 response_id = context_->storage()->NewResourceId();
if (response_id == kInvalidServiceWorkerResponseId)
return NULL;
return new ServiceWorkerWriteToCacheJob(
request, network_delegate, context_, version_, response_id);
}
int64 response_id = kInvalidServiceWorkerResponseId;
......@@ -56,8 +66,7 @@ net::URLRequestJob* ServiceWorkerContextRequestHandler::MaybeCreateJob(
bool ServiceWorkerContextRequestHandler::ShouldAddToScriptCache(
const GURL& url) {
// TODO(michaeln): Ensure the transition to INSTALLING can't
// happen prior to the initial eval completion.
// We only write imports that occur during the initial eval.
if (version_->status() != ServiceWorkerVersion::NEW)
return false;
return version_->script_cache_map()->Lookup(url) ==
......
......@@ -10,12 +10,13 @@
#include <vector>
#include "base/files/file_path.h"
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/sequence_checker.h"
#include "base/time/time.h"
#include "content/browser/service_worker/service_worker_version.h"
#include "content/common/content_export.h"
#include "content/common/service_worker/service_worker_status_code.h"
#include "url/gurl.h"
namespace leveldb {
......@@ -52,12 +53,6 @@ class CONTENT_EXPORT ServiceWorkerDatabase {
bool has_fetch_handler;
base::Time last_update_check;
ServiceWorkerVersion::Status GetVersionStatus() const {
if (is_active)
return ServiceWorkerVersion::ACTIVE;
return ServiceWorkerVersion::INSTALLED;
}
RegistrationData();
~RegistrationData();
};
......
......@@ -42,6 +42,10 @@ class ServiceWorkerResponseWriter
struct HttpResponseInfoIOBuffer
: public appcache::HttpResponseInfoIOBuffer {
public:
HttpResponseInfoIOBuffer() : appcache::HttpResponseInfoIOBuffer() {}
explicit HttpResponseInfoIOBuffer(net::HttpResponseInfo* info)
: appcache::HttpResponseInfoIOBuffer(info) {}
protected:
virtual ~HttpResponseInfoIOBuffer();
};
......
......@@ -63,8 +63,9 @@ void ServiceWorkerReadFromCacheJob::Kill() {
}
net::LoadState ServiceWorkerReadFromCacheJob::GetLoadState() const {
NOTIMPLEMENTED();
return net::LOAD_STATE_WAITING_FOR_APPCACHE;
if (reader_.get() && reader_->IsReadPending())
return net::LOAD_STATE_READING_RESPONSE;
return net::LOAD_STATE_IDLE;
}
bool ServiceWorkerReadFromCacheJob::GetCharset(std::string* charset) {
......
......@@ -95,8 +95,8 @@ ServiceWorkerRegistration* ServiceWorkerRegisterJob::registration() {
void ServiceWorkerRegisterJob::set_pending_version(
ServiceWorkerVersion* version) {
DCHECK(phase_ == UPDATE || phase_ == ACTIVATE) << phase_;
DCHECK(!internal_.pending_version || !version);
DCHECK(phase_ == UPDATE) << phase_;
DCHECK(!internal_.pending_version);
internal_.pending_version = version;
}
......@@ -375,7 +375,8 @@ void ServiceWorkerRegisterJob::Complete(ServiceWorkerStatusCode status) {
ResolvePromise(status, NULL, NULL);
}
DCHECK(callbacks_.empty());
context_->storage()->NotifyDoneInstallingRegistration(registration());
if (registration())
context_->storage()->NotifyDoneInstallingRegistration(registration());
context_->job_coordinator()->FinishJob(pattern_, this);
}
......@@ -400,7 +401,7 @@ void ServiceWorkerRegisterJob::AssociatePendingVersionToDocuments(
ServiceWorkerVersion* version) {
// TODO(michaeln): This needs to respect the longest prefix wins
// when it comes to finding a registration for a document url.
// This should should utilize storage->FindRegistrationForDocument().
// This should utilize storage->FindRegistrationForDocument().
for (scoped_ptr<ServiceWorkerContextCore::ProviderHostIterator> it =
context_->GetProviderHostIterator();
!it->IsAtEnd();
......
......@@ -38,6 +38,15 @@ class ServiceWorkerRequestInterceptor
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerRequestInterceptor);
};
bool IsMethodSupported(const std::string& method) {
return (method == "GET") || (method == "HEAD");
}
bool IsSchemeAndMethodSupported(const net::URLRequest* request) {
return request->url().SchemeIsHTTPOrHTTPS() &&
IsMethodSupported(request->method());
}
} // namespace
void ServiceWorkerRequestHandler::InitializeHandler(
......@@ -46,8 +55,10 @@ void ServiceWorkerRequestHandler::InitializeHandler(
int process_id,
int provider_id,
ResourceType::Type resource_type) {
if (!ServiceWorkerUtils::IsFeatureEnabled())
if (!ServiceWorkerUtils::IsFeatureEnabled() ||
!IsSchemeAndMethodSupported(request)) {
return;
}
if (!context_wrapper || !context_wrapper->context() ||
provider_id == kInvalidServiceWorkerProviderId) {
......
......@@ -13,9 +13,6 @@ namespace content {
ServiceWorkerScriptCacheMap::ServiceWorkerScriptCacheMap(
ServiceWorkerVersion* owner)
: owner_(owner),
is_eval_complete_(false),
resources_started_(0),
resources_finished_(0),
has_error_(false) {
}
......@@ -29,48 +26,42 @@ int64 ServiceWorkerScriptCacheMap::Lookup(const GURL& url) {
return found->second;
}
void ServiceWorkerScriptCacheMap::AddObserver(Observer* observer) {
observers_.AddObserver(observer);
}
void ServiceWorkerScriptCacheMap::RemoveObserver(Observer* observer) {
observers_.RemoveObserver(observer);
}
void ServiceWorkerScriptCacheMap::NotifyStartedCaching(
const GURL& url, int64 resource_id) {
DCHECK_EQ(kInvalidServiceWorkerResponseId, Lookup(url));
DCHECK(owner_->status() == ServiceWorkerVersion::NEW ||
owner_->status() == ServiceWorkerVersion::INSTALLING);
DCHECK(!is_eval_complete_);
DCHECK(owner_->status() == ServiceWorkerVersion::NEW);
resource_ids_[url] = resource_id;
++resources_started_;
// TODO(michaeln): Add resource id to the uncommitted list.
}
void ServiceWorkerScriptCacheMap::NotifyFinishedCaching(
const GURL& url, bool success) {
DCHECK_NE(kInvalidServiceWorkerResponseId, Lookup(url));
DCHECK(owner_->status() == ServiceWorkerVersion::NEW ||
owner_->status() == ServiceWorkerVersion::INSTALLING);
++resources_finished_;
if (!success)
DCHECK(owner_->status() == ServiceWorkerVersion::NEW);
if (!success) {
has_error_ = true;
if (url == owner_->script_url()) {
FOR_EACH_OBSERVER(Observer, observers_,
OnMainScriptCached(owner_, success));
resource_ids_.erase(url);
// TODO(michaeln): Doom the resource id.
}
if (is_eval_complete_ && resources_finished_ == resources_started_) {
FOR_EACH_OBSERVER(Observer, observers_,
OnAllScriptsCached(owner_, has_error_));
}
void ServiceWorkerScriptCacheMap::GetResources(
std::vector<ServiceWorkerDatabase::ResourceRecord>* resources) {
DCHECK(resources->empty());
for (ResourceIDMap::const_iterator it = resource_ids_.begin();
it != resource_ids_.end(); ++it) {
ServiceWorkerDatabase::ResourceRecord record = { it->second, it->first };
resources->push_back(record);
}
}
void ServiceWorkerScriptCacheMap::NotifyEvalCompletion() {
DCHECK(!is_eval_complete_);
is_eval_complete_ = true;
if (resources_finished_ == resources_started_) {
FOR_EACH_OBSERVER(Observer, observers_,
OnAllScriptsCached(owner_, has_error_));
void ServiceWorkerScriptCacheMap::SetResources(
const std::vector<ServiceWorkerDatabase::ResourceRecord>& resources) {
DCHECK(resource_ids_.empty());
typedef std::vector<ServiceWorkerDatabase::ResourceRecord> RecordVector;
for (RecordVector::const_iterator it = resources.begin();
it != resources.end(); ++it) {
resource_ids_[it->url] = it->resource_id;
}
}
......
......@@ -6,9 +6,10 @@
#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_SCRIPT_CACHE_MAP_H_
#include <map>
#include <vector>
#include "base/basictypes.h"
#include "base/observer_list.h"
#include "content/browser/service_worker/service_worker_database.h"
class GURL;
......@@ -20,33 +21,21 @@ class ServiceWorkerVersion;
// for a particular versions implicit script resources.
class ServiceWorkerScriptCacheMap {
public:
class Observer {
public:
// Notification that the main script resource has been written to
// the disk cache. Only called when a version is being initially
// installed.
virtual void OnMainScriptCached(ServiceWorkerVersion* version,
bool success) = 0;
// Notification that the main script resource and all imports have
// been written to the disk cache. Only called when a version is
// being initially installed.
virtual void OnAllScriptsCached(ServiceWorkerVersion* version,
bool success) = 0;
};
int64 Lookup(const GURL& url);
// Adds and removes Observers.
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
// Used during the initial run of a new version to build the map
// of resources ids.
// TODO(michaeln): Need more info about errors in Finished.
void NotifyStartedCaching(const GURL& url, int64 resource_id);
void NotifyFinishedCaching(const GURL& url, bool success);
void NotifyEvalCompletion();
// Used to retrieve the results of the initial run of a new version.
bool HasError() const { return has_error_; }
void GetResources(
std::vector<ServiceWorkerDatabase::ResourceRecord>* resources);
// Used when loading an existing version.
void SetResources(
const std::vector<ServiceWorkerDatabase::ResourceRecord>& resources);
private:
typedef std::map<GURL, int64> ResourceIDMap;
......@@ -58,13 +47,7 @@ class ServiceWorkerScriptCacheMap {
ServiceWorkerVersion* owner_;
ResourceIDMap resource_ids_;
// Members used only during initial install.
bool is_eval_complete_;
int resources_started_;
int resources_finished_;
bool has_error_;
ObserverList<Observer> observers_;
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerScriptCacheMap);
};
......
......@@ -709,7 +709,8 @@ ServiceWorkerStorage::CreateRegistration(
context_->GetLiveVersion(data.version_id);
if (!version) {
version = new ServiceWorkerVersion(registration, data.version_id, context_);
version->SetStatus(data.GetVersionStatus());
version->SetStatus(data.is_active ?
ServiceWorkerVersion::ACTIVE : ServiceWorkerVersion::INSTALLED);
}
if (version->status() == ServiceWorkerVersion::ACTIVE)
......
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/service_worker/service_worker_write_to_cache_job.h"
#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_disk_cache.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_util.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_status.h"
namespace content {
ServiceWorkerWriteToCacheJob::ServiceWorkerWriteToCacheJob(
net::URLRequest* request,
net::NetworkDelegate* network_delegate,
base::WeakPtr<ServiceWorkerContextCore> context,
ServiceWorkerVersion* version,
int64 response_id)
: net::URLRequestJob(request, network_delegate),
context_(context),
url_(request->url()),
response_id_(response_id),
version_(version),
has_been_killed_(false),
did_notify_started_(false),
did_notify_finished_(false),
weak_factory_(this) {
InitNetRequest();
}
ServiceWorkerWriteToCacheJob::~ServiceWorkerWriteToCacheJob() {
DCHECK_EQ(did_notify_started_, did_notify_finished_);
}
void ServiceWorkerWriteToCacheJob::Start() {
if (!context_) {
NotifyStartError(net::URLRequestStatus(
net::URLRequestStatus::FAILED, net::ERR_FAILED));
return;
}
version_->script_cache_map()->NotifyStartedCaching(
url_, response_id_);
did_notify_started_ = true;
StartNetRequest();
}
void ServiceWorkerWriteToCacheJob::Kill() {
if (has_been_killed_)
return;
weak_factory_.InvalidateWeakPtrs();
has_been_killed_ = true;
net_request_.reset();
if (did_notify_started_ && !did_notify_finished_) {
version_->script_cache_map()->NotifyFinishedCaching(
url_, false);
did_notify_finished_ = true;
}
writer_.reset();
context_.reset();
net::URLRequestJob::Kill();
}
net::LoadState ServiceWorkerWriteToCacheJob::GetLoadState() const {
if (writer_ && writer_->IsWritePending())
return net::LOAD_STATE_WAITING_FOR_APPCACHE;
if (net_request_)
return net_request_->GetLoadState().state;
return net::LOAD_STATE_IDLE;
}
bool ServiceWorkerWriteToCacheJob::GetCharset(std::string* charset) {
if (!http_info())
return false;
return http_info()->headers->GetCharset(charset);
}
bool ServiceWorkerWriteToCacheJob::GetMimeType(std::string* mime_type) const {
if (!http_info())
return false;
return http_info()->headers->GetMimeType(mime_type);
}
void ServiceWorkerWriteToCacheJob::GetResponseInfo(
net::HttpResponseInfo* info) {
if (!http_info())
return;
*info = *http_info();
}
int ServiceWorkerWriteToCacheJob::GetResponseCode() const {
if (!http_info())
return -1;
return http_info()->headers->response_code();
}
void ServiceWorkerWriteToCacheJob::SetExtraRequestHeaders(
const net::HttpRequestHeaders& headers) {
std::string value;
DCHECK(!headers.GetHeader(net::HttpRequestHeaders::kRange, &value));
net_request_->SetExtraRequestHeaders(headers);
}
bool ServiceWorkerWriteToCacheJob::ReadRawData(
net::IOBuffer* buf,
int buf_size,
int *bytes_read) {
net::URLRequestStatus status = ReadNetData(buf, buf_size, bytes_read);
SetStatus(status);
if (status.is_io_pending())
return false;
// No more data to process, the job is complete.
io_buffer_ = NULL;
version_->script_cache_map()->NotifyFinishedCaching(
url_, status.is_success());
did_notify_finished_ = true;
return status.is_success();
}
const net::HttpResponseInfo* ServiceWorkerWriteToCacheJob::http_info() const {
return http_info_.get();
}
void ServiceWorkerWriteToCacheJob::InitNetRequest() {
DCHECK(request());
net_request_ = request()->context()->CreateRequest(
request()->url(),
request()->priority(),
this,
this->GetCookieStore());
net_request_->set_first_party_for_cookies(
request()->first_party_for_cookies());
net_request_->SetReferrer(request()->referrer());
net_request_->SetExtraRequestHeaders(request()->extra_request_headers());
}
void ServiceWorkerWriteToCacheJob::StartNetRequest() {
net_request_->Start(); // We'll continue in OnResponseStarted.
}
net::URLRequestStatus ServiceWorkerWriteToCacheJob::ReadNetData(
net::IOBuffer* buf,
int buf_size,
int *bytes_read) {
DCHECK_GT(buf_size, 0);
DCHECK(bytes_read);
*bytes_read = 0;
io_buffer_ = buf;
int net_bytes_read = 0;
if (!net_request_->Read(buf, buf_size, &net_bytes_read)) {
if (net_request_->status().is_io_pending())
return net_request_->status();
DCHECK(!net_request_->status().is_success());
return net_request_->status();
}
if (net_bytes_read != 0) {
WriteDataToCache(net_bytes_read);
DCHECK(GetStatus().is_io_pending());
return GetStatus();
}
DCHECK(net_request_->status().is_success());
return net_request_->status();
}
void ServiceWorkerWriteToCacheJob::WriteHeadersToCache() {
if (!context_) {
AsyncNotifyDoneHelper(net::URLRequestStatus(
net::URLRequestStatus::FAILED, net::ERR_FAILED));
return;
}
writer_ = context_->storage()->CreateResponseWriter(response_id_);
info_buffer_ = new HttpResponseInfoIOBuffer(
new net::HttpResponseInfo(net_request_->response_info()));
writer_->WriteInfo(
info_buffer_,
base::Bind(&ServiceWorkerWriteToCacheJob::OnWriteHeadersComplete,
weak_factory_.GetWeakPtr()));
SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0));
}
void ServiceWorkerWriteToCacheJob::OnWriteHeadersComplete(int result) {
SetStatus(net::URLRequestStatus()); // Clear the IO_PENDING status
if (result < 0) {
AsyncNotifyDoneHelper(net::URLRequestStatus(
net::URLRequestStatus::FAILED, result));
return;
}
http_info_.reset(info_buffer_->http_info.release());
info_buffer_ = NULL;
NotifyHeadersComplete();
}
void ServiceWorkerWriteToCacheJob::WriteDataToCache(int amount_to_write) {
DCHECK_NE(0, amount_to_write);
SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0));
writer_->WriteData(
io_buffer_, amount_to_write,
base::Bind(&ServiceWorkerWriteToCacheJob::OnWriteDataComplete,
weak_factory_.GetWeakPtr()));
}
void ServiceWorkerWriteToCacheJob::OnWriteDataComplete(int result) {
DCHECK_NE(0, result);
io_buffer_ = NULL;
if (!context_) {
AsyncNotifyDoneHelper(net::URLRequestStatus(
net::URLRequestStatus::FAILED, net::ERR_FAILED));
return;
}
if (result < 0) {
AsyncNotifyDoneHelper(net::URLRequestStatus(
net::URLRequestStatus::FAILED, result));
return;
}
SetStatus(net::URLRequestStatus()); // Clear the IO_PENDING status
NotifyReadComplete(result);
}
void ServiceWorkerWriteToCacheJob::OnReceivedRedirect(
net::URLRequest* request,
const GURL& new_url,
bool* defer_redirect) {
DCHECK_EQ(net_request_, request);
// Script resources can't redirect.
AsyncNotifyDoneHelper(net::URLRequestStatus(
net::URLRequestStatus::FAILED, net::ERR_FAILED));
}
void ServiceWorkerWriteToCacheJob::OnAuthRequired(
net::URLRequest* request,
net::AuthChallengeInfo* auth_info) {
DCHECK_EQ(net_request_, request);
// TODO(michaeln): Pass this thru to our jobs client.
AsyncNotifyDoneHelper(net::URLRequestStatus(
net::URLRequestStatus::FAILED, net::ERR_FAILED));
}
void ServiceWorkerWriteToCacheJob::OnCertificateRequested(
net::URLRequest* request,
net::SSLCertRequestInfo* cert_request_info) {
DCHECK_EQ(net_request_, request);
// TODO(michaeln): Pass this thru to our jobs client.
// see NotifyCertificateRequested.
AsyncNotifyDoneHelper(net::URLRequestStatus(
net::URLRequestStatus::FAILED, net::ERR_FAILED));
}
void ServiceWorkerWriteToCacheJob:: OnSSLCertificateError(
net::URLRequest* request,
const net::SSLInfo& ssl_info,
bool fatal) {
DCHECK_EQ(net_request_, request);
// TODO(michaeln): Pass this thru to our jobs client,
// see NotifySSLCertificateError.
AsyncNotifyDoneHelper(net::URLRequestStatus(
net::URLRequestStatus::FAILED, net::ERR_FAILED));
}
void ServiceWorkerWriteToCacheJob::OnBeforeNetworkStart(
net::URLRequest* request,
bool* defer) {
DCHECK_EQ(net_request_, request);
NotifyBeforeNetworkStart(defer);
}
void ServiceWorkerWriteToCacheJob::OnResponseStarted(
net::URLRequest* request) {
DCHECK_EQ(net_request_, request);
if (!request->status().is_success()) {
AsyncNotifyDoneHelper(request->status());
return;
}
if (request->GetResponseCode() / 100 != 2) {
AsyncNotifyDoneHelper(net::URLRequestStatus(
net::URLRequestStatus::FAILED, net::ERR_FAILED));
// TODO(michaeln): Instead of error'ing immediately, send the net
// response to our consumer, just don't cache it?
return;
}
WriteHeadersToCache();
}
void ServiceWorkerWriteToCacheJob::OnReadCompleted(
net::URLRequest* request,
int bytes_read) {
DCHECK_EQ(net_request_, request);
if (!request->status().is_success()) {
AsyncNotifyDoneHelper(request->status());
return;
}
if (bytes_read > 0) {
WriteDataToCache(bytes_read);
return;
}
// We're done with all.
AsyncNotifyDoneHelper(request->status());
return;
}
void ServiceWorkerWriteToCacheJob::AsyncNotifyDoneHelper(
const net::URLRequestStatus& status) {
DCHECK(!status.is_io_pending());
version_->script_cache_map()->NotifyFinishedCaching(
url_, status.is_success());
did_notify_finished_ = true;
SetStatus(status);
NotifyDone(status);
}
} // namespace content
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_WRITE_TO_CACHE_JOB_
#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_WRITE_TO_CACHE_JOB_
#include "base/memory/weak_ptr.h"
#include "content/browser/service_worker/service_worker_disk_cache.h"
#include "content/browser/service_worker/service_worker_version.h"
#include "content/common/content_export.h"
#include "content/common/service_worker/service_worker_status_code.h"
#include "content/common/service_worker/service_worker_types.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_job.h"
namespace content {
class ServiceWorkerContextCore;
class ServiceWorkerResponseWriter;
class ServiceWorkerVersions;
// A URLRequestJob derivative used to cache the main script
// and its imports during the initial install of a new version.
// Another separate URLRequest is started which will perform
// a network fetch. The response produced for that separate
// request is written to the service worker script cache and piped
// to the consumer of the ServiceWorkerWriteToCacheJob for delivery
// to the renderer process housing the worker.
class CONTENT_EXPORT ServiceWorkerWriteToCacheJob
: public net::URLRequestJob,
public net::URLRequest::Delegate {
public:
ServiceWorkerWriteToCacheJob(
net::URLRequest* request,
net::NetworkDelegate* network_delegate,
base::WeakPtr<ServiceWorkerContextCore> context,
ServiceWorkerVersion* version,
int64 response_id);
private:
virtual ~ServiceWorkerWriteToCacheJob();
// net::URLRequestJob overrides
virtual void Start() OVERRIDE;
virtual void Kill() OVERRIDE;
virtual net::LoadState GetLoadState() const OVERRIDE;
virtual bool GetCharset(std::string* charset) OVERRIDE;
virtual bool GetMimeType(std::string* mime_type) const OVERRIDE;
virtual void GetResponseInfo(net::HttpResponseInfo* info) OVERRIDE;
virtual int GetResponseCode() const OVERRIDE;
virtual void SetExtraRequestHeaders(
const net::HttpRequestHeaders& headers) OVERRIDE;
virtual bool ReadRawData(net::IOBuffer* buf,
int buf_size,
int *bytes_read) OVERRIDE;
const net::HttpResponseInfo* http_info() const;
// Methods to drive the net request forward and
// write data to the disk cache.
void InitNetRequest();
void StartNetRequest();
net::URLRequestStatus ReadNetData(
net::IOBuffer* buf,
int buf_size,
int *bytes_read);
void WriteHeadersToCache();
void OnWriteHeadersComplete(int result);
void WriteDataToCache(int bytes_to_write);
void OnWriteDataComplete(int result);
// net::URLRequest::Delegate overrides that observe the net request.
virtual void OnReceivedRedirect(
net::URLRequest* request,
const GURL& new_url,
bool* defer_redirect) OVERRIDE;
virtual void OnAuthRequired(
net::URLRequest* request,
net::AuthChallengeInfo* auth_info) OVERRIDE;
virtual void OnCertificateRequested(
net::URLRequest* request,
net::SSLCertRequestInfo* cert_request_info) OVERRIDE;
virtual void OnSSLCertificateError(
net::URLRequest* request,
const net::SSLInfo& ssl_info,
bool fatal) OVERRIDE;
virtual void OnBeforeNetworkStart(
net::URLRequest* request,
bool* defer) OVERRIDE;
virtual void OnResponseStarted(net::URLRequest* request) OVERRIDE;
virtual void OnReadCompleted(
net::URLRequest* request,
int bytes_read) OVERRIDE;
void AsyncNotifyDoneHelper(const net::URLRequestStatus& status);
scoped_refptr<net::IOBuffer> io_buffer_;
scoped_refptr<HttpResponseInfoIOBuffer> info_buffer_;
base::WeakPtr<ServiceWorkerContextCore> context_;
GURL url_;
int64 response_id_;
scoped_ptr<net::URLRequest> net_request_;
scoped_ptr<net::HttpResponseInfo> http_info_;
scoped_ptr<ServiceWorkerResponseWriter> writer_;
scoped_refptr<ServiceWorkerVersion> version_;
bool has_been_killed_;
bool did_notify_started_;
bool did_notify_finished_;
base::WeakPtrFactory<ServiceWorkerWriteToCacheJob> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerWriteToCacheJob);
};
} // namespace content
#endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_WRITE_TO_CACHE_JOB_
......@@ -1206,6 +1206,8 @@
'browser/service_worker/service_worker_utils.h',
'browser/service_worker/service_worker_version.cc',
'browser/service_worker/service_worker_version.h',
'browser/service_worker/service_worker_write_to_cache_job.cc',
'browser/service_worker/service_worker_write_to_cache_job.h',
'browser/shared_worker/shared_worker_host.cc',
'browser/shared_worker/shared_worker_host.h',
'browser/shared_worker/shared_worker_instance.cc',
......
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