Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(adapter-node): add http2 support #185

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

aleclarson
Copy link
Contributor

Added support for node:http2. I decided not to create a new adapter-node-http2 package, since they share a lot of code.

import { createServer } from '@hattip/adapter-node/http2'

Same exact API as @hattip/adapter-node HTTP/1.1 API.

Other entry points include:

  • @hattip/adapter-node/http2/native-fetch
  • @hattip/adapter-node/http2/whatwg-node

No tests have been added yet.

Comment on lines +3 to +6
"editor.formatOnSave": true,
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added this out of convenience.

Comment on lines +133 to +147
type GenericResponse = {
write(chunk: Uint8Array): boolean;
once(event: "drain", listener: () => void): void;
once(event: "error", listener: (err: unknown) => void): void;
off(event: "drain", listener: () => void): void;
off(event: "error", listener: (err: unknown) => void): void;
};

async function writeAndAwait(
chunk: Uint8Array,
res: ServerResponse,
res: GenericResponse,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needed because write methods of http.ServerResponse and http2.Http2ServerResponse are not compatible according to the type-checker, even though they are when called without a callback.

Copy link
Contributor Author

@aleclarson aleclarson Nov 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file is used by functions that want to support both node:http and node:http2. For example, createRequestAdapter and sendResponse use these types.

@cyco130
Copy link
Member

cyco130 commented Nov 13, 2024

Looks great!

export interface DecoratedRequest extends Omit<IncomingMessage, "socket"> {
ip?: string;
protocol?: string;
socket: PossiblyEncryptedSocket;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This property was non-optional, but I saw another DecoratedRequest type in src/request.ts had it set as optional. Which one is right?

Copy link
Member

@cyco130 cyco130 Nov 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not optional, req.socket is always defined.

What I'm trying to achieve is that there's a badly documented req.socket.encrypted property that only exists when using node:https. The adapter uses it to infer the protocol (https or http) part of the URL when origin isn't manually set and trustProxy is false. (req.protocol is a non-standard Express property, useful when embedding a Hattip app into an Express app as a middleware).

I think the one in src/request.ts is just an error on my part.

@aleclarson aleclarson force-pushed the feat/adapter-node-http2 branch 2 times, most recently from ca02ba9 to f22ea93 Compare November 22, 2024 17:23
@aleclarson
Copy link
Contributor Author

aleclarson commented Nov 22, 2024

The test will fail since Node only supports HTTP/2 over TLS.

Also, it appears that native fetch in Node does not support HTTP/2 yet? nodejs/undici#2750

I don't know when I'll be able to investigate a solution.

@cyco130
Copy link
Member

cyco130 commented Nov 30, 2024

I'll start changing the testing setup to use node:http, node:http2, and node:https now (with self-signed certificates where necessary). There are other adapters that could benefit from it. So, leave it if you're already doing anything :D

@cyco130
Copy link
Member

cyco130 commented Dec 1, 2024

As far as I can understand Node can do HTTP/2 without SSL (just added tests for that, it seems to work). What it can't do seems to be upgrading from non-secure HTTP 1.1 to HTTP/2, it only supports upgrades via TLS ALPN.

More info here: nodejs/node#44887

@aleclarson aleclarson force-pushed the feat/adapter-node-http2 branch from f22ea93 to cee461b Compare December 7, 2024 17:50
@aleclarson
Copy link
Contributor Author

aleclarson commented Dec 7, 2024

@cyco130 Just rebased this PR. We're seeing timeouts in the Node HTTP/2 with native fetch test.

Could be my own fault, as I opted to keep the HTTP2 test fixture I wrote, since getting the new @hattip/adapter-node/http2 entry point to play with the fixture you wrote was proving difficult. 😅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants