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

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

Issue 2290453005: service worker: Refactor blob reading out of ServiceWorkerURLRequestJob (Closed)
Patch Set: Created 4 years, 3 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>
11 #include <map> 11 #include <map>
12 #include <string> 12 #include <string>
13 #include <utility> 13 #include <utility>
14 #include <vector> 14 #include <vector>
15 15
16 #include "base/bind.h" 16 #include "base/bind.h"
17 #include "base/guid.h" 17 #include "base/guid.h"
18 #include "base/location.h" 18 #include "base/location.h"
19 #include "base/single_thread_task_runner.h" 19 #include "base/single_thread_task_runner.h"
20 #include "base/strings/stringprintf.h" 20 #include "base/strings/stringprintf.h"
21 #include "base/threading/thread_task_runner_handle.h" 21 #include "base/threading/thread_task_runner_handle.h"
22 #include "base/time/time.h" 22 #include "base/time/time.h"
23 #include "content/browser/resource_context_impl.h" 23 #include "content/browser/resource_context_impl.h"
24 #include "content/browser/service_worker/embedded_worker_instance.h" 24 #include "content/browser/service_worker/embedded_worker_instance.h"
25 #include "content/browser/service_worker/service_worker_blob_reader.h"
25 #include "content/browser/service_worker/service_worker_fetch_dispatcher.h" 26 #include "content/browser/service_worker/service_worker_fetch_dispatcher.h"
26 #include "content/browser/service_worker/service_worker_provider_host.h" 27 #include "content/browser/service_worker/service_worker_provider_host.h"
27 #include "content/browser/service_worker/service_worker_response_info.h" 28 #include "content/browser/service_worker/service_worker_response_info.h"
28 #include "content/browser/streams/stream.h" 29 #include "content/browser/streams/stream.h"
29 #include "content/browser/streams/stream_context.h" 30 #include "content/browser/streams/stream_context.h"
30 #include "content/browser/streams/stream_registry.h" 31 #include "content/browser/streams/stream_registry.h"
31 #include "content/common/resource_request_body_impl.h" 32 #include "content/common/resource_request_body_impl.h"
32 #include "content/common/service_worker/service_worker_types.h" 33 #include "content/common/service_worker/service_worker_types.h"
33 #include "content/common/service_worker/service_worker_utils.h" 34 #include "content/common/service_worker/service_worker_utils.h"
34 #include "content/public/browser/blob_handle.h" 35 #include "content/public/browser/blob_handle.h"
35 #include "content/public/browser/resource_request_info.h" 36 #include "content/public/browser/resource_request_info.h"
36 #include "content/public/browser/service_worker_context.h" 37 #include "content/public/browser/service_worker_context.h"
37 #include "content/public/common/referrer.h" 38 #include "content/public/common/referrer.h"
38 #include "net/base/net_errors.h" 39 #include "net/base/net_errors.h"
39 #include "net/http/http_request_headers.h" 40 #include "net/http/http_request_headers.h"
40 #include "net/http/http_response_headers.h" 41 #include "net/http/http_response_headers.h"
41 #include "net/http/http_response_info.h" 42 #include "net/http/http_response_info.h"
42 #include "net/http/http_util.h" 43 #include "net/http/http_util.h"
43 #include "net/log/net_log.h" 44 #include "net/log/net_log.h"
44 #include "storage/browser/blob/blob_data_builder.h" 45 #include "storage/browser/blob/blob_data_builder.h"
45 #include "storage/browser/blob/blob_data_handle.h" 46 #include "storage/browser/blob/blob_data_handle.h"
46 #include "storage/browser/blob/blob_storage_context.h" 47 #include "storage/browser/blob/blob_storage_context.h"
47 #include "storage/browser/blob/blob_url_request_job_factory.h"
48 #include "ui/base/page_transition_types.h" 48 #include "ui/base/page_transition_types.h"
49 49
50 namespace content { 50 namespace content {
51 51
52 namespace { 52 namespace {
53 53
54 net::NetLog::EventType RequestJobResultToNetEventType( 54 net::NetLog::EventType RequestJobResultToNetEventType(
55 ServiceWorkerMetrics::URLRequestJobResult result) { 55 ServiceWorkerMetrics::URLRequestJobResult result) {
56 using n = net::NetLog; 56 using n = net::NetLog;
57 using m = ServiceWorkerMetrics; 57 using m = ServiceWorkerMetrics;
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
273 273
274 void ServiceWorkerURLRequestJob::Start() { 274 void ServiceWorkerURLRequestJob::Start() {
275 is_started_ = true; 275 is_started_ = true;
276 MaybeStartRequest(); 276 MaybeStartRequest();
277 } 277 }
278 278
279 void ServiceWorkerURLRequestJob::Kill() { 279 void ServiceWorkerURLRequestJob::Kill() {
280 net::URLRequestJob::Kill(); 280 net::URLRequestJob::Kill();
281 ClearStream(); 281 ClearStream();
282 fetch_dispatcher_.reset(); 282 fetch_dispatcher_.reset();
283 blob_request_.reset(); 283 blob_reader_.reset();
284 weak_factory_.InvalidateWeakPtrs(); 284 weak_factory_.InvalidateWeakPtrs();
285 } 285 }
286 286
287 net::LoadState ServiceWorkerURLRequestJob::GetLoadState() const { 287 net::LoadState ServiceWorkerURLRequestJob::GetLoadState() const {
288 // TODO(kinuko): refine this for better debug. 288 // TODO(kinuko): refine this for better debug.
289 return net::URLRequestJob::GetLoadState(); 289 return net::URLRequestJob::GetLoadState();
290 } 290 }
291 291
292 bool ServiceWorkerURLRequestJob::GetCharset(std::string* charset) { 292 bool ServiceWorkerURLRequestJob::GetCharset(std::string* charset) {
293 if (!http_info()) 293 if (!http_info())
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 // We don't support multiple range requests in one single URL request. 333 // We don't support multiple range requests in one single URL request.
334 if (ranges.size() == 1U) 334 if (ranges.size() == 1U)
335 byte_range_ = ranges[0]; 335 byte_range_ = ranges[0];
336 } 336 }
337 337
338 int ServiceWorkerURLRequestJob::ReadRawData(net::IOBuffer* buf, int buf_size) { 338 int ServiceWorkerURLRequestJob::ReadRawData(net::IOBuffer* buf, int buf_size) {
339 DCHECK(buf); 339 DCHECK(buf);
340 DCHECK_GE(buf_size, 0); 340 DCHECK_GE(buf_size, 0);
341 DCHECK(waiting_stream_url_.is_empty()); 341 DCHECK(waiting_stream_url_.is_empty());
342 342
343 int bytes_read = 0;
344
345 if (stream_.get()) { 343 if (stream_.get()) {
344 int bytes_read = 0;
346 switch (stream_->ReadRawData(buf, buf_size, &bytes_read)) { 345 switch (stream_->ReadRawData(buf, buf_size, &bytes_read)) {
347 case Stream::STREAM_HAS_DATA: 346 case Stream::STREAM_HAS_DATA:
348 DCHECK_GT(bytes_read, 0); 347 DCHECK_GT(bytes_read, 0);
349 return bytes_read; 348 return bytes_read;
350 case Stream::STREAM_COMPLETE: 349 case Stream::STREAM_COMPLETE:
351 DCHECK_EQ(0, bytes_read); 350 DCHECK_EQ(0, bytes_read);
352 RecordResult(ServiceWorkerMetrics::REQUEST_JOB_STREAM_RESPONSE); 351 RecordResult(ServiceWorkerMetrics::REQUEST_JOB_STREAM_RESPONSE);
353 return 0; 352 return 0;
354 case Stream::STREAM_EMPTY: 353 case Stream::STREAM_EMPTY:
355 stream_pending_buffer_ = buf; 354 stream_pending_buffer_ = buf;
356 stream_pending_buffer_size_ = buf_size; 355 stream_pending_buffer_size_ = buf_size;
357 return net::ERR_IO_PENDING; 356 return net::ERR_IO_PENDING;
358 case Stream::STREAM_ABORTED: 357 case Stream::STREAM_ABORTED:
359 // Handle this as connection reset. 358 // Handle this as connection reset.
360 RecordResult(ServiceWorkerMetrics::REQUEST_JOB_ERROR_STREAM_ABORTED); 359 RecordResult(ServiceWorkerMetrics::REQUEST_JOB_ERROR_STREAM_ABORTED);
361 return net::ERR_CONNECTION_RESET; 360 return net::ERR_CONNECTION_RESET;
362 } 361 }
363 NOTREACHED(); 362 NOTREACHED();
364 return net::ERR_FAILED; 363 return net::ERR_FAILED;
365 } 364 }
366 365
367 if (!blob_request_) 366 if (blob_reader_)
368 return 0; 367 return blob_reader_->ReadRawData(buf, buf_size);
369 blob_request_->Read(buf, buf_size, &bytes_read); 368
370 net::URLRequestStatus status = blob_request_->status(); 369 return 0;
371 if (status.status() != net::URLRequestStatus::SUCCESS)
372 return status.error();
373 if (bytes_read == 0)
374 RecordResult(ServiceWorkerMetrics::REQUEST_JOB_BLOB_RESPONSE);
375 return bytes_read;
376 } 370 }
377 371
378 // TODO(falken): Refactor Blob and Stream specific handling to separate classes. 372 void ServiceWorkerURLRequestJob::OnResponseStarted() {
379 // Overrides for Blob reading -------------------------------------------------
380
381 void ServiceWorkerURLRequestJob::OnReceivedRedirect(
382 net::URLRequest* request,
383 const net::RedirectInfo& redirect_info,
384 bool* defer_redirect) {
385 NOTREACHED();
386 }
387
388 void ServiceWorkerURLRequestJob::OnAuthRequired(
389 net::URLRequest* request,
390 net::AuthChallengeInfo* auth_info) {
391 NOTREACHED();
392 }
393
394 void ServiceWorkerURLRequestJob::OnCertificateRequested(
395 net::URLRequest* request,
396 net::SSLCertRequestInfo* cert_request_info) {
397 NOTREACHED();
398 }
399
400 void ServiceWorkerURLRequestJob::OnSSLCertificateError(
401 net::URLRequest* request,
402 const net::SSLInfo& ssl_info,
403 bool fatal) {
404 NOTREACHED();
405 }
406
407 void ServiceWorkerURLRequestJob::OnResponseStarted(net::URLRequest* request) {
408 // TODO(falken): Add Content-Length, Content-Type if they were not provided in
409 // the ServiceWorkerResponse.
410 if (response_time_.is_null()) 373 if (response_time_.is_null())
411 response_time_ = base::Time::Now(); 374 response_time_ = base::Time::Now();
412 CommitResponseHeader(); 375 CommitResponseHeader();
413 } 376 }
414 377
415 void ServiceWorkerURLRequestJob::OnReadCompleted(net::URLRequest* request, 378 void ServiceWorkerURLRequestJob::OnReadRawDataComplete(int bytes_read) {
416 int bytes_read) { 379 ReadRawDataComplete(bytes_read);
417 if (!request->status().is_success()) {
418 RecordResult(ServiceWorkerMetrics::REQUEST_JOB_ERROR_BLOB_READ);
419 } else if (bytes_read == 0) {
420 RecordResult(ServiceWorkerMetrics::REQUEST_JOB_BLOB_RESPONSE);
421 }
422 net::URLRequestStatus status = request->status();
423 ReadRawDataComplete(status.is_success() ? bytes_read : status.error());
424 } 380 }
425 381
382 void ServiceWorkerURLRequestJob::RecordResult(
383 ServiceWorkerMetrics::URLRequestJobResult result) {
384 // It violates style guidelines to handle a NOTREACHED() failure but if there
385 // is a bug don't let it corrupt UMA results by double-counting.
386 if (!ShouldRecordResult()) {
387 NOTREACHED();
388 return;
389 }
390 did_record_result_ = true;
391 ServiceWorkerMetrics::RecordURLRequestJobResult(IsMainResourceLoad(), result);
392 if (request()) {
393 request()->net_log().AddEvent(RequestJobResultToNetEventType(result));
394 }
395 }
396
397 // TODO(falken): Refactor Stream specific handling to a separate class.
426 // Overrides for Stream reading ----------------------------------------------- 398 // Overrides for Stream reading -----------------------------------------------
427 399
428 void ServiceWorkerURLRequestJob::OnDataAvailable(Stream* stream) { 400 void ServiceWorkerURLRequestJob::OnDataAvailable(Stream* stream) {
429 // Do nothing if stream_pending_buffer_ is empty, i.e. there's no ReadRawData 401 // Do nothing if stream_pending_buffer_ is empty, i.e. there's no ReadRawData
430 // operation waiting for IO completion. 402 // operation waiting for IO completion.
431 if (!stream_pending_buffer_.get()) 403 if (!stream_pending_buffer_.get())
432 return; 404 return;
433 405
434 // stream_pending_buffer_ is set to the IOBuffer instance provided to 406 // stream_pending_buffer_ is set to the IOBuffer instance provided to
435 // ReadRawData() by URLRequestJob. 407 // ReadRawData() by URLRequestJob.
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
780 if (!response.blob_uuid.empty() && blob_storage_context_) { 752 if (!response.blob_uuid.empty() && blob_storage_context_) {
781 SetResponseBodyType(BLOB); 753 SetResponseBodyType(BLOB);
782 std::unique_ptr<storage::BlobDataHandle> blob_data_handle = 754 std::unique_ptr<storage::BlobDataHandle> blob_data_handle =
783 blob_storage_context_->GetBlobDataFromUUID(response.blob_uuid); 755 blob_storage_context_->GetBlobDataFromUUID(response.blob_uuid);
784 if (!blob_data_handle) { 756 if (!blob_data_handle) {
785 // The renderer gave us a bad blob UUID. 757 // The renderer gave us a bad blob UUID.
786 RecordResult(ServiceWorkerMetrics::REQUEST_JOB_ERROR_BAD_BLOB); 758 RecordResult(ServiceWorkerMetrics::REQUEST_JOB_ERROR_BAD_BLOB);
787 DeliverErrorResponse(); 759 DeliverErrorResponse();
788 return; 760 return;
789 } 761 }
790 blob_request_ = storage::BlobProtocolHandler::CreateBlobRequest( 762 blob_reader_.reset(new ServiceWorkerBlobReader(this));
791 std::move(blob_data_handle), request()->context(), this); 763 blob_reader_->Start(std::move(blob_data_handle), request()->context());
792 blob_request_->Start();
793 } 764 }
794 765
795 SetResponse(response); 766 SetResponse(response);
796 767 if (!blob_reader_) {
797 if (!blob_request_) {
798 RecordResult(ServiceWorkerMetrics::REQUEST_JOB_HEADERS_ONLY_RESPONSE); 768 RecordResult(ServiceWorkerMetrics::REQUEST_JOB_HEADERS_ONLY_RESPONSE);
799 CommitResponseHeader(); 769 CommitResponseHeader();
800 } 770 }
801 } 771 }
802 772
803 void ServiceWorkerURLRequestJob::SetResponse( 773 void ServiceWorkerURLRequestJob::SetResponse(
804 const ServiceWorkerResponse& response) { 774 const ServiceWorkerResponse& response) {
805 response_url_ = response.url; 775 response_url_ = response.url;
806 service_worker_response_type_ = response.response_type; 776 service_worker_response_type_ = response.response_type;
807 cors_exposed_header_names_ = response.cors_exposed_header_names; 777 cors_exposed_header_names_ = response.cors_exposed_header_names;
(...skipping 27 matching lines...) Expand all
835 http_response_headers_->AddHeader(header); 805 http_response_headers_->AddHeader(header);
836 } 806 }
837 } 807 }
838 808
839 void ServiceWorkerURLRequestJob::CommitResponseHeader() { 809 void ServiceWorkerURLRequestJob::CommitResponseHeader() {
840 if (!http_response_info_) 810 if (!http_response_info_)
841 http_response_info_.reset(new net::HttpResponseInfo()); 811 http_response_info_.reset(new net::HttpResponseInfo());
842 http_response_info_->headers.swap(http_response_headers_); 812 http_response_info_->headers.swap(http_response_headers_);
843 http_response_info_->vary_data = net::HttpVaryData(); 813 http_response_info_->vary_data = net::HttpVaryData();
844 http_response_info_->metadata = 814 http_response_info_->metadata =
845 blob_request_ ? blob_request_->response_info().metadata : nullptr; 815 blob_reader_ ? blob_reader_->response_metadata() : nullptr;
846 NotifyHeadersComplete(); 816 NotifyHeadersComplete();
847 } 817 }
848 818
849 void ServiceWorkerURLRequestJob::DeliverErrorResponse() { 819 void ServiceWorkerURLRequestJob::DeliverErrorResponse() {
850 // TODO(falken): Print an error to the console of the ServiceWorker and of 820 // TODO(falken): Print an error to the console of the ServiceWorker and of
851 // the requesting page. 821 // the requesting page.
852 CreateResponseHeader( 822 CreateResponseHeader(
853 500, "Service Worker Response Error", ServiceWorkerHeaderMap()); 823 500, "Service Worker Response Error", ServiceWorkerHeaderMap());
854 CommitResponseHeader(); 824 CommitResponseHeader();
855 } 825 }
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
901 DCHECK_EQ(response_body_type_, UNKNOWN); 871 DCHECK_EQ(response_body_type_, UNKNOWN);
902 DCHECK_NE(type, UNKNOWN); 872 DCHECK_NE(type, UNKNOWN);
903 response_body_type_ = type; 873 response_body_type_ = type;
904 } 874 }
905 875
906 bool ServiceWorkerURLRequestJob::ShouldRecordResult() { 876 bool ServiceWorkerURLRequestJob::ShouldRecordResult() {
907 return !did_record_result_ && is_started_ && 877 return !did_record_result_ && is_started_ &&
908 response_type_ == FORWARD_TO_SERVICE_WORKER; 878 response_type_ == FORWARD_TO_SERVICE_WORKER;
909 } 879 }
910 880
911 void ServiceWorkerURLRequestJob::RecordResult(
912 ServiceWorkerMetrics::URLRequestJobResult result) {
913 // It violates style guidelines to handle a NOTREACHED() failure but if there
914 // is a bug don't let it corrupt UMA results by double-counting.
915 if (!ShouldRecordResult()) {
916 NOTREACHED();
917 return;
918 }
919 did_record_result_ = true;
920 ServiceWorkerMetrics::RecordURLRequestJobResult(IsMainResourceLoad(), result);
921 if (request())
922 request()->net_log().AddEvent(RequestJobResultToNetEventType(result));
923 }
924
925 void ServiceWorkerURLRequestJob::RecordStatusZeroResponseError( 881 void ServiceWorkerURLRequestJob::RecordStatusZeroResponseError(
926 blink::WebServiceWorkerResponseError error) { 882 blink::WebServiceWorkerResponseError error) {
927 // It violates style guidelines to handle a NOTREACHED() failure but if there 883 // It violates style guidelines to handle a NOTREACHED() failure but if there
928 // is a bug don't let it corrupt UMA results by double-counting. 884 // is a bug don't let it corrupt UMA results by double-counting.
929 if (!ShouldRecordResult()) { 885 if (!ShouldRecordResult()) {
930 NOTREACHED(); 886 NOTREACHED();
931 return; 887 return;
932 } 888 }
933 RecordResult(ServiceWorkerMetrics::REQUEST_JOB_ERROR_RESPONSE_STATUS_ZERO); 889 RecordResult(ServiceWorkerMetrics::REQUEST_JOB_ERROR_RESPONSE_STATUS_ZERO);
934 ServiceWorkerMetrics::RecordStatusZeroResponseError(IsMainResourceLoad(), 890 ServiceWorkerMetrics::RecordStatusZeroResponseError(IsMainResourceLoad(),
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
1039 CreateFetchRequest(), active_worker, resource_type_, request()->net_log(), 995 CreateFetchRequest(), active_worker, resource_type_, request()->net_log(),
1040 base::Bind(&ServiceWorkerURLRequestJob::DidPrepareFetchEvent, 996 base::Bind(&ServiceWorkerURLRequestJob::DidPrepareFetchEvent,
1041 weak_factory_.GetWeakPtr(), active_worker), 997 weak_factory_.GetWeakPtr(), active_worker),
1042 base::Bind(&ServiceWorkerURLRequestJob::DidDispatchFetchEvent, 998 base::Bind(&ServiceWorkerURLRequestJob::DidDispatchFetchEvent,
1043 weak_factory_.GetWeakPtr()))); 999 weak_factory_.GetWeakPtr())));
1044 worker_start_time_ = base::TimeTicks::Now(); 1000 worker_start_time_ = base::TimeTicks::Now();
1045 fetch_dispatcher_->Run(); 1001 fetch_dispatcher_->Run();
1046 } 1002 }
1047 1003
1048 } // namespace content 1004 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/service_worker/service_worker_url_request_job.h ('k') | content/content_browser.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698