1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-24 16:19:12 -05:00

fix(ext/http): fix crash in dropped Deno.serve requests (#21252)

Fixes #21250

We were attempting to recycle dropped resource responses too early.
This commit is contained in:
Matt Mastracci 2023-11-18 13:16:53 -07:00 committed by GitHub
parent c213ad380f
commit 679b7bb8fa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 71 additions and 62 deletions

View file

@ -2727,13 +2727,14 @@ Deno.test(
},
);
for (const url of ["text", "file", "stream"]) {
for (const delay of ["delay", "nodelay"]) {
for (const url of ["text", "file", "stream"]) {
// Ensure that we don't panic when the incoming TCP request was dropped
// https://github.com/denoland/deno/issues/20315 and that we correctly
// close/cancel the response
Deno.test({
permissions: { read: true, write: true, net: true },
name: `httpServerTcpCancellation_${url}`,
name: `httpServerTcpCancellation_${url}_${delay}`,
fn: async function () {
const ac = new AbortController();
const streamCancelled = url == "stream" ? deferred() : undefined;
@ -2764,6 +2765,10 @@ for (const url of ["text", "file", "stream"]) {
}
waitForRequest.resolve();
await waitForAbort;
if (delay == "delay") {
await new Promise((r) => setTimeout(r, 1000));
}
// Allocate the request body
req.body;
return new Response(respBody);
@ -2775,7 +2780,9 @@ for (const url of ["text", "file", "stream"]) {
// Create a POST request and drop it once the server has received it
const conn = await Deno.connect({ port: servePort });
const writer = conn.writable.getWriter();
await writer.write(new TextEncoder().encode(`POST /${url} HTTP/1.0\n\n`));
await writer.write(
new TextEncoder().encode(`POST /${url} HTTP/1.0\n\n`),
);
await waitForRequest;
await writer.close();
@ -2794,6 +2801,7 @@ for (const url of ["text", "file", "stream"]) {
await server.finished;
},
});
}
}
Deno.test(

View file

@ -716,6 +716,8 @@ pub async fn op_http_set_response_body_resource(
}
};
*http.needs_close_after_finish() = true;
set_response(
http.clone(),
resource.size_hint().1.map(|s| s as usize),
@ -726,7 +728,6 @@ pub async fn op_http_set_response_body_resource(
},
);
*http.needs_close_after_finish() = true;
http.response_body_finished().await;
Ok(())
}