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

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

Issue 269373002: Store the service worker script and its imports on first load... kinda (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/browser/service_worker/service_worker_write_to_cache_job.cc
diff --git a/content/browser/service_worker/service_worker_write_to_cache_job.cc b/content/browser/service_worker/service_worker_write_to_cache_job.cc
new file mode 100644
index 0000000000000000000000000000000000000000..da11abcfbe5c8f11160f40c6ad3772066c8e66e0
--- /dev/null
+++ b/content/browser/service_worker/service_worker_write_to_cache_job.cc
@@ -0,0 +1,307 @@
+// Copyright (c) 2014 The Chromium Authors. All rights reserved.
nhiroki 2014/05/15 23:30:08 nit: can you remove "(c)" ?
michaeln 2014/05/15 23:54:30 i don't know why i keep ending up with this copy/p
+// 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),
+ response_id_(response_id),
+ version_(version),
+ has_been_killed_(false),
+ weak_factory_(this) {
+ InitNetRequest();
+}
+
+ServiceWorkerWriteToCacheJob::~ServiceWorkerWriteToCacheJob() {
+}
+
+void ServiceWorkerWriteToCacheJob::Start() {
+ if (!context_) {
+ NotifyStartError(net::URLRequestStatus(
+ net::URLRequestStatus::FAILED, net::ERR_FAILED));
+ return;
+ }
+ version_->script_cache_map()->NotifyStartedCaching(
+ request()->url(), response_id_);
+ StartNetRequest();
+}
+
+void ServiceWorkerWriteToCacheJob::Kill() {
+ if (has_been_killed_)
+ return;
+ weak_factory_.InvalidateWeakPtrs();
+ has_been_killed_ = true;
+ net_request_.reset();
+ 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;
+
nhiroki 2014/05/15 23:30:08 nit: an empty line.
michaeln 2014/05/15 23:54:30 Done.
+}
+
+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(
+ request()->url(), status.is_success());
kinuko 2014/05/15 16:55:00 Ok... so we only reach here when all main script i
michaeln 2014/05/15 23:54:30 yes, that's worth a comment somewhere, i'll drop s
+ 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,
+ NULL); // TODO(michaeln): request()->cookie_store()
+ 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.
+ 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.
+ 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(
kinuko 2014/05/15 16:55:00 Why it's called Async?
michaeln 2014/05/16 00:12:09 Oh well... this was a poor attempt to try to clari
+ const net::URLRequestStatus& status) {
+ DCHECK(!status.is_io_pending());
+ version_->script_cache_map()->NotifyFinishedCaching(
+ request()->url(), status.is_success());
+ SetStatus(status);
+ NotifyDone(status);
+}
+
+} // namespace content

Powered by Google App Engine
This is Rietveld 408576698