summaryrefslogtreecommitdiff
path: root/ext/http
diff options
context:
space:
mode:
Diffstat (limited to 'ext/http')
-rw-r--r--ext/http/00_serve.js22
-rw-r--r--ext/http/01_http.js27
2 files changed, 37 insertions, 12 deletions
diff --git a/ext/http/00_serve.js b/ext/http/00_serve.js
index 17a67814b..b99f28c0f 100644
--- a/ext/http/00_serve.js
+++ b/ext/http/00_serve.js
@@ -36,6 +36,7 @@ import {
} from "ext:deno_web/06_streams.js";
import { listen, listenOptionApiName, TcpConn } from "ext:deno_net/01_net.js";
import { listenTls } from "ext:deno_net/02_tls.js";
+import { SymbolAsyncDispose } from "ext:deno_web/00_infra.js";
const {
ArrayPrototypePush,
ObjectHasOwn,
@@ -343,6 +344,7 @@ class CallbackContext {
fallbackHost;
serverRid;
closed;
+ /** @type {Promise<void> | undefined} */
closing;
listener;
@@ -671,22 +673,25 @@ function serveHttpOn(context, callback) {
PromisePrototypeCatch(callback(req), promiseErrorHandler);
}
- if (!context.closed && !context.closing) {
- context.closed = true;
- await op_http_close(rid, false);
+ if (!context.closing && !context.closed) {
+ context.closing = op_http_close(rid, false);
context.close();
}
+
+ await context.closing;
+ context.close();
+ context.closed = true;
})();
return {
finished,
async shutdown() {
- if (!context.closed && !context.closing) {
+ if (!context.closing && !context.closed) {
// Shut this HTTP server down gracefully
- context.closing = true;
- await op_http_close(context.serverRid, true);
- context.closed = true;
+ context.closing = op_http_close(context.serverRid, true);
}
+ await context.closing;
+ context.closed = true;
},
ref() {
ref = true;
@@ -700,6 +705,9 @@ function serveHttpOn(context, callback) {
core.unrefOp(currentPromise[promiseIdSymbol]);
}
},
+ [SymbolAsyncDispose]() {
+ return this.shutdown();
+ },
};
}
diff --git a/ext/http/01_http.js b/ext/http/01_http.js
index 705e616e4..cfe0f710e 100644
--- a/ext/http/01_http.js
+++ b/ext/http/01_http.js
@@ -44,6 +44,7 @@ import {
ReadableStreamPrototype,
} from "ext:deno_web/06_streams.js";
import { serve } from "ext:deno_http/00_serve.js";
+import { SymbolDispose } from "ext:deno_web/00_infra.js";
const {
ArrayPrototypeIncludes,
ArrayPrototypeMap,
@@ -69,6 +70,9 @@ const {
const connErrorSymbol = Symbol("connError");
const _deferred = Symbol("upgradeHttpDeferred");
+/** @type {(self: HttpConn, rid: number) => boolean} */
+let deleteManagedResource;
+
class HttpConn {
#rid = 0;
#closed = false;
@@ -79,7 +83,12 @@ class HttpConn {
// that were created during lifecycle of this request.
// When the connection is closed these resources should be closed
// as well.
- managedResources = new SafeSet();
+ #managedResources = new SafeSet();
+
+ static {
+ deleteManagedResource = (self, rid) =>
+ SetPrototypeDelete(self.#managedResources, rid);
+ }
constructor(rid, remoteAddr, localAddr) {
this.#rid = rid;
@@ -123,7 +132,7 @@ class HttpConn {
}
const { 0: streamRid, 1: method, 2: url } = nextRequest;
- SetPrototypeAdd(this.managedResources, streamRid);
+ SetPrototypeAdd(this.#managedResources, streamRid);
/** @type {ReadableStream<Uint8Array> | undefined} */
let body = null;
@@ -167,13 +176,21 @@ class HttpConn {
if (!this.#closed) {
this.#closed = true;
core.close(this.#rid);
- for (const rid of new SafeSetIterator(this.managedResources)) {
- SetPrototypeDelete(this.managedResources, rid);
+ for (const rid of new SafeSetIterator(this.#managedResources)) {
+ SetPrototypeDelete(this.#managedResources, rid);
core.close(rid);
}
}
}
+ [SymbolDispose]() {
+ core.tryClose(this.#rid);
+ for (const rid of new SafeSetIterator(this.#managedResources)) {
+ SetPrototypeDelete(this.#managedResources, rid);
+ core.tryClose(rid);
+ }
+ }
+
[SymbolAsyncIterator]() {
// deno-lint-ignore no-this-alias
const httpConn = this;
@@ -395,7 +412,7 @@ function createRespondWith(
abortController.abort(error);
throw error;
} finally {
- if (SetPrototypeDelete(httpConn.managedResources, streamRid)) {
+ if (deleteManagedResource(httpConn, streamRid)) {
core.close(streamRid);
}
}