A bridge to work with Node.js Servers (HTTP1/HTTPS/HTTP2) using the Request + Response paradigm of the WHATWG, instead of streams.
import { createListener } from "./main.ts";
import { createServer } from "node:http";
const s = createServer(
createListener(async (req, { net }) => {
return new Response(
`Hello ${req.headers.get("user-agent")} from ${net.remoteAddress}`,
);
}),
);
s.listen(8989);
- Must use Node.js
^18.13.0 || ^19.3.0 || >=20.0because of important changes ref1, ref2, ref3, ref4 - In case there are multiple listeners installed, the first one to return a
Responsewill "win" - thatResponsewill be sent to the user. Note that this does not mean the first handler mounted or the first one to be called - some handlers can be slower than others. The first one to finish executing and returning a Response will win, regardless of when it was mounted.
- Tests: raw HTTP request text (not via a client)
- Make
netinto lazy so we don't call.address()on every request as it probably won't be used much. - Maybe: expose
.rawWriteto flush information to the client? (for e.g., Early Hints) -
apivalue ofhttp1vsh2. ALPN standard says it should behttp/1.1but ugh that's too long. Maybeh1is enough? Consistent, but nobody know what it means.
- HTTP/2 assumes the persistent connection is used. Therefore, no
Connection: keep-aliveis required. Stream: the lifecycle of a stream is equivalent to a request-response message in HTTP/1.x.- A new id is assigned until it reaches 2³¹. When the last id is used, the browser sends a GOAWAY frame to initialize a new TCP connection, and the stream ID is reset.
- The stream ID is assigned in increasing order. The odd number is for the browser, and the even number is for the server. Therefore, you see the odd number more often.
- The stream-0 is reserved for flow-control. It cannot be closed.
- HTTP/2 and How it Works
- whatwg-node adapter
- Remix Run adapter (also has a stream pump, if required)
- nodejs/node#42529