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 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 241 return; | 241 return; |
| 242 ServiceWorkerMetrics::URLRequestJobResult result = | 242 ServiceWorkerMetrics::URLRequestJobResult result = |
| 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() { |
|
horo
2016/06/29 05:31:35
This function name should be FallbackToNetworkOrRe
shimazu
2016/07/04 06:31:11
Done.
falken
2016/07/05 06:49:28
What's the reason for both FallbackToNetwork() and
shimazu
2016/07/06 06:27:35
It's just for error cases. I think we should handl
| |
| 252 DCHECK_EQ(NOT_DETERMINED, response_type_); | 252 DCHECK_EQ(NOT_DETERMINED, response_type_); |
| 253 response_type_ = FALLBACK_TO_NETWORK; | 253 // TODO(mek): http://crbug.com/604084 Figure out what to do about CORS |
| 254 // preflight and fallbacks for foreign fetch events. | |
| 255 if (fetch_type_ != ServiceWorkerFetchType::FOREIGN_FETCH && | |
| 256 IsNeedToFallbackToRenderer()) { | |
| 257 response_type_ = FALLBACK_TO_RENDERER; | |
| 258 } else { | |
| 259 response_type_ = FALLBACK_TO_NETWORK; | |
| 260 } | |
| 254 MaybeStartRequest(); | 261 MaybeStartRequest(); |
| 255 } | 262 } |
| 256 | 263 |
| 257 void ServiceWorkerURLRequestJob::ForwardToServiceWorker() { | 264 void ServiceWorkerURLRequestJob::ForwardToServiceWorker() { |
| 258 DCHECK_EQ(NOT_DETERMINED, response_type_); | 265 DCHECK_EQ(NOT_DETERMINED, response_type_); |
| 259 response_type_ = FORWARD_TO_SERVICE_WORKER; | 266 response_type_ = FORWARD_TO_SERVICE_WORKER; |
| 260 MaybeStartRequest(); | 267 MaybeStartRequest(); |
| 261 } | 268 } |
| 262 | 269 |
| 263 void ServiceWorkerURLRequestJob::Start() { | 270 void ServiceWorkerURLRequestJob::Start() { |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 492 | 499 |
| 493 void ServiceWorkerURLRequestJob::StartRequest() { | 500 void ServiceWorkerURLRequestJob::StartRequest() { |
| 494 request()->net_log().AddEvent(net::NetLog::TYPE_SERVICE_WORKER_START_REQUEST); | 501 request()->net_log().AddEvent(net::NetLog::TYPE_SERVICE_WORKER_START_REQUEST); |
| 495 | 502 |
| 496 switch (response_type_) { | 503 switch (response_type_) { |
| 497 case NOT_DETERMINED: | 504 case NOT_DETERMINED: |
| 498 NOTREACHED(); | 505 NOTREACHED(); |
| 499 return; | 506 return; |
| 500 | 507 |
| 501 case FALLBACK_TO_NETWORK: | 508 case FALLBACK_TO_NETWORK: |
| 502 // Restart the request to create a new job. Our request handler will | 509 FinalizeToFallbackToNetwork(); |
| 503 // return nullptr, and the default job (which will hit network) should be | 510 return; |
| 504 // created. | 511 |
| 505 NotifyRestartRequired(); | 512 case FALLBACK_TO_RENDERER: |
| 513 FinalizeToFallbackToRenderer(); | |
| 506 return; | 514 return; |
| 507 | 515 |
| 508 case FORWARD_TO_SERVICE_WORKER: | 516 case FORWARD_TO_SERVICE_WORKER: |
| 509 if (HasRequestBody()) { | 517 if (HasRequestBody()) { |
| 510 DCHECK(!blob_construction_waiter_); | 518 DCHECK(!blob_construction_waiter_); |
| 511 blob_construction_waiter_.reset(new BlobConstructionWaiter(this)); | 519 blob_construction_waiter_.reset(new BlobConstructionWaiter(this)); |
| 512 blob_construction_waiter_->RunOnComplete( | 520 blob_construction_waiter_->RunOnComplete( |
| 513 base::Bind(&ServiceWorkerURLRequestJob::RequestBodyBlobsCompleted, | 521 base::Bind(&ServiceWorkerURLRequestJob::RequestBodyBlobsCompleted, |
| 514 GetWeakPtr())); | 522 GetWeakPtr())); |
| 515 return; | 523 return; |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 691 RecordResult(result); | 699 RecordResult(result); |
| 692 DeliverErrorResponse(); | 700 DeliverErrorResponse(); |
| 693 return; | 701 return; |
| 694 } | 702 } |
| 695 | 703 |
| 696 if (status != SERVICE_WORKER_OK) { | 704 if (status != SERVICE_WORKER_OK) { |
| 697 RecordResult(ServiceWorkerMetrics::REQUEST_JOB_ERROR_FETCH_EVENT_DISPATCH); | 705 RecordResult(ServiceWorkerMetrics::REQUEST_JOB_ERROR_FETCH_EVENT_DISPATCH); |
| 698 if (IsMainResourceLoad()) { | 706 if (IsMainResourceLoad()) { |
| 699 // Using the service worker failed, so fallback to network. | 707 // Using the service worker failed, so fallback to network. |
| 700 delegate_->MainResourceLoadFailed(); | 708 delegate_->MainResourceLoadFailed(); |
| 701 response_type_ = FALLBACK_TO_NETWORK; | 709 FinalizeToFallbackToNetwork(); |
| 702 NotifyRestartRequired(); | |
| 703 } else { | 710 } else { |
| 704 DeliverErrorResponse(); | 711 DeliverErrorResponse(); |
| 705 } | 712 } |
| 706 return; | 713 return; |
| 707 } | 714 } |
| 708 | 715 |
| 709 if (fetch_result == SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK) { | 716 if (fetch_result == SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK) { |
| 710 ServiceWorkerMetrics::RecordFallbackedRequestMode(request_mode_); | 717 if (IsNeedToFallbackToRenderer()) { |
| 711 // When the request_mode is |CORS| or |CORS-with-forced-preflight| and the | 718 FinalizeToFallbackToRenderer(); |
| 712 // origin of the request URL is different from the security origin of the | 719 } else { |
| 713 // document, we can't simply fallback to the network in the browser process. | 720 FinalizeToFallbackToNetwork(); |
| 714 // It is because the CORS preflight logic is implemented in the renderer. So | |
| 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 } | 721 } |
| 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; | 722 return; |
| 736 } | 723 } |
| 737 | 724 |
| 738 // We should have a response now. | 725 // We should have a response now. |
| 739 DCHECK_EQ(SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE, fetch_result); | 726 DCHECK_EQ(SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE, fetch_result); |
| 740 | 727 |
| 741 // A response with status code 0 is Blink telling us to respond with network | 728 // A response with status code 0 is Blink telling us to respond with network |
| 742 // error. | 729 // error. |
| 743 if (response.status_code == 0) { | 730 if (response.status_code == 0) { |
| 744 RecordStatusZeroResponseError(response.error); | 731 RecordStatusZeroResponseError(response.error); |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 859 } | 846 } |
| 860 | 847 |
| 861 void ServiceWorkerURLRequestJob::DeliverErrorResponse() { | 848 void ServiceWorkerURLRequestJob::DeliverErrorResponse() { |
| 862 // TODO(falken): Print an error to the console of the ServiceWorker and of | 849 // TODO(falken): Print an error to the console of the ServiceWorker and of |
| 863 // the requesting page. | 850 // the requesting page. |
| 864 CreateResponseHeader( | 851 CreateResponseHeader( |
| 865 500, "Service Worker Response Error", ServiceWorkerHeaderMap()); | 852 500, "Service Worker Response Error", ServiceWorkerHeaderMap()); |
| 866 CommitResponseHeader(); | 853 CommitResponseHeader(); |
| 867 } | 854 } |
| 868 | 855 |
| 856 void ServiceWorkerURLRequestJob::FinalizeToFallbackToNetwork() { | |
| 857 // Restart this request to create a new job. The default job (which will hit | |
| 858 // network) will be created in the next time because our request handler will | |
| 859 // return nullptr after restarting and this means our interceptor does not | |
| 860 // intercept. | |
| 861 if (ShouldRecordResult()) | |
| 862 RecordResult(ServiceWorkerMetrics::REQUEST_JOB_FALLBACK_RESPONSE); | |
| 863 response_type_ = FALLBACK_TO_NETWORK; | |
| 864 NotifyRestartRequired(); | |
| 865 return; | |
| 866 } | |
| 867 | |
| 868 void ServiceWorkerURLRequestJob::FinalizeToFallbackToRenderer() { | |
| 869 ServiceWorkerMetrics::RecordFallbackedRequestMode(request_mode_); | |
| 870 // TODO(mek): http://crbug.com/604084 Figure out what to do about CORS | |
| 871 // preflight and fallbacks for foreign fetch events. | |
| 872 fall_back_required_ = fetch_type_ != ServiceWorkerFetchType::FOREIGN_FETCH; | |
| 873 if (ShouldRecordResult()) | |
| 874 RecordResult(ServiceWorkerMetrics::REQUEST_JOB_FALLBACK_FOR_CORS); | |
| 875 CreateResponseHeader(400, "Service Worker Fallback Required", | |
| 876 ServiceWorkerHeaderMap()); | |
| 877 response_type_ = FALLBACK_TO_RENDERER; | |
| 878 CommitResponseHeader(); | |
| 879 } | |
| 880 | |
| 881 bool ServiceWorkerURLRequestJob::IsNeedToFallbackToRenderer() { | |
| 882 // When the request_mode is |CORS| or |CORS-with-forced-preflight| and the | |
| 883 // origin of the request URL is different from the security origin of the | |
| 884 // document, we can't simply fallback to the network in the browser process. | |
| 885 // It is because the CORS preflight logic is implemented in the renderer. So | |
| 886 // we returns a fall_back_required response to the renderer. | |
| 887 return !IsMainResourceLoad() && | |
| 888 (request_mode_ == FETCH_REQUEST_MODE_CORS || | |
| 889 request_mode_ == FETCH_REQUEST_MODE_CORS_WITH_FORCED_PREFLIGHT) && | |
| 890 !request()->initiator().IsSameOriginWith( | |
| 891 url::Origin(request()->url())); | |
| 892 } | |
| 893 | |
| 869 void ServiceWorkerURLRequestJob::SetResponseBodyType(ResponseBodyType type) { | 894 void ServiceWorkerURLRequestJob::SetResponseBodyType(ResponseBodyType type) { |
| 870 DCHECK_EQ(response_body_type_, UNKNOWN); | 895 DCHECK_EQ(response_body_type_, UNKNOWN); |
| 871 DCHECK_NE(type, UNKNOWN); | 896 DCHECK_NE(type, UNKNOWN); |
| 872 response_body_type_ = type; | 897 response_body_type_ = type; |
| 873 } | 898 } |
| 874 | 899 |
| 875 bool ServiceWorkerURLRequestJob::ShouldRecordResult() { | 900 bool ServiceWorkerURLRequestJob::ShouldRecordResult() { |
| 876 return !did_record_result_ && is_started_ && | 901 return !did_record_result_ && is_started_ && |
| 877 response_type_ == FORWARD_TO_SERVICE_WORKER; | 902 response_type_ == FORWARD_TO_SERVICE_WORKER; |
| 878 } | 903 } |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 934 } | 959 } |
| 935 | 960 |
| 936 void ServiceWorkerURLRequestJob::NotifyRestartRequired() { | 961 void ServiceWorkerURLRequestJob::NotifyRestartRequired() { |
| 937 ServiceWorkerResponseInfo::ForRequest(request_, true) | 962 ServiceWorkerResponseInfo::ForRequest(request_, true) |
| 938 ->OnPrepareToRestart(worker_start_time_, worker_ready_time_); | 963 ->OnPrepareToRestart(worker_start_time_, worker_ready_time_); |
| 939 delegate_->OnPrepareToRestart(); | 964 delegate_->OnPrepareToRestart(); |
| 940 URLRequestJob::NotifyRestartRequired(); | 965 URLRequestJob::NotifyRestartRequired(); |
| 941 } | 966 } |
| 942 | 967 |
| 943 void ServiceWorkerURLRequestJob::OnStartCompleted() const { | 968 void ServiceWorkerURLRequestJob::OnStartCompleted() const { |
| 944 if (response_type_ != FORWARD_TO_SERVICE_WORKER) { | 969 if (response_type_ != FORWARD_TO_SERVICE_WORKER && |
| 970 response_type_ != FALLBACK_TO_RENDERER) { | |
| 945 ServiceWorkerResponseInfo::ForRequest(request_, true) | 971 ServiceWorkerResponseInfo::ForRequest(request_, true) |
| 946 ->OnStartCompleted( | 972 ->OnStartCompleted( |
| 947 false /* was_fetched_via_service_worker */, | 973 false /* was_fetched_via_service_worker */, |
| 948 false /* was_fallback_required */, | 974 false /* was_fallback_required */, |
| 949 GURL() /* original_url_via_service_worker */, | 975 GURL() /* original_url_via_service_worker */, |
| 950 blink::WebServiceWorkerResponseTypeDefault, | 976 blink::WebServiceWorkerResponseTypeDefault, |
| 951 base::TimeTicks() /* service_worker_start_time */, | 977 base::TimeTicks() /* service_worker_start_time */, |
| 952 base::TimeTicks() /* service_worker_ready_time */, | 978 base::TimeTicks() /* service_worker_ready_time */, |
| 953 false /* respons_is_in_cache_storage */, | 979 false /* respons_is_in_cache_storage */, |
| 954 std::string() /* response_cache_storage_cache_name */, | 980 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(), | 1031 CreateFetchRequest(), active_worker, resource_type_, request()->net_log(), |
| 1006 base::Bind(&ServiceWorkerURLRequestJob::DidPrepareFetchEvent, | 1032 base::Bind(&ServiceWorkerURLRequestJob::DidPrepareFetchEvent, |
| 1007 weak_factory_.GetWeakPtr(), active_worker), | 1033 weak_factory_.GetWeakPtr(), active_worker), |
| 1008 base::Bind(&ServiceWorkerURLRequestJob::DidDispatchFetchEvent, | 1034 base::Bind(&ServiceWorkerURLRequestJob::DidDispatchFetchEvent, |
| 1009 weak_factory_.GetWeakPtr()))); | 1035 weak_factory_.GetWeakPtr()))); |
| 1010 worker_start_time_ = base::TimeTicks::Now(); | 1036 worker_start_time_ = base::TimeTicks::Now(); |
| 1011 fetch_dispatcher_->Run(); | 1037 fetch_dispatcher_->Run(); |
| 1012 } | 1038 } |
| 1013 | 1039 |
| 1014 } // namespace content | 1040 } // namespace content |
| OLD | NEW |