summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobbie Lodico <pandacoder@pm.me>2024-10-22 15:38:56 -0400
committerRobbie Lodico <pandacoder@pm.me>2024-10-23 08:10:35 -0400
commitc7f421ef5f836ef132e97ad6aaaa2ab2458f2ea5 (patch)
tree1c430d2c3b2a4794c1002513a21a826568e260ef
parent77dcf97d82cbfe4e4615475fa52ca03da645dbd8 (diff)
downloadredot-engine-c7f421ef5f836ef132e97ad6aaaa2ab2458f2ea5.tar.gz
Fix GodotFetch glue code for null response bodies
The spec says that Response.body can be null (in the event of requests that should have no body, like HEAD requests) and Firefox adheres to it which results in request failure for HEAD requests on Firefox for web exports. This commit addresses that by treating a null body as an "empty" body (without using a polyfill) and avoids changing the request lifecycle as much as possible. PR review changes: - Use == instead of strict === - Do not use ?? null - Comment formatting
-rw-r--r--platform/web/js/libs/library_godot_fetch.js16
1 files changed, 14 insertions, 2 deletions
diff --git a/platform/web/js/libs/library_godot_fetch.js b/platform/web/js/libs/library_godot_fetch.js
index 00616bc1a5..eeb3978256 100644
--- a/platform/web/js/libs/library_godot_fetch.js
+++ b/platform/web/js/libs/library_godot_fetch.js
@@ -59,7 +59,12 @@ const GodotFetch = {
});
obj.status = response.status;
obj.response = response;
- obj.reader = response.body.getReader();
+ // `body` can be null per spec (for example, in cases where the request method is HEAD).
+ // As of the time of writing, Chromium (127.0.6533.72) does not follow the spec but Firefox (131.0.3) does.
+ // See godotengine/godot#76825 for more information.
+ // See Chromium revert (of the change to follow the spec):
+ // https://chromium.googlesource.com/chromium/src/+/135354b7bdb554cd03c913af7c90aceead03c4d4
+ obj.reader = response.body?.getReader();
obj.chunked = chunked;
},
@@ -121,6 +126,10 @@ const GodotFetch = {
}
obj.reading = true;
obj.reader.read().then(GodotFetch.onread.bind(null, id)).catch(GodotFetch.onerror.bind(null, id));
+ } else if (obj.reader == null && obj.response.body == null) {
+ // Emulate a stream closure to maintain the request lifecycle.
+ obj.reading = true;
+ GodotFetch.onread(id, { value: undefined, done: true });
}
},
},
@@ -159,7 +168,10 @@ const GodotFetch = {
if (!obj.response) {
return 0;
}
- if (obj.reader) {
+ // If the reader is nullish, but there is no body, and the request is not marked as done,
+ // the same status should be returned as though the request is currently being read
+ // so that the proper lifecycle closure can be handled in `read()`.
+ if (obj.reader || (obj.response.body == null && !obj.done)) {
return 1;
}
if (obj.done) {