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

Side by Side 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 unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/service_worker/service_worker_url_request_job.h" 5 #include "content/browser/service_worker/service_worker_url_request_job.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <limits> 10 #include <limits>
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
81 case m::REQUEST_JOB_ERROR_STREAM_ABORTED: 81 case m::REQUEST_JOB_ERROR_STREAM_ABORTED:
82 return n::TYPE_SERVICE_WORKER_ERROR_STREAM_ABORTED; 82 return n::TYPE_SERVICE_WORKER_ERROR_STREAM_ABORTED;
83 case m::REQUEST_JOB_ERROR_KILLED: 83 case m::REQUEST_JOB_ERROR_KILLED:
84 return n::TYPE_SERVICE_WORKER_ERROR_KILLED; 84 return n::TYPE_SERVICE_WORKER_ERROR_KILLED;
85 case m::REQUEST_JOB_ERROR_KILLED_WITH_BLOB: 85 case m::REQUEST_JOB_ERROR_KILLED_WITH_BLOB:
86 return n::TYPE_SERVICE_WORKER_ERROR_KILLED_WITH_BLOB; 86 return n::TYPE_SERVICE_WORKER_ERROR_KILLED_WITH_BLOB;
87 case m::REQUEST_JOB_ERROR_KILLED_WITH_STREAM: 87 case m::REQUEST_JOB_ERROR_KILLED_WITH_STREAM:
88 return n::TYPE_SERVICE_WORKER_ERROR_KILLED_WITH_STREAM; 88 return n::TYPE_SERVICE_WORKER_ERROR_KILLED_WITH_STREAM;
89 case m::REQUEST_JOB_ERROR_BAD_DELEGATE: 89 case m::REQUEST_JOB_ERROR_BAD_DELEGATE:
90 return n::TYPE_SERVICE_WORKER_ERROR_BAD_DELEGATE; 90 return n::TYPE_SERVICE_WORKER_ERROR_BAD_DELEGATE;
91 case m::REQUEST_JOB_ERROR_REQUEST_BODY_BLOB_FAILED:
92 return n::TYPE_SERVICE_WORKER_ERROR_REQUEST_BODY_BLOB_FAILED;
91 // We can't log if there's no request; fallthrough. 93 // We can't log if there's no request; fallthrough.
92 case m::REQUEST_JOB_ERROR_NO_REQUEST: 94 case m::REQUEST_JOB_ERROR_NO_REQUEST:
93 // Obsolete types; fallthrough. 95 // Obsolete types; fallthrough.
94 case m::REQUEST_JOB_ERROR_DESTROYED: 96 case m::REQUEST_JOB_ERROR_DESTROYED:
95 case m::REQUEST_JOB_ERROR_DESTROYED_WITH_BLOB: 97 case m::REQUEST_JOB_ERROR_DESTROYED_WITH_BLOB:
96 case m::REQUEST_JOB_ERROR_DESTROYED_WITH_STREAM: 98 case m::REQUEST_JOB_ERROR_DESTROYED_WITH_STREAM:
97 // Invalid type. 99 // Invalid type.
98 case m::NUM_REQUEST_JOB_RESULT_TYPES: 100 case m::NUM_REQUEST_JOB_RESULT_TYPES:
99 NOTREACHED() << result; 101 NOTREACHED() << result;
100 } 102 }
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after
396 void ServiceWorkerURLRequestJob::MaybeStartRequest() { 398 void ServiceWorkerURLRequestJob::MaybeStartRequest() {
397 if (is_started_ && response_type_ != NOT_DETERMINED) { 399 if (is_started_ && response_type_ != NOT_DETERMINED) {
398 // Start asynchronously. 400 // Start asynchronously.
399 base::ThreadTaskRunnerHandle::Get()->PostTask( 401 base::ThreadTaskRunnerHandle::Get()->PostTask(
400 FROM_HERE, base::Bind(&ServiceWorkerURLRequestJob::StartRequest, 402 FROM_HERE, base::Bind(&ServiceWorkerURLRequestJob::StartRequest,
401 weak_factory_.GetWeakPtr())); 403 weak_factory_.GetWeakPtr()));
402 } 404 }
403 } 405 }
404 406
405 void ServiceWorkerURLRequestJob::StartRequest() { 407 void ServiceWorkerURLRequestJob::StartRequest() {
406 if (request()) { 408 request()->net_log().AddEvent(net::NetLog::TYPE_SERVICE_WORKER_START_REQUEST);
407 request()->net_log().AddEvent(
408 net::NetLog::TYPE_SERVICE_WORKER_START_REQUEST);
409 }
410 409
411 switch (response_type_) { 410 switch (response_type_) {
412 case NOT_DETERMINED: 411 case NOT_DETERMINED:
413 NOTREACHED(); 412 NOTREACHED();
414 return; 413 return;
415 414
416 case FALLBACK_TO_NETWORK: 415 case FALLBACK_TO_NETWORK:
417 // Restart the request to create a new job. Our request handler will 416 // Restart the request to create a new job. Our request handler will
418 // return nullptr, and the default job (which will hit network) should be 417 // return nullptr, and the default job (which will hit network) should be
419 // created. 418 // created.
420 NotifyRestartRequired(); 419 NotifyRestartRequired();
421 return; 420 return;
422 421
423 case FORWARD_TO_SERVICE_WORKER: 422 case FORWARD_TO_SERVICE_WORKER:
424 ServiceWorkerMetrics::URLRequestJobResult result = 423 if (HasRequestBody()) {
425 ServiceWorkerMetrics::REQUEST_JOB_ERROR_BAD_DELEGATE; 424 WaitForRequestBobyBlobsToComplete();
426 ServiceWorkerVersion* active_worker =
427 delegate_->GetServiceWorkerVersion(&result);
428 if (!active_worker) {
429 RecordResult(result);
430 DeliverErrorResponse();
431 return; 425 return;
432 } 426 }
433 427
434 DCHECK(!fetch_dispatcher_); 428 DispatchToWorker();
435 // Send a fetch event to the ServiceWorker associated to the
436 // provider_host.
437 fetch_dispatcher_.reset(new ServiceWorkerFetchDispatcher(
438 CreateFetchRequest(), active_worker, resource_type_,
439 base::Bind(&ServiceWorkerURLRequestJob::DidPrepareFetchEvent,
440 weak_factory_.GetWeakPtr()),
441 base::Bind(&ServiceWorkerURLRequestJob::DidDispatchFetchEvent,
442 weak_factory_.GetWeakPtr())));
443 worker_start_time_ = base::TimeTicks::Now();
444 fetch_dispatcher_->Run();
445 return; 429 return;
446 } 430 }
447 431
448 NOTREACHED(); 432 NOTREACHED();
449 } 433 }
450 434
435 void ServiceWorkerURLRequestJob::DispatchToWorker() {
436 ServiceWorkerMetrics::URLRequestJobResult result =
437 ServiceWorkerMetrics::REQUEST_JOB_ERROR_BAD_DELEGATE;
438 ServiceWorkerVersion* active_worker =
439 delegate_->GetServiceWorkerVersion(&result);
440 if (!active_worker) {
441 RecordResult(result);
442 DeliverErrorResponse();
443 return;
444 }
445
446 DCHECK(!fetch_dispatcher_);
447 fetch_dispatcher_.reset(new ServiceWorkerFetchDispatcher(
448 CreateFetchRequest(), active_worker, resource_type_,
449 base::Bind(&ServiceWorkerURLRequestJob::DidPrepareFetchEvent,
450 weak_factory_.GetWeakPtr()),
451 base::Bind(&ServiceWorkerURLRequestJob::DidDispatchFetchEvent,
452 weak_factory_.GetWeakPtr())));
453 worker_start_time_ = base::TimeTicks::Now();
454 fetch_dispatcher_->Run();
455 }
456
451 std::unique_ptr<ServiceWorkerFetchRequest> 457 std::unique_ptr<ServiceWorkerFetchRequest>
452 ServiceWorkerURLRequestJob::CreateFetchRequest() { 458 ServiceWorkerURLRequestJob::CreateFetchRequest() {
453 std::string blob_uuid; 459 std::string blob_uuid;
454 uint64_t blob_size = 0; 460 uint64_t blob_size = 0;
455 // The upload data in URLRequest may have been cleared while handing redirect. 461 // The upload data in URLRequest may have been cleared while handing redirect.
456 if (request_->has_upload()) 462 if (request_->has_upload())
457 CreateRequestBodyBlob(&blob_uuid, &blob_size); 463 CreateRequestBodyBlob(&blob_uuid, &blob_size);
458 std::unique_ptr<ServiceWorkerFetchRequest> request( 464 std::unique_ptr<ServiceWorkerFetchRequest> request(
459 new ServiceWorkerFetchRequest()); 465 new ServiceWorkerFetchRequest());
460 request->mode = request_mode_; 466 request->mode = request_mode_;
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after
854 fall_back_required_, response_url_, 860 fall_back_required_, response_url_,
855 service_worker_response_type_, worker_start_time_, 861 service_worker_response_type_, worker_start_time_,
856 worker_ready_time_, response_is_in_cache_storage_, 862 worker_ready_time_, response_is_in_cache_storage_,
857 response_cache_storage_cache_name_); 863 response_cache_storage_cache_name_);
858 } 864 }
859 865
860 bool ServiceWorkerURLRequestJob::IsMainResourceLoad() const { 866 bool ServiceWorkerURLRequestJob::IsMainResourceLoad() const {
861 return ServiceWorkerUtils::IsMainResourceType(resource_type_); 867 return ServiceWorkerUtils::IsMainResourceType(resource_type_);
862 } 868 }
863 869
870 bool ServiceWorkerURLRequestJob::HasRequestBody() {
871 // |has_upload| must be checked since it may have been cleared while handling
872 // a redirect.
873 return request_->has_upload() && body_.get() && blob_storage_context_;
874 }
875
876 void ServiceWorkerURLRequestJob::WaitForRequestBobyBlobsToComplete() {
877 DCHECK(HasRequestBody());
878
879 num_pending_request_body_blobs_ = 0;
880 for (const ResourceRequestBody::Element& element : (*body_->elements())) {
881 if (element.type() == ResourceRequestBody::Element::TYPE_BLOB)
882 ++num_pending_request_body_blobs_;
883 }
884
885 if (num_pending_request_body_blobs_ == 0) {
886 DispatchToWorker();
887 return;
888 }
889
890 TRACE_EVENT_ASYNC_BEGIN1(
891 "ServiceWorker",
892 "ServiceWorkerURLRequestJob::WaitForRequestBobyBlobsToComplete", this,
893 "URL", request()->url().spec());
894 request()->net_log().AddEvent(
895 net::NetLog::TYPE_SERVICE_WORKER_REQUEST_BODY_BLOB_CONSTRUCTION_STARTED);
896
897 for (const ResourceRequestBody::Element& element : (*body_->elements())) {
898 if (element.type() == ResourceRequestBody::Element::TYPE_BLOB) {
899 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
900 blob_storage_context_->GetBlobDataFromUUID(element.blob_uuid());
901 handle->RunOnConstructionComplete(
902 base::Bind(&ServiceWorkerURLRequestJob::OneRequestBodyBlobCompleted,
903 GetWeakPtr()));
904 }
905 }
906 }
907
908 void ServiceWorkerURLRequestJob::OneRequestBodyBlobCompleted(
909 bool success,
910 storage::IPCBlobCreationCancelCode cancel_code) {
911 if (num_pending_request_body_blobs_ == 0) {
912 // We already ran the callback.
913 return;
914 }
915
916 if (success)
917 --num_pending_request_body_blobs_;
918 else
919 num_pending_request_body_blobs_ = 0;
920
921 if (num_pending_request_body_blobs_ == 0)
922 RequestBodyBlobsCompleted(success, cancel_code);
923 }
924
925 void ServiceWorkerURLRequestJob::RequestBodyBlobsCompleted(
926 bool success,
927 storage::IPCBlobCreationCancelCode cancel_code) {
928 TRACE_EVENT_ASYNC_END2(
929 "ServiceWorker",
930 "ServiceWorkerURLRequestJob::WaitForRequestBobyBlobsToComplete", this,
931 "Success", success, "IPCBlobCreationCancelCode",
932 static_cast<int>(cancel_code));
933
934 if (!success) {
935 RecordResult(
936 ServiceWorkerMetrics::REQUEST_JOB_ERROR_REQUEST_BODY_BLOB_FAILED);
937 NotifyStartError(net::URLRequestStatus::FromError(net::ERR_FAILED));
938 return;
939 }
940
941 request()->net_log().AddEvent(
942 net::NetLog::TYPE_SERVICE_WORKER_REQUEST_BODY_BLOB_CONSTRUCTION_FINISHED);
943 DispatchToWorker();
944 }
945
864 } // namespace content 946 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698