ITADN

Client disconnect leaves dangling response stream on inbound requests when using node adapter

#161Closedmini-ninja-64 创建于 2024-10-11
bug
M
mini-ninja-64commented
Hello, I like hattip and have been using it on a few projects, I think I have found a bug. If this is intended behaviour please disregard this issue. ## Description When a user connects to a hattip server (using the node adapter) and they cancel their connection before the request can complete, the response stream is left hanging. ## Recreation The easiest way to recreate this, is to make a handler that responds with a long lived request, a server side events style setup. ```ts const httpServer = createServer((req) => { const headers = new Headers({ "Content-Type": "text/event-stream", "Cache-Control": "no-cache", Connection: "keep-alive", }); const encoder = new TextEncoder(); const pingBytes = encoder.encode("ping\n"); let pingInterval: NodeJS.Timeout | undefined; return new Response( new ReadableStream<Uint8Array>({ start(controller) { console.log("Starting request"); pingInterval = setInterval(() => { controller.enqueue(pingBytes); console.log("pinging"); }, 1 * 1000); }, cancel(reason) { console.log("Cancelled due to: ", reason); clearInterval(pingInterval); }, }), { headers } ); }).listen(3000, () => { console.log(`Server listening on http://0.0.0.0:3000`); }); ``` Curl Output: ```sh ~ curl --request GET --no-buffer http://localhost:3000/ ping ^C ``` Application Output: ```sh Server started Starting request pinging pinging pinging pinging ... and so on ``` ## Why? I am not mega familiar with the internals of hattip but, it seems to me that because node handles client disconnects at the request level and request error events [appear to only be listened](https://github.com/hattipjs/hattip/blob/4748fe56d6ea845470b6b6a4cc8bc50d5566c60f/packages/adapter/adapter-node/src/request.ts#L144) to by `!GET && !Node` requests while also only erroring out the request controller then there is no way for a handler to handle a client disconnecting prematurely as request bodies are handed elsewhere with no control over the running handler, this results in dangling connections as seen above. ## Possible Solutions As stated previously "I am not mega familiar with the internals of hattip", but it seems that if you want to handle this behaviour on the response side you would need to intercept error events on node requests and proxy them to cancel a `Response`'s `ReadableStream`. Otherwise I guess there would need to be a way to check a requests status outside of the `request.body` `ReadableStream` as that does not provide easy access to checking error status and such, or maybe just some generic error handler function can be supplied somewhere 🤔. Thank you for all your work on hattip (it is a pleasure to use) and thank you for taking the time to read this. I'm also very happy to implement a solution, but would like to hear your API design thoughts before hand.
关闭于 2024-10-23 7 条评论