Skip to content

Commit

Permalink
Merge pull request #79846 from Faless/web/no_body_length
Browse files Browse the repository at this point in the history
[Web] Always return -1 as body length in HTTPClientWeb
  • Loading branch information
YuriSizov committed Jul 24, 2023
2 parents ee06d3e + f4713d2 commit bec47cd
Show file tree
Hide file tree
Showing 4 changed files with 10 additions and 17 deletions.
1 change: 1 addition & 0 deletions doc/classes/HTTPClient.xml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
<description>
Returns the response's body length.
[b]Note:[/b] Some Web servers may not send a body length. In this case, the value returned will be [code]-1[/code]. If using chunked transfer encoding, the body length will also be [code]-1[/code].
[b]Note:[/b] This function always returns [code]-1[/code] on the Web platform due to browsers limitations.
</description>
</method>
<method name="get_response_code" qualifiers="const">
Expand Down
10 changes: 9 additions & 1 deletion platform/web/http_client_web.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,15 @@ Error HTTPClientWeb::get_response_headers(List<String> *r_response) {
}

int64_t HTTPClientWeb::get_response_body_length() const {
return godot_js_fetch_body_length_get(js_id);
// Body length cannot be consistently retrieved from the web.
// Reading the "content-length" value will return a meaningless value when the response is compressed,
// as reading will return uncompressed chunks in any case, resulting in a mismatch between the detected
// body size and the actual size returned by repeatedly calling read_response_body_chunk.
// Additionally, while "content-length" is considered a safe CORS header, "content-encoding" is not,
// so using the "content-encoding" to decide if "content-length" is meaningful is not an option either.
// We simply must accept the fact that browsers are awful when it comes to networking APIs.
// See GH-47597, and GH-79327.
return -1;
}

PackedByteArray HTTPClientWeb::read_response_body_chunk() {
Expand Down
1 change: 0 additions & 1 deletion platform/web/http_client_web.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ extern int godot_js_fetch_read_headers(int p_id, void (*parse_callback)(int p_si
extern int godot_js_fetch_read_chunk(int p_id, uint8_t *p_buf, int p_buf_size);
extern void godot_js_fetch_free(int p_id);
extern godot_js_fetch_state_t godot_js_fetch_state_get(int p_id);
extern int godot_js_fetch_body_length_get(int p_id);
extern int godot_js_fetch_http_status_get(int p_id);
extern int godot_js_fetch_is_chunked(int p_id);

Expand Down
15 changes: 0 additions & 15 deletions platform/web/js/libs/library_godot_fetch.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,22 +50,17 @@ const GodotFetch = {
return;
}
let chunked = false;
let bodySize = -1;
response.headers.forEach(function (value, header) {
const v = value.toLowerCase().trim();
const h = header.toLowerCase().trim();
if (h === 'transfer-encoding' && v === 'chunked') {
chunked = true;
}
if (h === 'content-length') {
bodySize = parseInt(v, 10);
}
});
obj.status = response.status;
obj.response = response;
obj.reader = response.body.getReader();
obj.chunked = chunked;
obj.bodySize = bodySize;
},

onerror: function (id, err) {
Expand All @@ -87,7 +82,6 @@ const GodotFetch = {
reading: false,
status: 0,
chunks: [],
bodySize: -1,
};
const id = IDHandler.add(obj);
const init = {
Expand Down Expand Up @@ -224,15 +218,6 @@ const GodotFetch = {
return p_buf_size - to_read;
},

godot_js_fetch_body_length_get__sig: 'ii',
godot_js_fetch_body_length_get: function (p_id) {
const obj = IDHandler.get(p_id);
if (!obj || !obj.response) {
return -1;
}
return obj.bodySize;
},

godot_js_fetch_is_chunked__sig: 'ii',
godot_js_fetch_is_chunked: function (p_id) {
const obj = IDHandler.get(p_id);
Expand Down

0 comments on commit bec47cd

Please sign in to comment.