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