mirror of
https://github.com/denoland/deno.git
synced 2025-03-03 17:34:47 -05:00
fix(ext/http): abort request signal when response errors (#17822)
This commit is contained in:
parent
1c285ac214
commit
92c3ac3034
2 changed files with 41 additions and 3 deletions
|
@ -2762,6 +2762,39 @@ for (const compression of [true, false]) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Deno.test({
|
||||||
|
name: "request signal is aborted when response errors",
|
||||||
|
permissions: { net: true },
|
||||||
|
async fn() {
|
||||||
|
let httpConn: Deno.HttpConn;
|
||||||
|
const promise = (async () => {
|
||||||
|
const listener = Deno.listen({ port: 4501 });
|
||||||
|
const conn = await listener.accept();
|
||||||
|
listener.close();
|
||||||
|
httpConn = Deno.serveHttp(conn);
|
||||||
|
const ev = await httpConn.nextRequest();
|
||||||
|
const { request, respondWith } = ev!;
|
||||||
|
|
||||||
|
await delay(300);
|
||||||
|
await assertRejects(() => respondWith(new Response("Hello World")));
|
||||||
|
assert(request.signal.aborted);
|
||||||
|
})();
|
||||||
|
|
||||||
|
const abortController = new AbortController();
|
||||||
|
|
||||||
|
fetch("http://127.0.0.1:4501/", {
|
||||||
|
signal: abortController.signal,
|
||||||
|
}).catch(() => {
|
||||||
|
// ignore
|
||||||
|
});
|
||||||
|
|
||||||
|
await delay(100);
|
||||||
|
abortController.abort();
|
||||||
|
await promise;
|
||||||
|
httpConn!.close();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
function chunkedBodyReader(h: Headers, r: BufReader): Deno.Reader {
|
function chunkedBodyReader(h: Headers, r: BufReader): Deno.Reader {
|
||||||
// Based on https://tools.ietf.org/html/rfc2616#section-19.4.6
|
// Based on https://tools.ietf.org/html/rfc2616#section-19.4.6
|
||||||
const tp = new TextProtoReader(r);
|
const tp = new TextProtoReader(r);
|
||||||
|
|
|
@ -18,7 +18,7 @@ import {
|
||||||
fromInnerRequest,
|
fromInnerRequest,
|
||||||
newInnerRequest,
|
newInnerRequest,
|
||||||
} from "ext:deno_fetch/23_request.js";
|
} from "ext:deno_fetch/23_request.js";
|
||||||
import * as abortSignal from "ext:deno_web/03_abort_signal.js";
|
import { AbortController } from "ext:deno_web/03_abort_signal.js";
|
||||||
import {
|
import {
|
||||||
_eventLoop,
|
_eventLoop,
|
||||||
_idleTimeoutDuration,
|
_idleTimeoutDuration,
|
||||||
|
@ -135,10 +135,10 @@ class HttpConn {
|
||||||
body !== null ? new InnerBody(body) : null,
|
body !== null ? new InnerBody(body) : null,
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
const signal = abortSignal.newSignal();
|
const abortController = new AbortController();
|
||||||
const request = fromInnerRequest(
|
const request = fromInnerRequest(
|
||||||
innerRequest,
|
innerRequest,
|
||||||
signal,
|
abortController.signal,
|
||||||
"immutable",
|
"immutable",
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
|
@ -149,6 +149,7 @@ class HttpConn {
|
||||||
request,
|
request,
|
||||||
this.#remoteAddr,
|
this.#remoteAddr,
|
||||||
this.#localAddr,
|
this.#localAddr,
|
||||||
|
abortController,
|
||||||
);
|
);
|
||||||
|
|
||||||
return { request, respondWith };
|
return { request, respondWith };
|
||||||
|
@ -185,6 +186,7 @@ function createRespondWith(
|
||||||
request,
|
request,
|
||||||
remoteAddr,
|
remoteAddr,
|
||||||
localAddr,
|
localAddr,
|
||||||
|
abortController,
|
||||||
) {
|
) {
|
||||||
return async function respondWith(resp) {
|
return async function respondWith(resp) {
|
||||||
try {
|
try {
|
||||||
|
@ -381,6 +383,9 @@ function createRespondWith(
|
||||||
}
|
}
|
||||||
ws[_serverHandleIdleTimeout]();
|
ws[_serverHandleIdleTimeout]();
|
||||||
}
|
}
|
||||||
|
} catch (error) {
|
||||||
|
abortController.abort(error);
|
||||||
|
throw error;
|
||||||
} finally {
|
} finally {
|
||||||
if (SetPrototypeDelete(httpConn.managedResources, streamRid)) {
|
if (SetPrototypeDelete(httpConn.managedResources, streamRid)) {
|
||||||
core.close(streamRid);
|
core.close(streamRid);
|
||||||
|
|
Loading…
Add table
Reference in a new issue