mirror of
https://github.com/Facepunch/sbox-public.git
synced 2026-08-02 08:50:18 -04:00
RequestStreamAsync went through RequestAsync, which sends with the default HttpCompletionOption.ResponseContentRead - so the whole body was downloaded before the task resolved, and the "stream" handed back was the buffer. A response that never ends (NDJSON, SSE, a chunked long poll) therefore never resolved at all. It also did `using var response`, disposing the response and with it the content stream, before returning that stream to the caller. That second bug hid the first: you could not read the stream far enough to notice the buffering. Send with ResponseHeadersRead and return a stream that owns the HttpResponseMessage and disposes it with itself. RequestAsync's signature is untouched, so no Sandbox.Access change is needed, and the consumer side (System.IO.Stream.*, StreamReader) was already whitelisted. Validation is unaffected: SboxHttpHandler runs Http.IsAllowedAsync before every send, redirects included, all before the headers come back. WebTests.HttpStreamTest serves paced chunked NDJSON on localhost:8080 (a port Http.IsAllowed accepts) and asserts the call returns before the body ends, that the lines arrive spread across it rather than at once, and that a non-2xx still throws.