- From: Dominique Hazael-Massieux <dom@w3.org>
- Date: Tue, 31 May 2022 09:07:01 +0200
- To: "'public-networks-ig@w3.org'" <public-networks-ig@w3.org>
Hello, Back in February, we had a joint meeting with the Games Community Group [1]; one of the outcomes of that conversation was feedback from one of the CG participant, Fabio Alessandrelli from Godot Engine, on the limitations of the capabilities provided by network API in Web browsers. Fabio very kindly agreed to compile that feedback, which he now has done in: https://docs.google.com/document/d/1kBaHZCkRd3lUiVW3xRWfGnLX4IdN9JtLww_IHPNA2QM/edit#heading=h.tcfuqee8mzcv (also copied below for posterity) It would be useful if our group could take the lead on figuring if and how some of these gaps could be fixed. Dom 1. https://www.w3.org/events/meetings/43010bf1-547f-4c0d-b61b-cadeaca4b475 #### text copy of https://docs.google.com/document/d/1kBaHZCkRd3lUiVW3xRWfGnLX4IdN9JtLww_IHPNA2QM/edit# Fetch --- In general, fetch is much stricter than regular platform APIs, being subjected to CORS restrictions, but the main limitation we face is the impossibility to gather download progress information in the many scenarios where it would otherwise be possible. Download Progress In a native platform, you would be able to read the "Content-Length" header (often available) and count the bytes as you receive them. With fetch, this is not possible whenever the response is compressed because the streaming API automatically decompresses it, and does not provide information about the number of compressed bytes processed. Originally, we tried to support download progress detection when "Content-Encoding" was not set so we knew the response was not compressed. That resulted in bugs during CORS requests due to "Content-Length" being added to the headers safelist but not "Content-Encoding", so we ended up removing it completely in the Web export (since non-compressed responses are rare anyway). Currently, to have a progress bar of the download using fetch during engine start, we hard-code file sizes in the exported HTML, which is of course not a viable option for dynamic resources and quite a burden in terms of usability and potential optimizations during read. I'm unsure what is the best way to solve it, and I suppose it depends on the level of abstraction that fetch wants to provide, and doing some research I found two related issues: https://github.com/whatwg/fetch/issues/1358 and https://github.com/whatwg/fetch/issues/607. I would advocate for a much simpler solution and expose "Response.contentLength" (null when unavailable) and "Response.contentReceived" (body bytes received). Those 2 properties could also allow better estimates of the amount of bytes transferred over the wire if it was possible to know when a cached response was returned. Which also as far as I know is not possible to detect as of now. I found a "cache state" mentioned in the living standard, but it seems mostly related to the "Resource Timing API" and found no trace of something similar in browser implementations, so maybe I'm missing something here. CORS and credentials Fetch cannot make authenticated CORS requests without explicitly setting the "credentials: 'include'" option, but that results in a rejected promise when "Access-Control-Allow-Origin: *" ( https://fetch.spec.whatwg.org/#cors-protocol-and-credentials ), which we cannot check since we cannot (AFAIK) make CORS preflight requests with `fetch` itself (i.e. OPTIONS "fetch" are themselves subjects to CORS). We also had multiple requests from users asking to allow setting custom credentials (e.g. making a REST client which exchanges tokens), but since `Authorization` is a reserved header, that is also not currently possible (and people dangerously hack around it using query parameters instead). I believe this is somehow by design, but I also think this design hinders both the usability of the web as a platform, and contrary to what it might seem, even security (people hack around it, authentication query parameters get logged/stored by proxies or the browser itself). WebSocket --- WebSocket is a really solid standard, one very surprising limitation of the browser API is it doesn't allow setting extra handshake headers. Doing so is supported by many native implementation due to high user demand, here is a link to our own issue about that: https://github.com/godotengine/godot/issues/27129 But a quick online search for "websocket custom headers" shows how much there's demand for that. This can of course be circumvented using request query parameters and this is how it's done right now in most implementations when targeting the Web platform, but it makes both server processing and proxy filtering harder, more error prone (again, logging/storing issue for query parameters), and more costly in terms of resources. I am not sure there is a good reason for not supporting them, beside requiring an API change to the constructor, they could be subject to usual header restrictions ( https://developer.mozilla.org/en-US/docs/Glossary/Forbidden_header_name ) or even limiting them to `X-*` headers would be an improvement, but again, the headers restrictions seem to cause more troubles than the potential issues they solve.
Received on Tuesday, 31 May 2022 07:07:04 UTC