diff --git a/content/browser/service_worker/service_worker_main_resource_loader.cc b/content/browser/service_worker/service_worker_main_resource_loader.cc index d15c6373e3bc4..714ec22f4b189 100644 --- a/content/browser/service_worker/service_worker_main_resource_loader.cc +++ b/content/browser/service_worker/service_worker_main_resource_loader.cc @@ -99,6 +99,11 @@ std::string GetContainerHostClientId(int frame_tree_node_id) { return client_uuid; } +bool IsStaticRouterRaceRequestFixEnabled() { + return base::FeatureList::IsEnabled( + features::kServiceWorkerStaticRouterRaceRequestFix); +} + } // namespace // This class waits for completion of a stream response from the service worker. @@ -717,11 +722,14 @@ void ServiceWorkerMainResourceLoader::DidDispatchFetchEvent( // When kRaceNetworkRequest preload is triggered, it's possible that the // response is already committed without waiting for the fetch event result. // Invalidate and destruct if the class already detached from the request. - has_fetch_event_finished_ = true; - if (dispatched_preload_type() == DispatchedPreloadType::kRaceNetworkRequest && - is_detached_ && status_ == Status::kCompleted) { - InvalidateAndDeleteIfNeeded(); - return; + if (IsStaticRouterRaceRequestFixEnabled()) { + has_fetch_event_finished_ = true; + if (dispatched_preload_type() == + DispatchedPreloadType::kRaceNetworkRequest && + is_detached_ && status_ == Status::kCompleted) { + InvalidateAndDeleteIfNeeded(); + return; + } } bool is_fallback = @@ -1119,11 +1127,14 @@ void ServiceWorkerMainResourceLoader::InvalidateAndDeleteIfNeeded() { // 1) RaceNetworkRequest is dispatched and the network wins the race. // 2) The fetch event result is not received yet. // The postponed things will be done in DidDispatchFetchEvent(). - if (dispatched_preload_type() == DispatchedPreloadType::kRaceNetworkRequest && - race_network_request_url_loader_client_.has_value() && - !has_fetch_event_finished_) { - CHECK(fetch_dispatcher_); - return; + if (IsStaticRouterRaceRequestFixEnabled()) { + if (dispatched_preload_type() == + DispatchedPreloadType::kRaceNetworkRequest && + race_network_request_url_loader_client_.has_value() && + !has_fetch_event_finished_) { + CHECK(fetch_dispatcher_); + return; + } } // The fetch dispatcher or stream waiter may still be running. Don't let them diff --git a/content/common/features.cc b/content/common/features.cc index 48d7b90052179..af77eaca11072 100644 --- a/content/common/features.cc +++ b/content/common/features.cc @@ -473,6 +473,13 @@ BASE_FEATURE(kServiceWorkerStaticRouterStartServiceWorker, "ServiceWorkerStaticRouterStartServiceWorker", base::FEATURE_ENABLED_BY_DEFAULT); +// (crbug.com/340949948): Killswitch for the fix to address the ServiceWorker +// main and subreosurce loader lifetime issue, which introduces fetch() failure +// in the sw fetch handler. +BASE_FEATURE(kServiceWorkerStaticRouterRaceRequestFix, + "kServiceWorkerStaticRouterRaceRequestFix", + base::FEATURE_ENABLED_BY_DEFAULT); + // The set of ServiceWorker to bypass while making navigation request. // They are represented by a comma separated list of HEX encoded SHA256 hash of // the ServiceWorker's scripts. diff --git a/content/common/features.h b/content/common/features.h index 8c5e09041b338..0d6af32578f45 100644 --- a/content/common/features.h +++ b/content/common/features.h @@ -111,6 +111,7 @@ CONTENT_EXPORT BASE_DECLARE_FEATURE(kSendBeaconThrowForBlobWithNonSimpleType); CONTENT_EXPORT BASE_DECLARE_FEATURE(kServiceWorkerAutoPreload); CONTENT_EXPORT BASE_DECLARE_FEATURE( kServiceWorkerStaticRouterStartServiceWorker); +CONTENT_EXPORT BASE_DECLARE_FEATURE(kServiceWorkerStaticRouterRaceRequestFix); CONTENT_EXPORT BASE_DECLARE_FEATURE( kServiceWorkerBypassFetchHandlerHashStrings); CONTENT_EXPORT extern const base::FeatureParam<std::string> diff --git a/content/renderer/service_worker/service_worker_subresource_loader.cc b/content/renderer/service_worker/service_worker_subresource_loader.cc index fa436878708ce..278e3c759bc05 100644 --- a/content/renderer/service_worker/service_worker_subresource_loader.cc +++ b/content/renderer/service_worker/service_worker_subresource_loader.cc @@ -16,6 +16,7 @@ #include "base/strings/strcat.h" #include "base/task/sequenced_task_runner.h" #include "base/trace_event/trace_event.h" +#include "content/common/features.h" #include "content/common/fetch/fetch_request_type_converters.h" #include "content/common/service_worker/race_network_request_url_loader_client.h" #include "content/common/service_worker/service_worker_router_evaluator.h" @@ -172,6 +173,12 @@ blink::mojom::ServiceWorkerFetchEventTimingPtr AdjustTimingIfNeededCrBug1342408( base::UmaHistogramBoolean(kMetricsName, true); return timing; } + +bool IsStaticRouterRaceRequestFixEnabled() { + return base::FeatureList::IsEnabled( + features::kServiceWorkerStaticRouterRaceRequestFix); +} + } // namespace // A ServiceWorkerStreamCallback implementation which waits for completion of @@ -346,10 +353,13 @@ void ServiceWorkerSubresourceLoader::MaybeDeleteThis() { // 2) The fetch event handler has not been finished yet. // The postponed destruction will be done in // ServiceWorkerFetchResponseCallback methods. - if (dispatched_preload_type() == DispatchedPreloadType::kRaceNetworkRequest && - race_network_request_loader_client_.has_value() && - controller_connector_observation_.IsObserving()) { - return; + if (IsStaticRouterRaceRequestFixEnabled()) { + if (dispatched_preload_type() == + DispatchedPreloadType::kRaceNetworkRequest && + race_network_request_loader_client_.has_value() && + controller_connector_observation_.IsObserving()) { + return; + } } delete this; } @@ -627,7 +637,8 @@ void ServiceWorkerSubresourceLoader::OnResponse( TRACE_ID_LOCAL(request_id_)), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); SettleFetchEventDispatch(blink::ServiceWorkerStatusCode::kOk); - if (IsResponseAlreadyCommittedByRaceNetworkRequest()) { + if (IsStaticRouterRaceRequestFixEnabled() && + IsResponseAlreadyCommittedByRaceNetworkRequest()) { MaybeDeleteThis(); return; } @@ -648,7 +659,8 @@ void ServiceWorkerSubresourceLoader::OnResponseStream( TRACE_ID_LOCAL(request_id_)), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); SettleFetchEventDispatch(blink::ServiceWorkerStatusCode::kOk); - if (IsResponseAlreadyCommittedByRaceNetworkRequest()) { + if (IsStaticRouterRaceRequestFixEnabled() && + IsResponseAlreadyCommittedByRaceNetworkRequest()) { MaybeDeleteThis(); return; } @@ -660,7 +672,8 @@ void ServiceWorkerSubresourceLoader::OnFallback( std::optional<network::DataElementChunkedDataPipe> request_body, blink::mojom::ServiceWorkerFetchEventTimingPtr timing) { SettleFetchEventDispatch(blink::ServiceWorkerStatusCode::kOk); - if (IsResponseAlreadyCommittedByRaceNetworkRequest()) { + if (IsStaticRouterRaceRequestFixEnabled() && + IsResponseAlreadyCommittedByRaceNetworkRequest()) { MaybeDeleteThis(); return; }