mirror of
https://github.com/servo/servo
synced 2026-05-14 10:56:44 +02:00
# Description For the initial WebSocket handshake, we need to create a proper handshake request and `fetch()` it. Creating this handshake request begins in `WebSocketMethods::Constructor()`, which sends the partially prepared `RequestBuilder` over to `components/net/resource_thread.rs`. There we handle the incoming `CoreResourceMsg::Fetch` message and finish creating the handshake request in `components/net/websocket_loader.rs::create_handshake_request()`. Finally we fetch the request by calling `components/net/fetch/methods.rs::fetch()`. `fetch()` eventually calls `http_network_fetch()`. This is where the "actual fetching" of the request takes place on a network level, which means we need to handle WebSocket handshake requests differently than non-WebSocket requests. I mostly moved the existing code, which uses `tungstenite`, with some type massaging (thanks again, @jdm, for helping me out here!). This included converting from tungstenite types to Servo's net types (request/response). # The tricky bits In order to fetch the handshake request via `components/net/fetch/methods.rs::fetch()`, we need to convert the request URL's scheme from ws(s) to http(s). Then, we need to "undo" this conversion again when doing CSP checks (i.e. http(s) back to ws(s)). To avoid having this "undoing" logic in a bunch of places we introduced `Request::original_url()`, holding the URL before the scheme conversion took place. Unfortunately this only gets as so far. There are still some places, where we need to explicitly check and/or convert the URL scheme (e.g. retroactively upgrading to a secure scheme). # Related * https://websockets.spec.whatwg.org/#concept-websocket-establish * https://fetch.spec.whatwg.org/#http-network-fetch * https://github.com/w3c/webappsec-csp/issues/532 --- Fixes: #35028 --------- Signed-off-by: pylbrecht <pylbrecht@mailbox.org>