Chromium Code Reviews| Index: content/browser/service_worker/service_worker_url_request_job.cc |
| diff --git a/content/browser/service_worker/service_worker_url_request_job.cc b/content/browser/service_worker/service_worker_url_request_job.cc |
| index a81f696815cd59d644941d3b4f275ec9db14013b..268cede7f477abc4085aa87a92a632fe28a8f1a9 100644 |
| --- a/content/browser/service_worker/service_worker_url_request_job.cc |
| +++ b/content/browser/service_worker/service_worker_url_request_job.cc |
| @@ -250,10 +250,29 @@ ServiceWorkerURLRequestJob::~ServiceWorkerURLRequestJob() { |
| void ServiceWorkerURLRequestJob::FallbackToNetwork() { |
| DCHECK_EQ(NOT_DETERMINED, response_type_); |
| + // TODO(shimazu): Remove the condition of FOREIGN_FETCH after figuring out |
| + // what to do about CORS preflight and fallbacks for foreign fetch events. |
| + // http://crbug.com/604084 |
| + DCHECK(!IsFallbackToRendererNeeded() || |
| + (fetch_type_ == ServiceWorkerFetchType::FOREIGN_FETCH)); |
| response_type_ = FALLBACK_TO_NETWORK; |
| MaybeStartRequest(); |
| } |
| +void ServiceWorkerURLRequestJob::FallbackToNetworkOrRenderer() { |
| + DCHECK_EQ(NOT_DETERMINED, response_type_); |
| + // TODO(shimazu): Remove the condition of FOREIGN_FETCH after figuring out |
| + // what to do about CORS preflight and fallbacks for foreign fetch events. |
| + // http://crbug.com/604084 |
| + DCHECK(fetch_type_ != ServiceWorkerFetchType::FOREIGN_FETCH); |
|
falken
2016/07/07 05:15:34
DCHECK_NE
shimazu
2016/07/07 06:23:52
Done.
|
| + if (IsFallbackToRendererNeeded()) { |
| + response_type_ = FALLBACK_TO_RENDERER; |
| + } else { |
| + response_type_ = FALLBACK_TO_NETWORK; |
| + } |
| + MaybeStartRequest(); |
| +} |
| + |
| void ServiceWorkerURLRequestJob::ForwardToServiceWorker() { |
| DCHECK_EQ(NOT_DETERMINED, response_type_); |
| response_type_ = FORWARD_TO_SERVICE_WORKER; |
| @@ -499,10 +518,11 @@ void ServiceWorkerURLRequestJob::StartRequest() { |
| return; |
| case FALLBACK_TO_NETWORK: |
| - // Restart the request to create a new job. Our request handler will |
| - // return nullptr, and the default job (which will hit network) should be |
| - // created. |
| - NotifyRestartRequired(); |
| + FinalizeFallbackToNetwork(); |
| + return; |
| + |
| + case FALLBACK_TO_RENDERER: |
| + FinalizeFallbackToRenderer(); |
| return; |
| case FORWARD_TO_SERVICE_WORKER: |
| @@ -698,8 +718,7 @@ void ServiceWorkerURLRequestJob::DidDispatchFetchEvent( |
| if (IsMainResourceLoad()) { |
| // Using the service worker failed, so fallback to network. |
| delegate_->MainResourceLoadFailed(); |
| - response_type_ = FALLBACK_TO_NETWORK; |
| - NotifyRestartRequired(); |
| + FinalizeFallbackToNetwork(); |
| } else { |
| DeliverErrorResponse(); |
| } |
| @@ -708,30 +727,11 @@ void ServiceWorkerURLRequestJob::DidDispatchFetchEvent( |
| if (fetch_result == SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK) { |
| ServiceWorkerMetrics::RecordFallbackedRequestMode(request_mode_); |
| - // When the request_mode is |CORS| or |CORS-with-forced-preflight| and the |
| - // origin of the request URL is different from the security origin of the |
| - // document, we can't simply fallback to the network in the browser process. |
| - // It is because the CORS preflight logic is implemented in the renderer. So |
| - // we returns a fall_back_required response to the renderer. |
| - if ((request_mode_ == FETCH_REQUEST_MODE_CORS || |
| - request_mode_ == FETCH_REQUEST_MODE_CORS_WITH_FORCED_PREFLIGHT) && |
| - !request()->initiator().IsSameOriginWith( |
| - url::Origin(request()->url()))) { |
| - // TODO(mek): http://crbug.com/604084 Figure out what to do about CORS |
| - // preflight and fallbacks for foreign fetch events. |
| - fall_back_required_ = |
| - fetch_type_ != ServiceWorkerFetchType::FOREIGN_FETCH; |
| - RecordResult(ServiceWorkerMetrics::REQUEST_JOB_FALLBACK_FOR_CORS); |
| - CreateResponseHeader( |
| - 400, "Service Worker Fallback Required", ServiceWorkerHeaderMap()); |
| - CommitResponseHeader(); |
| - return; |
| + if (IsFallbackToRendererNeeded()) { |
| + FinalizeFallbackToRenderer(); |
| + } else { |
| + FinalizeFallbackToNetwork(); |
| } |
| - // Change the response type and restart the request to fallback to |
| - // the network. |
| - RecordResult(ServiceWorkerMetrics::REQUEST_JOB_FALLBACK_RESPONSE); |
| - response_type_ = FALLBACK_TO_NETWORK; |
| - NotifyRestartRequired(); |
| return; |
| } |
| @@ -866,6 +866,43 @@ void ServiceWorkerURLRequestJob::DeliverErrorResponse() { |
| CommitResponseHeader(); |
| } |
| +void ServiceWorkerURLRequestJob::FinalizeFallbackToNetwork() { |
| + // Restart this request to create a new job. The default job (which will hit |
| + // network) will be created in the next time because our request handler will |
| + // return nullptr after restarting and this means our interceptor does not |
| + // intercept. |
| + if (ShouldRecordResult()) |
| + RecordResult(ServiceWorkerMetrics::REQUEST_JOB_FALLBACK_RESPONSE); |
| + response_type_ = FALLBACK_TO_NETWORK; |
| + NotifyRestartRequired(); |
| + return; |
| +} |
| + |
| +void ServiceWorkerURLRequestJob::FinalizeFallbackToRenderer() { |
| + // TODO(mek): http://crbug.com/604084 Figure out what to do about CORS |
| + // preflight and fallbacks for foreign fetch events. |
| + fall_back_required_ = fetch_type_ != ServiceWorkerFetchType::FOREIGN_FETCH; |
| + if (ShouldRecordResult()) |
| + RecordResult(ServiceWorkerMetrics::REQUEST_JOB_FALLBACK_FOR_CORS); |
| + CreateResponseHeader(400, "Service Worker Fallback Required", |
| + ServiceWorkerHeaderMap()); |
| + response_type_ = FALLBACK_TO_RENDERER; |
| + CommitResponseHeader(); |
| +} |
| + |
| +bool ServiceWorkerURLRequestJob::IsFallbackToRendererNeeded() const { |
| + // When the request_mode is |CORS| or |CORS-with-forced-preflight| and the |
| + // origin of the request URL is different from the security origin of the |
| + // document, we can't simply fallback to the network in the browser process. |
| + // It is because the CORS preflight logic is implemented in the renderer. So |
| + // 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.
|
| + return !IsMainResourceLoad() && |
| + (request_mode_ == FETCH_REQUEST_MODE_CORS || |
| + request_mode_ == FETCH_REQUEST_MODE_CORS_WITH_FORCED_PREFLIGHT) && |
| + !request()->initiator().IsSameOriginWith( |
| + url::Origin(request()->url())); |
| +} |
| + |
| void ServiceWorkerURLRequestJob::SetResponseBodyType(ResponseBodyType type) { |
| DCHECK_EQ(response_body_type_, UNKNOWN); |
| DCHECK_NE(type, UNKNOWN); |
| @@ -941,7 +978,8 @@ void ServiceWorkerURLRequestJob::NotifyRestartRequired() { |
| } |
| void ServiceWorkerURLRequestJob::OnStartCompleted() const { |
| - if (response_type_ != FORWARD_TO_SERVICE_WORKER) { |
| + if (response_type_ != FORWARD_TO_SERVICE_WORKER && |
| + response_type_ != FALLBACK_TO_RENDERER) { |
| ServiceWorkerResponseInfo::ForRequest(request_, true) |
| ->OnStartCompleted( |
| false /* was_fetched_via_service_worker */, |