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

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

Issue 1967683003: service worker: Wait for request body blobs to finish construction (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 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_url_request_job.cc
diff --git a/content/browser/service_worker/service_worker_url_request_job.cc b/content/browser/service_worker/service_worker_url_request_job.cc
index 37daad262323d988763fe3ea282a44720c8ebb02..8cfc2699cc506385553797675df66f5a1883c936 100644
--- a/content/browser/service_worker/service_worker_url_request_job.cc
+++ b/content/browser/service_worker/service_worker_url_request_job.cc
@@ -88,6 +88,8 @@ net::NetLog::EventType RequestJobResultToNetEventType(
return n::TYPE_SERVICE_WORKER_ERROR_KILLED_WITH_STREAM;
case m::REQUEST_JOB_ERROR_BAD_DELEGATE:
return n::TYPE_SERVICE_WORKER_ERROR_BAD_DELEGATE;
+ case m::REQUEST_JOB_ERROR_REQUEST_BODY_BLOB_FAILED:
+ return n::TYPE_SERVICE_WORKER_ERROR_REQUEST_BODY_BLOB_FAILED;
// We can't log if there's no request; fallthrough.
case m::REQUEST_JOB_ERROR_NO_REQUEST:
// Obsolete types; fallthrough.
@@ -403,10 +405,7 @@ void ServiceWorkerURLRequestJob::MaybeStartRequest() {
}
void ServiceWorkerURLRequestJob::StartRequest() {
- if (request()) {
- request()->net_log().AddEvent(
- net::NetLog::TYPE_SERVICE_WORKER_START_REQUEST);
- }
+ request()->net_log().AddEvent(net::NetLog::TYPE_SERVICE_WORKER_START_REQUEST);
switch (response_type_) {
case NOT_DETERMINED:
@@ -421,33 +420,40 @@ void ServiceWorkerURLRequestJob::StartRequest() {
return;
case FORWARD_TO_SERVICE_WORKER:
- ServiceWorkerMetrics::URLRequestJobResult result =
- ServiceWorkerMetrics::REQUEST_JOB_ERROR_BAD_DELEGATE;
- ServiceWorkerVersion* active_worker =
- delegate_->GetServiceWorkerVersion(&result);
- if (!active_worker) {
- RecordResult(result);
- DeliverErrorResponse();
+ if (HasRequestBody()) {
+ WaitForRequestBobyBlobsToComplete();
return;
}
- DCHECK(!fetch_dispatcher_);
- // Send a fetch event to the ServiceWorker associated to the
- // provider_host.
- fetch_dispatcher_.reset(new ServiceWorkerFetchDispatcher(
- CreateFetchRequest(), active_worker, resource_type_,
- base::Bind(&ServiceWorkerURLRequestJob::DidPrepareFetchEvent,
- weak_factory_.GetWeakPtr()),
- base::Bind(&ServiceWorkerURLRequestJob::DidDispatchFetchEvent,
- weak_factory_.GetWeakPtr())));
- worker_start_time_ = base::TimeTicks::Now();
- fetch_dispatcher_->Run();
+ DispatchToWorker();
return;
}
NOTREACHED();
}
+void ServiceWorkerURLRequestJob::DispatchToWorker() {
+ ServiceWorkerMetrics::URLRequestJobResult result =
+ ServiceWorkerMetrics::REQUEST_JOB_ERROR_BAD_DELEGATE;
+ ServiceWorkerVersion* active_worker =
+ delegate_->GetServiceWorkerVersion(&result);
+ if (!active_worker) {
+ RecordResult(result);
+ DeliverErrorResponse();
+ return;
+ }
+
+ DCHECK(!fetch_dispatcher_);
+ fetch_dispatcher_.reset(new ServiceWorkerFetchDispatcher(
+ CreateFetchRequest(), active_worker, resource_type_,
+ base::Bind(&ServiceWorkerURLRequestJob::DidPrepareFetchEvent,
+ weak_factory_.GetWeakPtr()),
+ base::Bind(&ServiceWorkerURLRequestJob::DidDispatchFetchEvent,
+ weak_factory_.GetWeakPtr())));
+ worker_start_time_ = base::TimeTicks::Now();
+ fetch_dispatcher_->Run();
+}
+
std::unique_ptr<ServiceWorkerFetchRequest>
ServiceWorkerURLRequestJob::CreateFetchRequest() {
std::string blob_uuid;
@@ -861,4 +867,80 @@ bool ServiceWorkerURLRequestJob::IsMainResourceLoad() const {
return ServiceWorkerUtils::IsMainResourceType(resource_type_);
}
+bool ServiceWorkerURLRequestJob::HasRequestBody() {
+ // |has_upload| must be checked since it may have been cleared while handling
+ // a redirect.
+ return request_->has_upload() && body_.get() && blob_storage_context_;
+}
+
+void ServiceWorkerURLRequestJob::WaitForRequestBobyBlobsToComplete() {
+ DCHECK(HasRequestBody());
+
+ num_pending_request_body_blobs_ = 0;
+ for (const ResourceRequestBody::Element& element : (*body_->elements())) {
+ if (element.type() == ResourceRequestBody::Element::TYPE_BLOB)
+ ++num_pending_request_body_blobs_;
+ }
+
+ if (num_pending_request_body_blobs_ == 0) {
+ DispatchToWorker();
+ return;
+ }
+
+ TRACE_EVENT_ASYNC_BEGIN1(
+ "ServiceWorker",
+ "ServiceWorkerURLRequestJob::WaitForRequestBobyBlobsToComplete", this,
+ "URL", request()->url().spec());
+ request()->net_log().AddEvent(
+ net::NetLog::TYPE_SERVICE_WORKER_REQUEST_BODY_BLOB_CONSTRUCTION_STARTED);
+
+ for (const ResourceRequestBody::Element& element : (*body_->elements())) {
+ if (element.type() == ResourceRequestBody::Element::TYPE_BLOB) {
+ std::unique_ptr<storage::BlobDataHandle> handle =
dmurph 2016/05/11 21:35:58 You can check if the blob is building before calli
falken 2016/05/12 08:49:33 Done. I had considered that but was worried about
+ blob_storage_context_->GetBlobDataFromUUID(element.blob_uuid());
+ handle->RunOnConstructionComplete(
+ base::Bind(&ServiceWorkerURLRequestJob::OneRequestBodyBlobCompleted,
+ GetWeakPtr()));
+ }
+ }
+}
+
+void ServiceWorkerURLRequestJob::OneRequestBodyBlobCompleted(
+ bool success,
+ storage::IPCBlobCreationCancelCode cancel_code) {
+ if (num_pending_request_body_blobs_ == 0) {
+ // We already ran the callback.
+ return;
+ }
+
+ if (success)
+ --num_pending_request_body_blobs_;
+ else
+ num_pending_request_body_blobs_ = 0;
+
+ if (num_pending_request_body_blobs_ == 0)
+ RequestBodyBlobsCompleted(success, cancel_code);
+}
+
+void ServiceWorkerURLRequestJob::RequestBodyBlobsCompleted(
+ bool success,
+ storage::IPCBlobCreationCancelCode cancel_code) {
+ TRACE_EVENT_ASYNC_END2(
+ "ServiceWorker",
+ "ServiceWorkerURLRequestJob::WaitForRequestBobyBlobsToComplete", this,
+ "Success", success, "IPCBlobCreationCancelCode",
+ static_cast<int>(cancel_code));
+
+ if (!success) {
+ RecordResult(
+ ServiceWorkerMetrics::REQUEST_JOB_ERROR_REQUEST_BODY_BLOB_FAILED);
+ NotifyStartError(net::URLRequestStatus::FromError(net::ERR_FAILED));
+ return;
+ }
+
+ request()->net_log().AddEvent(
+ net::NetLog::TYPE_SERVICE_WORKER_REQUEST_BODY_BLOB_CONSTRUCTION_FINISHED);
+ DispatchToWorker();
+}
+
} // namespace content

Powered by Google App Engine
This is Rietveld 408576698