Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: a6b87573f6bfc30bb841afe4c9e5c74ac91fa4e1
      
https://github.com/WebKit/WebKit/commit/a6b87573f6bfc30bb841afe4c9e5c74ac91fa4e1
  Author: Ahmad Saleem <[email protected]>
  Date:   2026-08-19 (Wed, 19 Aug 2026)

  Changed paths:
    A 
LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-preflight-unterminated-body.any-expected.txt
    A 
LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-preflight-unterminated-body.any.html
    A 
LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-preflight-unterminated-body.any.js
    A 
LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-preflight-unterminated-body.any.worker-expected.txt
    A 
LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-preflight-unterminated-body.any.worker.html
    A 
LayoutTests/imported/w3c/web-platform-tests/fetch/api/resources/preflight-unterminated-body.py
    M Source/WebKit/NetworkProcess/NetworkCORSPreflightChecker.cpp
    M Source/WebKit/NetworkProcess/NetworkCORSPreflightChecker.h

  Log Message:
  -----------
  CORS preflight fetch hangs indefinitely when the OPTIONS response body never 
terminates
https://bugs.webkit.org/show_bug.cgi?id=320657
rdar://184231090

Reviewed by Youenn Fablet.

NetworkCORSPreflightChecker only validated the preflight in 
didCompleteWithError, so
the outcome was gated on the response body finishing. A server that answers 
OPTIONS
with valid Access-Control-Allow-* headers followed by a body that never 
terminates
stalled the preflight, and with it the actual request, forever: fetch() never 
settled
and the bytes were streamed and discarded until the page aborted. Chrome and 
Firefox
conclude the preflight from the headers, so this was a WebKit-only hang.

The body must not control the result. Every step of CORS-preflight fetch [1] 
after the
response is obtained reads only its status and header list -- "response's 
status is an
ok status", then Access-Control-Allow-Methods, Access-Control-Allow-Headers and
Access-Control-Max-Age -- and the response it returns is inspected by HTTP 
fetch only
for being a network error. validatePreflightResponse already touches nothing 
else.

So conclude the preflight from the status and headers as soon as they arrive, 
via a new
completePreflight() that didCompleteWithError also routes through. Answer
PolicyAction::Ignore, which cancels the load rather than draining it, then 
clear the
task's client and cancel it, so didCompleteWithError cannot follow and report a 
second
result.

Do this for every preflight response rather than only for ones that declare a 
body.
expectedContentLength() is not comparable across ports -- CFNetwork reports -1 
for an
undeclared length while soup_message_headers_get_content_length() reports 0 -- 
so
treating a zero length as an empty body would leave the GLib ports on the old 
path and
still hanging.

m_loadInformation.metrics, the Inspector's extra metrics for the preflight 
transaction,
is no longer populated, as it came only from didCompleteWithError. Now that the 
body is
deliberately not read, final metrics are not meaningful for a preflight.

[1] https://fetch.spec.whatwg.org/#cors-preflight-fetch

Tests: 
imported/w3c/web-platform-tests/fetch/api/cors/cors-preflight-unterminated-body.any.html
       
imported/w3c/web-platform-tests/fetch/api/cors/cors-preflight-unterminated-body.any.worker.html

* 
LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-preflight-unterminated-body.any-expected.txt:
 Added.
* 
LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-preflight-unterminated-body.any.html:
 Added.
* 
LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-preflight-unterminated-body.any.js:
 Added.
* 
LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-preflight-unterminated-body.any.worker-expected.txt:
 Added.
* 
LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-preflight-unterminated-body.any.worker.html:
 Added.
* 
LayoutTests/imported/w3c/web-platform-tests/fetch/api/resources/preflight-unterminated-body.py:
 Added.
(main):
* Source/WebKit/NetworkProcess/NetworkCORSPreflightChecker.cpp:
(WebKit::NetworkCORSPreflightChecker::didReceiveResponse):
(WebKit::NetworkCORSPreflightChecker::didCompleteWithError):
(WebKit::NetworkCORSPreflightChecker::completePreflight):
* Source/WebKit/NetworkProcess/NetworkCORSPreflightChecker.h:

Canonical link: https://commits.webkit.org/319485@main



To unsubscribe from these emails, change your notification settings at 
https://github.com/WebKit/WebKit/settings/notifications

Reply via email to