Skip to content

A service worker task should be done when its NetworkResourceLoader is don - #77267

Draft
youennf wants to merge 2 commits into
WebKit:mainfrom
youennf:eng/A-service-worker-task-should-be-done-when-its-NetworkResourceLoader-is-done
Draft

youennf wants to merge 2 commits into
WebKit:mainfrom
youennf:eng/A-service-worker-task-should-be-done-when-its-NetworkResourceLoader-is-done

Conversation

@youennf

@youennf youennf commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

2172873

A service worker task should be done when its NetworkResourceLoader is don
https://bugs.webkit.org/show_bug.cgi?id=327822
rdar://problem/190211445

Reviewed by NOBODY (OOPS!).

We want to align NetworkResourceLoader handling of m_serviceWorkerFetchTask with m_networkLoad.
For that reason, we are now cancelling/nullifying m_serviceWorkerFetchTask in NetworkResourceLoader::cleanup.

Given there are some async callbacks (content filtering for instance), to ensure that we do not restart either network loads or service worker tasks
after the NetworkResourceLoader has been cleaned up, we add NetworkResourceLoader::m_isDone and set it to true in NetworkResourceLoader::cleanup.

We use it in NetworkResourceLoader::continueWillSendRequest and NetworkResourceLoader::startWithServiceWorker to check at async return time whether we should continue.

As a strengthening, we update ServiceWorkerFetchTask to include more m_isDone checks so that we do not create reentrancy potential issues.

Covered by existing tests.

* Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp:
(WebKit::NetworkResourceLoader::~NetworkResourceLoader):
(WebKit::NetworkResourceLoader::cleanup):
(WebKit::NetworkResourceLoader::convertToDownload):
(WebKit::NetworkResourceLoader::abort):
(WebKit::NetworkResourceLoader::continueWillSendRequest):
(WebKit::NetworkResourceLoader::startWithServiceWorker):
* Source/WebKit/NetworkProcess/NetworkResourceLoader.h:
* Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.cpp:
(WebKit::ServiceWorkerFetchTask::didFinish):
(WebKit::ServiceWorkerFetchTask::didFail):

2172873

Misc iOS, visionOS, tvOS & watchOS macOS Linux Windows Apple Internal
✅ 🧪 style ✅ 🛠 ios ✅ 🛠 mac ✅ 🛠 wpe ✅ 🛠 win ⏳ 🛠 ios-apple
✅ 🧪 bindings ✅ 🛠 ios-sim ✅ 🛠 mac-AS-debug ✅ 🧪 wpe-wk2 ⏳ 🧪 win-tests ⏳ 🛠 mac-apple
✅ 🧪 webkitperl ✅ 🧪 ios-wk2 ✅ 🧪 api-mac ✅ 🧪 api-wpe ⏳ 🛠 vision-apple
✅ 🧪 ios-wk2-wpt ⏳ 🧪 api-mac-debug
⏳ 🧪 api-ios ✅ 🧪 mac-wk2 ✅ 🛠 gtk3-gcc
❌ 🛠 ios-safer-cpp ⏳ 🧪 mac-AS-debug-wk2 ✅ 🛠 gtk
✅ 🛠 vision ✅ 🧪 mac-wk2-stress ✅ 🧪 gtk-wk2
✅ 🛠 vision-sim ⏳ 🧪 mac-intel-wk2 ✅ 🧪 api-gtk
✅ 🧪 vision-wk2 ✅ 🛠 mac-safer-cpp ✅ 🛠 playstation
✅ 🛠 tv ✅ 🧪 mac-site-isolation
❌ 🛠 tv-sim
✅ 🛠 watch
✅ 🛠 watch-sim

…ence its loader

rdar://188341702
https://bugs.webkit.org/show_bug.cgi?id=327816

Reviewed by NOBODY (OOPS!).

NetworkResourceLoader can race the service worker fetch with the network.
In case of redirection for a navigation load, we might receive the network redirection before the service worker answer.
In that case, NetworkResourceLoader would set its service worker task to null and would either create a new one directly or would restart the load.
That makes the NetworkResourceLoader forgetting about the service worker task.
If NetworkResourceLoader dies, the service worker fetch task might start when its context connection is created and would crash.

To prevent this, we make sure to cancel the service worker fetch task when NetworkResourceLoader is no longer interested in it.
We do this in NetworkResourceLoader::continueWillSendRequest and for good measure, we also do this in NetworkResourceLoader::~NetworkResourceLoader.

While writing the test, we hit an issue with an ASSERT in SWServerWorker::setWorkerScripts.
This happens as the test is trying to create several fetch events on the same service worker that is not yet running.
We would then load scripts for every of these fetch events, which is unnecessary.

To prevent this, we introduce a HashMap of the workers whose scripts are being loaded.
We store the callbacks to call when the scripts are loaded.
If a worker is already in this HashMap, it means that scripts are being loaded and we do not need to request the store to load them again.

Test: http/wpt/service-workers/service-worker-fetch-task-cancel-on-redirect.https.html

* LayoutTests/http/wpt/service-workers/resources/redirect.py: Added.
* LayoutTests/http/wpt/service-workers/service-worker-fetch-task-cancel-on-redirect.https-expected.txt: Added.
* LayoutTests/http/wpt/service-workers/service-worker-fetch-task-cancel-on-redirect.https.html: Added.
* Source/WebCore/workers/service/server/SWServer.cpp:
(WebCore::SWServer::close):
(WebCore::SWServer::loadWorkerScripts):
* Source/WebCore/workers/service/server/SWServer.h:
* Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp:
(WebKit::NetworkResourceLoader::continueWillSendRequest):
* Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.cpp:
(WebKit::ServiceWorkerFetchTask::start):
(WebKit::ServiceWorkerFetchTask::startFetch):
…s don

https://bugs.webkit.org/show_bug.cgi?id=327822
rdar://problem/190211445

Reviewed by NOBODY (OOPS!).

We want to align NetworkResourceLoader handling of m_serviceWorkerFetchTask with m_networkLoad.
For that reason, we are now cancelling/nullifying m_serviceWorkerFetchTask in NetworkResourceLoader::cleanup.

Given there are some async callbacks (content filtering for instance), to ensure that we do not restart either network loads or service worker tasks
after the NetworkResourceLoader has been cleaned up, we add NetworkResourceLoader::m_isDone and set it to true in NetworkResourceLoader::cleanup.

We use it in NetworkResourceLoader::continueWillSendRequest and NetworkResourceLoader::startWithServiceWorker to check at async return time whether we should continue.

As a strengthening, we update ServiceWorkerFetchTask to include more m_isDone checks so that we do not create reentrancy potential issues.

Covered by existing tests.

* Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp:
(WebKit::NetworkResourceLoader::~NetworkResourceLoader):
(WebKit::NetworkResourceLoader::cleanup):
(WebKit::NetworkResourceLoader::convertToDownload):
(WebKit::NetworkResourceLoader::abort):
(WebKit::NetworkResourceLoader::continueWillSendRequest):
(WebKit::NetworkResourceLoader::startWithServiceWorker):
* Source/WebKit/NetworkProcess/NetworkResourceLoader.h:
* Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.cpp:
(WebKit::ServiceWorkerFetchTask::didFinish):
(WebKit::ServiceWorkerFetchTask::didFail):
@youennf youennf self-assigned this Oct 16, 2026
@youennf youennf added the Service Workers Component for Service Workers bugs. label Oct 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Service Workers Component for Service Workers bugs.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants