Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 243 ServiceWorkerMetrics::REQUEST_JOB_ERROR_KILLED; | 243 ServiceWorkerMetrics::REQUEST_JOB_ERROR_KILLED; |
| 244 if (response_body_type_ == STREAM) | 244 if (response_body_type_ == STREAM) |
| 245 result = ServiceWorkerMetrics::REQUEST_JOB_ERROR_KILLED_WITH_STREAM; | 245 result = ServiceWorkerMetrics::REQUEST_JOB_ERROR_KILLED_WITH_STREAM; |
| 246 else if (response_body_type_ == BLOB) | 246 else if (response_body_type_ == BLOB) |
| 247 result = ServiceWorkerMetrics::REQUEST_JOB_ERROR_KILLED_WITH_BLOB; | 247 result = ServiceWorkerMetrics::REQUEST_JOB_ERROR_KILLED_WITH_BLOB; |
| 248 RecordResult(result); | 248 RecordResult(result); |
| 249 } | 249 } |
| 250 | 250 |
| 251 void ServiceWorkerURLRequestJob::FallbackToNetwork() { | 251 void ServiceWorkerURLRequestJob::FallbackToNetwork() { |
| 252 DCHECK_EQ(NOT_DETERMINED, response_type_); | 252 DCHECK_EQ(NOT_DETERMINED, response_type_); |
| 253 // TODO(shimazu): Remove the condition of FOREIGN_FETCH after figuring out | |
| 254 // what to do about CORS preflight and fallbacks for foreign fetch events. | |
| 255 // http://crbug.com/604084 | |
| 256 DCHECK(!IsFallbackToRendererNeeded() || | |
| 257 (fetch_type_ == ServiceWorkerFetchType::FOREIGN_FETCH)); | |
| 253 response_type_ = FALLBACK_TO_NETWORK; | 258 response_type_ = FALLBACK_TO_NETWORK; |
| 254 MaybeStartRequest(); | 259 MaybeStartRequest(); |
| 255 } | 260 } |
| 256 | 261 |
| 262 void ServiceWorkerURLRequestJob::FallbackToNetworkOrRenderer() { | |
| 263 DCHECK_EQ(NOT_DETERMINED, response_type_); | |
| 264 // TODO(shimazu): Remove the condition of FOREIGN_FETCH after figuring out | |
| 265 // what to do about CORS preflight and fallbacks for foreign fetch events. | |
| 266 // http://crbug.com/604084 | |
| 267 DCHECK(fetch_type_ != ServiceWorkerFetchType::FOREIGN_FETCH); | |
|
falken
2016/07/07 05:15:34
DCHECK_NE
shimazu
2016/07/07 06:23:52
Done.
| |
| 268 if (IsFallbackToRendererNeeded()) { | |
| 269 response_type_ = FALLBACK_TO_RENDERER; | |
| 270 } else { | |
| 271 response_type_ = FALLBACK_TO_NETWORK; | |
| 272 } | |
| 273 MaybeStartRequest(); | |
| 274 } | |
| 275 | |
| 257 void ServiceWorkerURLRequestJob::ForwardToServiceWorker() { | 276 void ServiceWorkerURLRequestJob::ForwardToServiceWorker() { |
| 258 DCHECK_EQ(NOT_DETERMINED, response_type_); | 277 DCHECK_EQ(NOT_DETERMINED, response_type_); |
| 259 response_type_ = FORWARD_TO_SERVICE_WORKER; | 278 response_type_ = FORWARD_TO_SERVICE_WORKER; |
| 260 MaybeStartRequest(); | 279 MaybeStartRequest(); |
| 261 } | 280 } |
| 262 | 281 |
| 263 void ServiceWorkerURLRequestJob::Start() { | 282 void ServiceWorkerURLRequestJob::Start() { |
| 264 is_started_ = true; | 283 is_started_ = true; |
| 265 MaybeStartRequest(); | 284 MaybeStartRequest(); |
| 266 } | 285 } |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 492 | 511 |
| 493 void ServiceWorkerURLRequestJob::StartRequest() { | 512 void ServiceWorkerURLRequestJob::StartRequest() { |
| 494 request()->net_log().AddEvent(net::NetLog::TYPE_SERVICE_WORKER_START_REQUEST); | 513 request()->net_log().AddEvent(net::NetLog::TYPE_SERVICE_WORKER_START_REQUEST); |
| 495 | 514 |
| 496 switch (response_type_) { | 515 switch (response_type_) { |
| 497 case NOT_DETERMINED: | 516 case NOT_DETERMINED: |
| 498 NOTREACHED(); | 517 NOTREACHED(); |
| 499 return; | 518 return; |
| 500 | 519 |
| 501 case FALLBACK_TO_NETWORK: | 520 case FALLBACK_TO_NETWORK: |
| 502 // Restart the request to create a new job. Our request handler will | 521 FinalizeFallbackToNetwork(); |
| 503 // return nullptr, and the default job (which will hit network) should be | 522 return; |
| 504 // created. | 523 |
| 505 NotifyRestartRequired(); | 524 case FALLBACK_TO_RENDERER: |
| 525 FinalizeFallbackToRenderer(); | |
| 506 return; | 526 return; |
| 507 | 527 |
| 508 case FORWARD_TO_SERVICE_WORKER: | 528 case FORWARD_TO_SERVICE_WORKER: |
| 509 if (HasRequestBody()) { | 529 if (HasRequestBody()) { |
| 510 DCHECK(!blob_construction_waiter_); | 530 DCHECK(!blob_construction_waiter_); |
| 511 blob_construction_waiter_.reset(new BlobConstructionWaiter(this)); | 531 blob_construction_waiter_.reset(new BlobConstructionWaiter(this)); |
| 512 blob_construction_waiter_->RunOnComplete( | 532 blob_construction_waiter_->RunOnComplete( |
| 513 base::Bind(&ServiceWorkerURLRequestJob::RequestBodyBlobsCompleted, | 533 base::Bind(&ServiceWorkerURLRequestJob::RequestBodyBlobsCompleted, |
| 514 GetWeakPtr())); | 534 GetWeakPtr())); |
| 515 return; | 535 return; |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 691 RecordResult(result); | 711 RecordResult(result); |
| 692 DeliverErrorResponse(); | 712 DeliverErrorResponse(); |
| 693 return; | 713 return; |
| 694 } | 714 } |
| 695 | 715 |
| 696 if (status != SERVICE_WORKER_OK) { | 716 if (status != SERVICE_WORKER_OK) { |
| 697 RecordResult(ServiceWorkerMetrics::REQUEST_JOB_ERROR_FETCH_EVENT_DISPATCH); | 717 RecordResult(ServiceWorkerMetrics::REQUEST_JOB_ERROR_FETCH_EVENT_DISPATCH); |
| 698 if (IsMainResourceLoad()) { | 718 if (IsMainResourceLoad()) { |
| 699 // Using the service worker failed, so fallback to network. | 719 // Using the service worker failed, so fallback to network. |
| 700 delegate_->MainResourceLoadFailed(); | 720 delegate_->MainResourceLoadFailed(); |
| 701 response_type_ = FALLBACK_TO_NETWORK; | 721 FinalizeFallbackToNetwork(); |
| 702 NotifyRestartRequired(); | |
| 703 } else { | 722 } else { |
| 704 DeliverErrorResponse(); | 723 DeliverErrorResponse(); |
| 705 } | 724 } |
| 706 return; | 725 return; |
| 707 } | 726 } |
| 708 | 727 |
| 709 if (fetch_result == SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK) { | 728 if (fetch_result == SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK) { |
| 710 ServiceWorkerMetrics::RecordFallbackedRequestMode(request_mode_); | 729 ServiceWorkerMetrics::RecordFallbackedRequestMode(request_mode_); |
| 711 // When the request_mode is |CORS| or |CORS-with-forced-preflight| and the | 730 if (IsFallbackToRendererNeeded()) { |
| 712 // origin of the request URL is different from the security origin of the | 731 FinalizeFallbackToRenderer(); |
| 713 // document, we can't simply fallback to the network in the browser process. | 732 } else { |
| 714 // It is because the CORS preflight logic is implemented in the renderer. So | 733 FinalizeFallbackToNetwork(); |
| 715 // we returns a fall_back_required response to the renderer. | |
| 716 if ((request_mode_ == FETCH_REQUEST_MODE_CORS || | |
| 717 request_mode_ == FETCH_REQUEST_MODE_CORS_WITH_FORCED_PREFLIGHT) && | |
| 718 !request()->initiator().IsSameOriginWith( | |
| 719 url::Origin(request()->url()))) { | |
| 720 // TODO(mek): http://crbug.com/604084 Figure out what to do about CORS | |
| 721 // preflight and fallbacks for foreign fetch events. | |
| 722 fall_back_required_ = | |
| 723 fetch_type_ != ServiceWorkerFetchType::FOREIGN_FETCH; | |
| 724 RecordResult(ServiceWorkerMetrics::REQUEST_JOB_FALLBACK_FOR_CORS); | |
| 725 CreateResponseHeader( | |
| 726 400, "Service Worker Fallback Required", ServiceWorkerHeaderMap()); | |
| 727 CommitResponseHeader(); | |
| 728 return; | |
| 729 } | 734 } |
| 730 // Change the response type and restart the request to fallback to | |
| 731 // the network. | |
| 732 RecordResult(ServiceWorkerMetrics::REQUEST_JOB_FALLBACK_RESPONSE); | |
| 733 response_type_ = FALLBACK_TO_NETWORK; | |
| 734 NotifyRestartRequired(); | |
| 735 return; | 735 return; |
| 736 } | 736 } |
| 737 | 737 |
| 738 // We should have a response now. | 738 // We should have a response now. |
| 739 DCHECK_EQ(SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE, fetch_result); | 739 DCHECK_EQ(SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE, fetch_result); |
| 740 | 740 |
| 741 // A response with status code 0 is Blink telling us to respond with network | 741 // A response with status code 0 is Blink telling us to respond with network |
| 742 // error. | 742 // error. |
| 743 if (response.status_code == 0) { | 743 if (response.status_code == 0) { |
| 744 RecordStatusZeroResponseError(response.error); | 744 RecordStatusZeroResponseError(response.error); |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 859 } | 859 } |
| 860 | 860 |
| 861 void ServiceWorkerURLRequestJob::DeliverErrorResponse() { | 861 void ServiceWorkerURLRequestJob::DeliverErrorResponse() { |
| 862 // TODO(falken): Print an error to the console of the ServiceWorker and of | 862 // TODO(falken): Print an error to the console of the ServiceWorker and of |
| 863 // the requesting page. | 863 // the requesting page. |
| 864 CreateResponseHeader( | 864 CreateResponseHeader( |
| 865 500, "Service Worker Response Error", ServiceWorkerHeaderMap()); | 865 500, "Service Worker Response Error", ServiceWorkerHeaderMap()); |
| 866 CommitResponseHeader(); | 866 CommitResponseHeader(); |
| 867 } | 867 } |
| 868 | 868 |
| 869 void ServiceWorkerURLRequestJob::FinalizeFallbackToNetwork() { | |
| 870 // Restart this request to create a new job. The default job (which will hit | |
| 871 // network) will be created in the next time because our request handler will | |
| 872 // return nullptr after restarting and this means our interceptor does not | |
| 873 // intercept. | |
| 874 if (ShouldRecordResult()) | |
| 875 RecordResult(ServiceWorkerMetrics::REQUEST_JOB_FALLBACK_RESPONSE); | |
| 876 response_type_ = FALLBACK_TO_NETWORK; | |
| 877 NotifyRestartRequired(); | |
| 878 return; | |
| 879 } | |
| 880 | |
| 881 void ServiceWorkerURLRequestJob::FinalizeFallbackToRenderer() { | |
| 882 // TODO(mek): http://crbug.com/604084 Figure out what to do about CORS | |
| 883 // preflight and fallbacks for foreign fetch events. | |
| 884 fall_back_required_ = fetch_type_ != ServiceWorkerFetchType::FOREIGN_FETCH; | |
| 885 if (ShouldRecordResult()) | |
| 886 RecordResult(ServiceWorkerMetrics::REQUEST_JOB_FALLBACK_FOR_CORS); | |
| 887 CreateResponseHeader(400, "Service Worker Fallback Required", | |
| 888 ServiceWorkerHeaderMap()); | |
| 889 response_type_ = FALLBACK_TO_RENDERER; | |
| 890 CommitResponseHeader(); | |
| 891 } | |
| 892 | |
| 893 bool ServiceWorkerURLRequestJob::IsFallbackToRendererNeeded() const { | |
| 894 // When the request_mode is |CORS| or |CORS-with-forced-preflight| and the | |
| 895 // origin of the request URL is different from the security origin of the | |
| 896 // document, we can't simply fallback to the network in the browser process. | |
| 897 // It is because the CORS preflight logic is implemented in the renderer. So | |
| 898 // we returns a fall_back_required response to the renderer. | |
|
falken
2016/07/07 05:15:34
return
shimazu
2016/07/07 06:23:52
Done.
| |
| 899 return !IsMainResourceLoad() && | |
| 900 (request_mode_ == FETCH_REQUEST_MODE_CORS || | |
| 901 request_mode_ == FETCH_REQUEST_MODE_CORS_WITH_FORCED_PREFLIGHT) && | |
| 902 !request()->initiator().IsSameOriginWith( | |
| 903 url::Origin(request()->url())); | |
| 904 } | |
| 905 | |
| 869 void ServiceWorkerURLRequestJob::SetResponseBodyType(ResponseBodyType type) { | 906 void ServiceWorkerURLRequestJob::SetResponseBodyType(ResponseBodyType type) { |
| 870 DCHECK_EQ(response_body_type_, UNKNOWN); | 907 DCHECK_EQ(response_body_type_, UNKNOWN); |
| 871 DCHECK_NE(type, UNKNOWN); | 908 DCHECK_NE(type, UNKNOWN); |
| 872 response_body_type_ = type; | 909 response_body_type_ = type; |
| 873 } | 910 } |
| 874 | 911 |
| 875 bool ServiceWorkerURLRequestJob::ShouldRecordResult() { | 912 bool ServiceWorkerURLRequestJob::ShouldRecordResult() { |
| 876 return !did_record_result_ && is_started_ && | 913 return !did_record_result_ && is_started_ && |
| 877 response_type_ == FORWARD_TO_SERVICE_WORKER; | 914 response_type_ == FORWARD_TO_SERVICE_WORKER; |
| 878 } | 915 } |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 934 } | 971 } |
| 935 | 972 |
| 936 void ServiceWorkerURLRequestJob::NotifyRestartRequired() { | 973 void ServiceWorkerURLRequestJob::NotifyRestartRequired() { |
| 937 ServiceWorkerResponseInfo::ForRequest(request_, true) | 974 ServiceWorkerResponseInfo::ForRequest(request_, true) |
| 938 ->OnPrepareToRestart(worker_start_time_, worker_ready_time_); | 975 ->OnPrepareToRestart(worker_start_time_, worker_ready_time_); |
| 939 delegate_->OnPrepareToRestart(); | 976 delegate_->OnPrepareToRestart(); |
| 940 URLRequestJob::NotifyRestartRequired(); | 977 URLRequestJob::NotifyRestartRequired(); |
| 941 } | 978 } |
| 942 | 979 |
| 943 void ServiceWorkerURLRequestJob::OnStartCompleted() const { | 980 void ServiceWorkerURLRequestJob::OnStartCompleted() const { |
| 944 if (response_type_ != FORWARD_TO_SERVICE_WORKER) { | 981 if (response_type_ != FORWARD_TO_SERVICE_WORKER && |
| 982 response_type_ != FALLBACK_TO_RENDERER) { | |
| 945 ServiceWorkerResponseInfo::ForRequest(request_, true) | 983 ServiceWorkerResponseInfo::ForRequest(request_, true) |
| 946 ->OnStartCompleted( | 984 ->OnStartCompleted( |
| 947 false /* was_fetched_via_service_worker */, | 985 false /* was_fetched_via_service_worker */, |
| 948 false /* was_fallback_required */, | 986 false /* was_fallback_required */, |
| 949 GURL() /* original_url_via_service_worker */, | 987 GURL() /* original_url_via_service_worker */, |
| 950 blink::WebServiceWorkerResponseTypeDefault, | 988 blink::WebServiceWorkerResponseTypeDefault, |
| 951 base::TimeTicks() /* service_worker_start_time */, | 989 base::TimeTicks() /* service_worker_start_time */, |
| 952 base::TimeTicks() /* service_worker_ready_time */, | 990 base::TimeTicks() /* service_worker_ready_time */, |
| 953 false /* respons_is_in_cache_storage */, | 991 false /* respons_is_in_cache_storage */, |
| 954 std::string() /* response_cache_storage_cache_name */, | 992 std::string() /* response_cache_storage_cache_name */, |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1005 CreateFetchRequest(), active_worker, resource_type_, request()->net_log(), | 1043 CreateFetchRequest(), active_worker, resource_type_, request()->net_log(), |
| 1006 base::Bind(&ServiceWorkerURLRequestJob::DidPrepareFetchEvent, | 1044 base::Bind(&ServiceWorkerURLRequestJob::DidPrepareFetchEvent, |
| 1007 weak_factory_.GetWeakPtr(), active_worker), | 1045 weak_factory_.GetWeakPtr(), active_worker), |
| 1008 base::Bind(&ServiceWorkerURLRequestJob::DidDispatchFetchEvent, | 1046 base::Bind(&ServiceWorkerURLRequestJob::DidDispatchFetchEvent, |
| 1009 weak_factory_.GetWeakPtr()))); | 1047 weak_factory_.GetWeakPtr()))); |
| 1010 worker_start_time_ = base::TimeTicks::Now(); | 1048 worker_start_time_ = base::TimeTicks::Now(); |
| 1011 fetch_dispatcher_->Run(); | 1049 fetch_dispatcher_->Run(); |
| 1012 } | 1050 } |
| 1013 | 1051 |
| 1014 } // namespace content | 1052 } // namespace content |
| OLD | NEW |