diff --git a/application.test.ts b/application.test.ts index 6e62817..e619d25 100644 --- a/application.test.ts +++ b/application.test.ts @@ -998,6 +998,52 @@ Deno.test({ }, }); +Deno.test({ + name: "application .fetch() websocket upgrade", + ignore: isNode(), + sanitizeOps: false, + sanitizeResources: false, + async fn() { + const app = new Application(); + let wsReceived = ""; + app.use((ctx) => { + const ws = ctx.upgrade(); + ws.onmessage = (event) => { + wsReceived = event.data; + ws.send("pong"); + ws.close(); + }; + }); + + const controller = new AbortController(); + let port = 0; + const { promise: listeningPromise, resolve: listeningResolve } = + createPromiseWithResolvers(); + const server = Deno.serve({ + signal: controller.signal, + port: 0, + handler: app.fetch as (req: Request) => Promise, + onListen({ port: p }) { + port = p; + listeningResolve(); + }, + }); + await listeningPromise; + + const { promise, resolve, reject } = createPromiseWithResolvers(); + const ws = new WebSocket(`ws://localhost:${port}/`); + ws.onopen = () => ws.send("ping"); + ws.onmessage = (event) => resolve(event.data); + ws.onerror = () => reject(new Error("WebSocket error")); + const reply = await promise; + assertEquals(reply, "pong"); + assertEquals(wsReceived, "ping"); + controller.abort(); + await server.finished; + teardown(); + }, +}); + function isBigInitValue(value: unknown): value is { __bigint: string } { return value != null && typeof value === "object" && "__bigint" in value && typeof (value as any).__bigint === "string"; diff --git a/application.ts b/application.ts index 3dcd423..e0fa771 100644 --- a/application.ts +++ b/application.ts @@ -718,6 +718,10 @@ export class Application> ); try { await this.#getComposed()(context); + if (context.respond === false) { + context.response.destroy(); + return contextRequest.response; + } const response = await context.response.toDomResponse(); context.response.destroy(false); return response;