Skip to content

Commit 5416653

Browse files
committed
Add http/2 support
Closes #42
1 parent a0889f8 commit 5416653

File tree

9 files changed

+140
-0
lines changed

9 files changed

+140
-0
lines changed

packages/node-fetch-server/CHANGELOG.md

+26
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,32 @@
22

33
This is the changelog for [`node-fetch-server`](https://github.com/mjackson/remix-the-web/tree/main/packages/node-fetch-server). It follows [semantic versioning](https://semver.org/).
44

5+
## HEAD
6+
7+
- Add http/2 support with an example
8+
9+
```ts
10+
import * as http2 from 'node:http2';
11+
import { createRequestListener } from '@mjackson/node-fetch-server';
12+
13+
let server = http2.createSecureServer(options);
14+
15+
server.on(
16+
'request',
17+
createRequestListener((request) => {
18+
let url = new URL(request.url);
19+
20+
if (url.pathname === '/') {
21+
return new Response('Hello HTTP/2!', {
22+
headers: { 'content-type': 'text/plain' },
23+
});
24+
}
25+
26+
return new Response('Not Found', { status: 404 });
27+
}),
28+
);
29+
```
30+
531
## v0.5.1 (2025-01-25)
632

733
- Iterate manually over response bodies in `sendResponse` instead of using `for await...of`. This seems to avoid an issue where the iterator tries to read from a stream after the lock has been released.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# node-fetch-server HTTP/2 Example
2+
3+
This is an example of building a http/2 server for Node.js using [the built-in `http2` module](https://nodejs.org/api/http2.html).
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"name": "node-fetch-server-http2-example",
3+
"private": true,
4+
"type": "module",
5+
"dependencies": {
6+
"@mjackson/node-fetch-server": "workspace:^"
7+
}
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIICpDCCAYwCCQDont9/q43GLTANBgkqhkiG9w0BAQsFADAUMRIwEAYDVQQDDAls
3+
b2NhbGhvc3QwHhcNMjUwMjA2MTkyMjU5WhcNMjYwMjA2MTkyMjU5WjAUMRIwEAYD
4+
VQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDX
5+
z69g6TBkbdv0TMeTL3jRLgdiSoTyqjcjLEakgEfPDtS0vLadkrqiTipx5do6CpyB
6+
0vMqrYVgFnnUKykJuTPh5pFIdTFbAKkv3YcyVMRfzt5eMLRFQ5iFbmbzme7BksaZ
7+
D6b0ahwnNPvRGX/Kz362wQ10nK4YP7JCXbc0Ybxvdfq5o8L0uoOjW5K+8JULVLmc
8+
imeXA8NLe8ui/flvBgc/P4qt5SVh0S+/FjTEa12DCzxkvaOmWKqpHjzUMg0aKkrV
9+
Q22hjaEdkgcKomqC/4I3de6bGr828yJltXxTp80/8TaM4U7xPi8hvUfOW+wLPUK9
10+
ODJ+XtQu1LhtQwwe1a0RAgMBAAEwDQYJKoZIhvcNAQELBQADggEBADsHhsAveJ7N
11+
LOS/J8+y5/KGphlW0/bZzsJGCkm9YMFfPW6U3Ac85X67oahzd7kPI5n2z867dVXO
12+
Ix60enYF3xf2IzcL/FVSL+dDW6JKIp6lB+qdlA7EeN3Segx+NV/fErHUZmL5WmBN
13+
hNlOdEx06uo6Pp21+RyktDMFKBbpDbPrWHziNWJz0mT6SA1RMT8ElWxKXalO6XFT
14+
yJCM/iwpm4SrTZ11j8Nszcv730DrMr/hF+uO4d2N4FzV1NAKv66JpXnzPC1jcCFs
15+
Js7880NtdEdBVadp8gB5Cmu7I6ZcNKe24x1nRNtyddQkgUllKOoIGobrHk02l0PV
16+
0gnz6agIzfQ=
17+
-----END CERTIFICATE-----
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
-----BEGIN CERTIFICATE REQUEST-----
2+
MIICWTCCAUECAQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0B
3+
AQEFAAOCAQ8AMIIBCgKCAQEA18+vYOkwZG3b9EzHky940S4HYkqE8qo3IyxGpIBH
4+
zw7UtLy2nZK6ok4qceXaOgqcgdLzKq2FYBZ51CspCbkz4eaRSHUxWwCpL92HMlTE
5+
X87eXjC0RUOYhW5m85nuwZLGmQ+m9GocJzT70Rl/ys9+tsENdJyuGD+yQl23NGG8
6+
b3X6uaPC9LqDo1uSvvCVC1S5nIpnlwPDS3vLov35bwYHPz+KreUlYdEvvxY0xGtd
7+
gws8ZL2jpliqqR481DINGipK1UNtoY2hHZIHCqJqgv+CN3Xumxq/NvMiZbV8U6fN
8+
P/E2jOFO8T4vIb1HzlvsCz1CvTgyfl7ULtS4bUMMHtWtEQIDAQABoAAwDQYJKoZI
9+
hvcNAQELBQADggEBAMyfFv3WSqg/X6RmrIZjuFdZ6fnV8Gd5twFuzGWcxcTaxQZx
10+
OwY7hKXXFsTRjx15T84wV7KcRK26RY9CJB+28zWp5r67/zLO1DkeZ+DuDjyazLPD
11+
iPMmpOhzK9dsu3ymhRjlQcKtUHfK5x/hlSvKaL8LYhEMY8G16ST8GQxoNAR+ax6t
12+
zq+wS7WccS7kKXr4uJf0H0KL3CqkmzLDlyiV/4f2UGQPk2riYihPuaikb5tLftUv
13+
cDsLwa4YOU6shdKa6Z0yq2oMjRYzAS79/gF22oxs5pK0Fzf5geQGjbzqd/CPrvWM
14+
M0IMtej9xpq+CfQv/pxAxmLEMW4WCnnqFwCN/xI=
15+
-----END CERTIFICATE REQUEST-----
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import * as http2 from 'node:http2';
2+
import * as fs from 'node:fs';
3+
import * as path from 'node:path';
4+
import { createRequestListener } from '@mjackson/node-fetch-server';
5+
6+
const __dirname = path.dirname(new URL(import.meta.url).pathname);
7+
const PORT = 3000;
8+
9+
let options = {
10+
key: fs.readFileSync(path.join(__dirname, 'server.key')),
11+
cert: fs.readFileSync(path.join(__dirname, 'server.crt')),
12+
};
13+
14+
let server = http2.createSecureServer(options);
15+
16+
server.on(
17+
'request',
18+
createRequestListener((request) => {
19+
let url = new URL(request.url);
20+
21+
if (url.pathname === '/') {
22+
return new Response('Hello HTTP/2!', {
23+
headers: { 'content-type': 'text/plain' },
24+
});
25+
}
26+
27+
return new Response('Not Found', { status: 404 });
28+
}),
29+
);
30+
31+
server.on('error', (err) => {
32+
console.error('Server error:', err);
33+
});
34+
35+
server.listen(PORT, () => {
36+
console.log(`Server running at https://localhost:${PORT}`);
37+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
-----BEGIN RSA PRIVATE KEY-----
2+
MIIEowIBAAKCAQEA18+vYOkwZG3b9EzHky940S4HYkqE8qo3IyxGpIBHzw7UtLy2
3+
nZK6ok4qceXaOgqcgdLzKq2FYBZ51CspCbkz4eaRSHUxWwCpL92HMlTEX87eXjC0
4+
RUOYhW5m85nuwZLGmQ+m9GocJzT70Rl/ys9+tsENdJyuGD+yQl23NGG8b3X6uaPC
5+
9LqDo1uSvvCVC1S5nIpnlwPDS3vLov35bwYHPz+KreUlYdEvvxY0xGtdgws8ZL2j
6+
pliqqR481DINGipK1UNtoY2hHZIHCqJqgv+CN3Xumxq/NvMiZbV8U6fNP/E2jOFO
7+
8T4vIb1HzlvsCz1CvTgyfl7ULtS4bUMMHtWtEQIDAQABAoIBAGlbyDgcv/ZXt+lF
8+
zq0poOcmfI5c6Rj7Rp3SUM6gne4VRHzUIKc+6gSw+oHOgEKTyaKL1RFB03p8no+Z
9+
XpiTpSOlB8qDBEx0PyTSFt3YimJnwSHkzy19eamyo2pL/UbdnD0/aferEgGGGWYU
10+
99GQiUE5cJM8prXJ6wIBdJ6LFI6o+fNWjWAQeg6wEuA3MbfvQ4uZo8WvknVaJLqa
11+
AYMPK/V1bT9/hmaLFfDiLMrD92ZC+mJqgEvsLrU64mQmASa7Zfh9v6sqqS6h4vjZ
12+
fmJfQjG1+g1rCkE2kHEYKmziz3A0A5FUjWwny3RSt9lbIJh2E0vcgYtbF3abUCIe
13+
aQOQkP0CgYEA7MLq430P+Arn2xFPX8Y7XeQftv++qBsLZeq4lSV6ru1/mG68xFrm
14+
fqXI/xi3lyfbezpG0BFQGqVFB1f70IMGKcM7Ph1l5mI4OWcpqzcKi8UqGRzeFJ9Z
15+
NB7HWrU8h2dl/d5yRF4EmYj2RrBxoZdjN0H+3yL/TotcTuPPPbDKeRMCgYEA6Vj3
16+
Kjnn3avIMK/UWkREXoGCvRQH2wD4h6vQs1ro2PNMyWB+JS1XxucJbPfDmZhqxkyt
17+
rWehadRrmlMfTX27llRjeoVH3h54QE58lgLme+Ak3qjNiiUlFVFiCpEaYrba3iDk
18+
A3jqQ1naqXyP6sbiItRZ96v05hiWIYe8WkaiCcsCgYAUziAT84Z2toafUosWEHZh
19+
Ds3Wp+yaGx5KS3EC8jMwsgAXZgvCeXZtxKW//O0NJFx+HKXiXNMcNE+3kHy5Wvos
20+
q1JGaBDvSMxGBxG7UO/lTmMfp9DAISyWjunXx7tU7rogr+58oYJn94gkuBaUK5h1
21+
X6BE/W9P+KEY8Z3hfuqb7wKBgHGDhtEy1BmgvET68/lpZjz3Eat7OAsQoNYW/fKS
22+
Ed2gFcWMvDDHqwCmWY55xNxOKfsHSCGn3PzHigTL1Nl0hbGuoanzdi+WcPcPd0ne
23+
ZVLzidwLD9nZEf4Z1fC//67vtu8B3wnVY1iaOGXko3oZf95joNR8ASmB4l6zUiw0
24+
WhUbAoGBAJIAzNQMMIF3fSUL4CnhTaWuo6UNUvQjXiSfx9opzWLfMWgGqoJ1RqEF
25+
HTL3jLQQfypqy6E0LtVRMhXJL/J1dY46ZJmkYxosDyfi1Om1wmKV4mbUGoIKiMFd
26+
1uOjZjUX3/XGA5rt1pdQxdwbauDgrPorQkKJFFWbCYZ9YCAxGxP9
27+
-----END RSA PRIVATE KEY-----

pnpm-lock.yaml

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pnpm-workspace.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@ packages:
44
- packages/multipart-parser/bench
55
- packages/multipart-parser/examples/*
66
- packages/node-fetch-server/bench
7+
- packages/node-fetch-server/examples/*
78
- packages/tar-parser/bench
89
- scripts

0 commit comments

Comments
 (0)