websocket upgrade client: hold state in Cell/JsCell, take ThisPtr instead of *mut Self

Merged
JA
3mo ago
+432-590

What

HTTPClient<SSL> (the WebSocket HTTP-upgrade client) already received ThisPtr<Self> from the uws dispatch, but every field write and every self-call went back through as_ptr() with its own unsafe block. This moves the mutable fields into Cell/JsCell, makes cancel/fail/terminate/process_response/start_proxy_tls_handshake/on_proxy_tls_handshake_complete/handle_decrypted_data take ThisPtr<Self>, and turns the &mut self helpers into &self.

  • input_body_buf is lent to socket/tunnel writes through one with_input_body helper, so no cell borrow spans a write that can re-enter clear_input; a buffer installed by a re-entrant call wins over the lent one. (On main, on_proxy_tls_handshake_complete held &(*this).input_body_buf across a tunnel write that can reach clear_data.)
  • UpgradeClientUnion stores the ThisPtr built once in WebSocketProxyTunnel::init instead of re-wrapping the raw pointer at each dispatch.
  • handle_writable now takes its ref guard before flushing the proxy tunnel. The flush can reach terminate → handle_close, which drops the socket's ref while this frame still reads the client.

unsafe count: WebSocketUpgradeClient.rs 170 → 54, WebSocketProxyTunnel.rs 48 → 43. What remains is releasing refs owned by C++/the socket (Self::deref), calls into the still-raw WebSocketProxyTunnel, and the extern-C/FFI edges.

Testing

Debug+ASAN build, all passing: websocket-client, websocket-proxy, websocket-proxy-close-reentrancy (needs --timeout 60000 under ASAN, same as main), websocket-proxy-tunnel-upgrade-leak, websocket-proxy-tunnel-client-leak, websocket-close-connecting, websocket-custom-headers, websocket-accept-header-validation, websocket-subprotocol-strict, error-event, websocket-client-short-read, test-ws-bidir-proxy, websocket-handshake-event, websocket-close-code, websocket-permessage-deflate-simple. Also drove ws:// and wss:// echo round-trips, wss:// verify-rejection, close() during connect / during handshake, and a non-101 response by hand.