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

Side by Side Diff: content/browser/service_worker/service_worker_url_request_job.cc

Issue 1985383002: Logging and check fail crbug/612358 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: cleaned up logging 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 }
101 NOTREACHED() << result; 103 NOTREACHED() << result;
102 return n::TYPE_FAILED; 104 return n::TYPE_FAILED;
103 } 105 }
104 106
105 } // namespace 107 } // namespace
106 108
109 class ServiceWorkerURLRequestJob::BlobConstructionWaiter {
110 public:
111 explicit BlobConstructionWaiter(ServiceWorkerURLRequestJob* owner)
112 : owner_(owner), weak_factory_(this) {
113 TRACE_EVENT_ASYNC_BEGIN1("ServiceWorker", "BlobConstructionWaiter", this,
114 "URL", owner_->request()->url().spec());
115 owner_->request()->net_log().BeginEvent(
116 net::NetLog::TYPE_SERVICE_WORKER_WAITING_FOR_REQUEST_BODY_BLOB);
117 }
118
119 ~BlobConstructionWaiter() {
120 owner_->request()->net_log().EndEvent(
121 net::NetLog::TYPE_SERVICE_WORKER_WAITING_FOR_REQUEST_BODY_BLOB,
122 net::NetLog::BoolCallback("success", phase_ == Phase::SUCCESS));
123 TRACE_EVENT_ASYNC_END1("ServiceWorker", "BlobConstructionWaiter", this,
124 "Success", phase_ == Phase::SUCCESS);
125 }
126
127 void RunOnComplete(const base::Callback<void(bool)>& callback) {
128 DCHECK_EQ(static_cast<int>(Phase::INITIAL), static_cast<int>(phase_));
129 phase_ = Phase::WAITING;
130 num_pending_request_body_blobs_ = 0;
131 callback_ = callback;
132
133 for (const ResourceRequestBody::Element& element :
134 *(owner_->body_->elements())) {
135 if (element.type() != ResourceRequestBody::Element::TYPE_BLOB)
136 continue;
137
138 std::unique_ptr<storage::BlobDataHandle> handle =
139 owner_->blob_storage_context_->GetBlobDataFromUUID(
140 element.blob_uuid());
141 if (handle->IsBroken()) {
142 Complete(false);
143 return;
144 }
145 if (handle->IsBeingBuilt()) {
146 ++num_pending_request_body_blobs_;
147 handle->RunOnConstructionComplete(
148 base::Bind(&BlobConstructionWaiter::OneRequestBodyBlobCompleted,
149 weak_factory_.GetWeakPtr()));
150 }
151 }
152
153 if (num_pending_request_body_blobs_ == 0)
154 Complete(true);
155 }
156
157 private:
158 enum class Phase { INITIAL, WAITING, SUCCESS, FAIL };
159
160 void OneRequestBodyBlobCompleted(
161 bool success,
162 storage::IPCBlobCreationCancelCode cancel_code) {
163 DCHECK_GT(num_pending_request_body_blobs_, 0UL);
164
165 if (success)
166 --num_pending_request_body_blobs_;
167 else
168 num_pending_request_body_blobs_ = 0;
169
170 if (num_pending_request_body_blobs_ == 0)
171 Complete(success);
172 }
173
174 void Complete(bool success) {
175 DCHECK_EQ(static_cast<int>(Phase::WAITING), static_cast<int>(phase_));
176 phase_ = success ? Phase::SUCCESS : Phase::FAIL;
177 // Destroys |this|.
178 callback_.Run(success);
179 }
180
181 // Owns and must outlive |this|.
182 ServiceWorkerURLRequestJob* owner_;
183
184 scoped_refptr<ResourceRequestBody> body_;
185 base::Callback<void(bool)> callback_;
186 size_t num_pending_request_body_blobs_ = 0;
187 Phase phase_ = Phase::INITIAL;
188 base::WeakPtrFactory<BlobConstructionWaiter> weak_factory_;
189
190 DISALLOW_COPY_AND_ASSIGN(BlobConstructionWaiter);
191 };
192
107 bool ServiceWorkerURLRequestJob::Delegate::RequestStillValid( 193 bool ServiceWorkerURLRequestJob::Delegate::RequestStillValid(
108 ServiceWorkerMetrics::URLRequestJobResult* result) { 194 ServiceWorkerMetrics::URLRequestJobResult* result) {
109 return true; 195 return true;
110 } 196 }
111 197
112 ServiceWorkerURLRequestJob::ServiceWorkerURLRequestJob( 198 ServiceWorkerURLRequestJob::ServiceWorkerURLRequestJob(
113 net::URLRequest* request, 199 net::URLRequest* request,
114 net::NetworkDelegate* network_delegate, 200 net::NetworkDelegate* network_delegate,
115 const std::string& client_id, 201 const std::string& client_id,
116 base::WeakPtr<storage::BlobStorageContext> blob_storage_context, 202 base::WeakPtr<storage::BlobStorageContext> blob_storage_context,
(...skipping 24 matching lines...) Expand all
141 frame_type_(frame_type), 227 frame_type_(frame_type),
142 fall_back_required_(false), 228 fall_back_required_(false),
143 body_(body), 229 body_(body),
144 fetch_type_(fetch_type), 230 fetch_type_(fetch_type),
145 weak_factory_(this) { 231 weak_factory_(this) {
146 DCHECK(delegate_) << "ServiceWorkerURLRequestJob requires a delegate"; 232 DCHECK(delegate_) << "ServiceWorkerURLRequestJob requires a delegate";
147 } 233 }
148 234
149 ServiceWorkerURLRequestJob::~ServiceWorkerURLRequestJob() { 235 ServiceWorkerURLRequestJob::~ServiceWorkerURLRequestJob() {
150 ClearStream(); 236 ClearStream();
237 blob_construction_waiter_.reset();
151 238
152 if (!ShouldRecordResult()) 239 if (!ShouldRecordResult())
153 return; 240 return;
154 ServiceWorkerMetrics::URLRequestJobResult result = 241 ServiceWorkerMetrics::URLRequestJobResult result =
155 ServiceWorkerMetrics::REQUEST_JOB_ERROR_KILLED; 242 ServiceWorkerMetrics::REQUEST_JOB_ERROR_KILLED;
156 if (response_body_type_ == STREAM) 243 if (response_body_type_ == STREAM)
157 result = ServiceWorkerMetrics::REQUEST_JOB_ERROR_KILLED_WITH_STREAM; 244 result = ServiceWorkerMetrics::REQUEST_JOB_ERROR_KILLED_WITH_STREAM;
158 else if (response_body_type_ == BLOB) 245 else if (response_body_type_ == BLOB)
159 result = ServiceWorkerMetrics::REQUEST_JOB_ERROR_KILLED_WITH_BLOB; 246 result = ServiceWorkerMetrics::REQUEST_JOB_ERROR_KILLED_WITH_BLOB;
160 RecordResult(result); 247 RecordResult(result);
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
396 void ServiceWorkerURLRequestJob::MaybeStartRequest() { 483 void ServiceWorkerURLRequestJob::MaybeStartRequest() {
397 if (is_started_ && response_type_ != NOT_DETERMINED) { 484 if (is_started_ && response_type_ != NOT_DETERMINED) {
398 // Start asynchronously. 485 // Start asynchronously.
399 base::ThreadTaskRunnerHandle::Get()->PostTask( 486 base::ThreadTaskRunnerHandle::Get()->PostTask(
400 FROM_HERE, base::Bind(&ServiceWorkerURLRequestJob::StartRequest, 487 FROM_HERE, base::Bind(&ServiceWorkerURLRequestJob::StartRequest,
401 weak_factory_.GetWeakPtr())); 488 weak_factory_.GetWeakPtr()));
402 } 489 }
403 } 490 }
404 491
405 void ServiceWorkerURLRequestJob::StartRequest() { 492 void ServiceWorkerURLRequestJob::StartRequest() {
406 if (request()) { 493 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 494
411 switch (response_type_) { 495 switch (response_type_) {
412 case NOT_DETERMINED: 496 case NOT_DETERMINED:
413 NOTREACHED(); 497 NOTREACHED();
414 return; 498 return;
415 499
416 case FALLBACK_TO_NETWORK: 500 case FALLBACK_TO_NETWORK:
417 // Restart the request to create a new job. Our request handler will 501 // 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 502 // return nullptr, and the default job (which will hit network) should be
419 // created. 503 // created.
420 NotifyRestartRequired(); 504 NotifyRestartRequired();
421 return; 505 return;
422 506
423 case FORWARD_TO_SERVICE_WORKER: 507 case FORWARD_TO_SERVICE_WORKER:
424 ServiceWorkerMetrics::URLRequestJobResult result = 508 if (HasRequestBody()) {
425 ServiceWorkerMetrics::REQUEST_JOB_ERROR_BAD_DELEGATE; 509 DCHECK(!blob_construction_waiter_);
426 ServiceWorkerVersion* active_worker = 510 blob_construction_waiter_.reset(new BlobConstructionWaiter(this));
427 delegate_->GetServiceWorkerVersion(&result); 511 blob_construction_waiter_->RunOnComplete(
428 if (!active_worker) { 512 base::Bind(&ServiceWorkerURLRequestJob::RequestBodyBlobsCompleted,
429 RecordResult(result); 513 GetWeakPtr()));
430 DeliverErrorResponse();
431 return; 514 return;
432 } 515 }
433 516
434 DCHECK(!fetch_dispatcher_); 517 RequestBodyBlobsCompleted(true);
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; 518 return;
446 } 519 }
447 520
448 NOTREACHED(); 521 NOTREACHED();
449 } 522 }
450 523
451 std::unique_ptr<ServiceWorkerFetchRequest> 524 std::unique_ptr<ServiceWorkerFetchRequest>
452 ServiceWorkerURLRequestJob::CreateFetchRequest() { 525 ServiceWorkerURLRequestJob::CreateFetchRequest() {
453 std::string blob_uuid; 526 std::string blob_uuid;
454 uint64_t blob_size = 0; 527 uint64_t blob_size = 0;
455 // The upload data in URLRequest may have been cleared while handing redirect. 528 if (HasRequestBody())
456 if (request_->has_upload())
457 CreateRequestBodyBlob(&blob_uuid, &blob_size); 529 CreateRequestBodyBlob(&blob_uuid, &blob_size);
458 std::unique_ptr<ServiceWorkerFetchRequest> request( 530 std::unique_ptr<ServiceWorkerFetchRequest> request(
459 new ServiceWorkerFetchRequest()); 531 new ServiceWorkerFetchRequest());
460 request->mode = request_mode_; 532 request->mode = request_mode_;
461 request->is_main_resource_load = IsMainResourceLoad(); 533 request->is_main_resource_load = IsMainResourceLoad();
462 request->request_context_type = request_context_type_; 534 request->request_context_type = request_context_type_;
463 request->frame_type = frame_type_; 535 request->frame_type = frame_type_;
464 request->url = request_->url(); 536 request->url = request_->url();
465 request->method = request_->method(); 537 request->method = request_->method();
466 const net::HttpRequestHeaders& headers = request_->extra_request_headers(); 538 const net::HttpRequestHeaders& headers = request_->extra_request_headers();
(...skipping 17 matching lines...) Expand all
484 CHECK( 556 CHECK(
485 request_->referrer_policy() == 557 request_->referrer_policy() ==
486 net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE); 558 net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE);
487 request->referrer = 559 request->referrer =
488 Referrer(GURL(request_->referrer()), blink::WebReferrerPolicyDefault); 560 Referrer(GURL(request_->referrer()), blink::WebReferrerPolicyDefault);
489 } 561 }
490 request->fetch_type = fetch_type_; 562 request->fetch_type = fetch_type_;
491 return request; 563 return request;
492 } 564 }
493 565
494 bool ServiceWorkerURLRequestJob::CreateRequestBodyBlob(std::string* blob_uuid, 566 void ServiceWorkerURLRequestJob::CreateRequestBodyBlob(std::string* blob_uuid,
495 uint64_t* blob_size) { 567 uint64_t* blob_size) {
496 if (!body_.get() || !blob_storage_context_) 568 DCHECK(HasRequestBody());
497 return false;
498
499 // To ensure the blobs stick around until the end of the reading. 569 // To ensure the blobs stick around until the end of the reading.
500 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles; 570 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles;
501 std::vector<std::unique_ptr<storage::BlobDataSnapshot>> snapshots; 571 std::vector<std::unique_ptr<storage::BlobDataSnapshot>> snapshots;
502 // TODO(dmurph): Allow blobs to be added below, so that the context can 572 // TODO(dmurph): Allow blobs to be added below, so that the context can
503 // efficiently re-use blob items for the new blob. 573 // efficiently re-use blob items for the new blob.
504 std::vector<const ResourceRequestBody::Element*> resolved_elements; 574 std::vector<const ResourceRequestBody::Element*> resolved_elements;
505 for (const ResourceRequestBody::Element& element : (*body_->elements())) { 575 for (const ResourceRequestBody::Element& element : (*body_->elements())) {
506 if (element.type() != ResourceRequestBody::Element::TYPE_BLOB) { 576 if (element.type() != ResourceRequestBody::Element::TYPE_BLOB) {
507 resolved_elements.push_back(&element); 577 resolved_elements.push_back(&element);
508 continue; 578 continue;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
553 break; 623 break;
554 default: 624 default:
555 NOTIMPLEMENTED(); 625 NOTIMPLEMENTED();
556 } 626 }
557 } 627 }
558 628
559 request_body_blob_data_handle_ = 629 request_body_blob_data_handle_ =
560 blob_storage_context_->AddFinishedBlob(&blob_builder); 630 blob_storage_context_->AddFinishedBlob(&blob_builder);
561 *blob_uuid = uuid; 631 *blob_uuid = uuid;
562 *blob_size = total_size; 632 *blob_size = total_size;
563 return true;
564 } 633 }
565 634
566 void ServiceWorkerURLRequestJob::DidPrepareFetchEvent() { 635 void ServiceWorkerURLRequestJob::DidPrepareFetchEvent() {
567 worker_ready_time_ = base::TimeTicks::Now(); 636 worker_ready_time_ = base::TimeTicks::Now();
568 load_timing_info_.send_start = worker_ready_time_; 637 load_timing_info_.send_start = worker_ready_time_;
569 } 638 }
570 639
571 void ServiceWorkerURLRequestJob::DidDispatchFetchEvent( 640 void ServiceWorkerURLRequestJob::DidDispatchFetchEvent(
572 ServiceWorkerStatusCode status, 641 ServiceWorkerStatusCode status,
573 ServiceWorkerFetchEventResult fetch_result, 642 ServiceWorkerFetchEventResult fetch_result,
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after
854 fall_back_required_, response_url_, 923 fall_back_required_, response_url_,
855 service_worker_response_type_, worker_start_time_, 924 service_worker_response_type_, worker_start_time_,
856 worker_ready_time_, response_is_in_cache_storage_, 925 worker_ready_time_, response_is_in_cache_storage_,
857 response_cache_storage_cache_name_); 926 response_cache_storage_cache_name_);
858 } 927 }
859 928
860 bool ServiceWorkerURLRequestJob::IsMainResourceLoad() const { 929 bool ServiceWorkerURLRequestJob::IsMainResourceLoad() const {
861 return ServiceWorkerUtils::IsMainResourceType(resource_type_); 930 return ServiceWorkerUtils::IsMainResourceType(resource_type_);
862 } 931 }
863 932
933 bool ServiceWorkerURLRequestJob::HasRequestBody() {
934 // URLRequest::has_upload() must be checked since its upload data may have
935 // been cleared while handling a redirect.
936 return request_->has_upload() && body_.get() && blob_storage_context_;
937 }
938
939 void ServiceWorkerURLRequestJob::RequestBodyBlobsCompleted(bool success) {
940 blob_construction_waiter_.reset();
941 if (!success) {
942 RecordResult(
943 ServiceWorkerMetrics::REQUEST_JOB_ERROR_REQUEST_BODY_BLOB_FAILED);
944 // TODO(falken): This and below should probably be NotifyStartError, not
945 // DeliverErrorResponse. But changing it causes
946 // ServiceWorkerURLRequestJobTest.DeletedProviderHostBeforeFetchEvent to
947 // fail.
948 DeliverErrorResponse();
949 return;
950 }
951
952 ServiceWorkerMetrics::URLRequestJobResult result =
953 ServiceWorkerMetrics::REQUEST_JOB_ERROR_BAD_DELEGATE;
954 ServiceWorkerVersion* active_worker =
955 delegate_->GetServiceWorkerVersion(&result);
956 if (!active_worker) {
957 RecordResult(result);
958 DeliverErrorResponse();
959 return;
960 }
961
962 DCHECK(!fetch_dispatcher_);
963 fetch_dispatcher_.reset(new ServiceWorkerFetchDispatcher(
964 CreateFetchRequest(), active_worker, resource_type_,
965 base::Bind(&ServiceWorkerURLRequestJob::DidPrepareFetchEvent,
966 weak_factory_.GetWeakPtr()),
967 base::Bind(&ServiceWorkerURLRequestJob::DidDispatchFetchEvent,
968 weak_factory_.GetWeakPtr())));
969 worker_start_time_ = base::TimeTicks::Now();
970 fetch_dispatcher_->Run();
971 }
972
864 } // namespace content 973 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698