| 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..326e3efef378059665564a0965006d281cd5bd10 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_NE(ServiceWorkerFetchType::FOREIGN_FETCH, fetch_type_);
|
| + 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 return a fall_back_required response to the renderer.
|
| + 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 */,
|
|
|