Skip to content

Commit

Permalink
node: Handle "upgrade" event (denoland#2457)
Browse files Browse the repository at this point in the history
  • Loading branch information
bartlomieju committed Aug 24, 2022
1 parent f43f112 commit 98bf54e
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 5 deletions.
10 changes: 10 additions & 0 deletions _deno_unstable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,16 @@ export function serve(
}
}

export function upgradeHttpRaw(
...args: Parameters<typeof Deno.upgradeHttpRaw>
): ReturnType<typeof Deno.upgradeHttpRaw> {
if (typeof Deno.upgradeHttpRaw == "function") {
return Deno.upgradeHttpRaw(...args);
} else {
throw new TypeError("Requires --unstable");
}
}

export function addSignalListener(
...args: Parameters<typeof Deno.addSignalListener>
): ReturnType<typeof Deno.addSignalListener> {
Expand Down
29 changes: 24 additions & 5 deletions node/http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
import { OutgoingMessage } from "./_http_outgoing.ts";
import { Agent } from "./_http_agent.mjs";
import { urlToHttpOptions } from "./internal/url.ts";
import { constants, TCP } from "./internal_binding/tcp_wrap.ts";

const METHODS = [
"ACL",
Expand Down Expand Up @@ -421,6 +422,13 @@ export class IncomingMessageForServer extends NodeReadable {
get headers() {
return Object.fromEntries(this.#req.headers.entries());
}

get upgrade(): boolean {
return Boolean(
this.#req.headers.get("connection")?.toLowerCase().includes("upgrade") &&
this.#req.headers.get("upgrade"),
);
}
}

type ServerHandler = (
Expand Down Expand Up @@ -543,11 +551,22 @@ class ServerImpl extends EventEmitter {
#serve() {
const ac = new AbortController();
const handler = (request: Request) => {
return new Promise<Response>((resolve): void => {
const req = new IncomingMessageForServer(request);
const res = new ServerResponse(undefined, resolve);
this.emit("request", req, res);
});
const req = new IncomingMessageForServer(request);
if (req.upgrade && this.listenerCount("upgrade") > 0) {
const [conn, head] = DenoUnstable.upgradeHttpRaw(request) as [
Deno.Conn,
Uint8Array,
];
const socket = new Socket({
handle: new TCP(constants.SERVER, conn),
});
this.emit("upgrade", req, socket, new Buffer(head));
} else {
return new Promise<Response>((resolve): void => {
const res = new ServerResponse(undefined, resolve);
this.emit("request", req, res);
});
}
};

if (this.#hasClosed) {
Expand Down

0 comments on commit 98bf54e

Please sign in to comment.