Skip to content
This repository was archived by the owner on Jul 7, 2025. It is now read-only.
/ express Public archive

Commit 2b1f48c

Browse files
committed
Correctly handle GET/POST methods & content negotiation
1 parent feddaed commit 2b1f48c

File tree

2 files changed

+47
-10
lines changed

2 files changed

+47
-10
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ Changelog
3838

3939
To be released.
4040

41+
- Fixed the middleware to not fill `Request.body` when the request method is
42+
`GET` or `HEAD`.
43+
- Fixed the middleware to content-negotiate the response based on
44+
the `Accept` header.
45+
4146
### Version 0.1.2
4247

4348
Released on August 5, 2024.

src/index.ts

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { Readable } from "node:stream";
2-
import type { ReadableStream as WebReadableStream } from "node:stream/web";
32
import type { Federation } from "@fedify/fedify";
43
import type {
54
Request as ERequest,
@@ -25,15 +24,18 @@ export function integrateFederation<TContextData>(
2524
? contextData
2625
: Promise.resolve(contextData);
2726
contextDataPromise.then(async (contextData) => {
27+
let notFound = false;
28+
let notAcceptable = false;
2829
const response = await federation.fetch(request, {
2930
contextData,
3031
onNotFound: () => {
3132
// If the `federation` object finds a request not responsible for it
3233
// (i.e., not a federation-related request), it will call the `next`
3334
// function provided by the Express framework to continue the request
3435
// handling by the Express:
36+
notFound = true;
3537
next();
36-
return new Response("", { status: 404 }); // unused
38+
return new Response("Not found", { status: 404 }); // unused
3739
},
3840
onNotAcceptable: () => {
3941
// Similar to `onNotFound`, but slightly more tricky.
@@ -42,11 +44,27 @@ export function integrateFederation<TContextData>(
4244
// the `next` function provided by the Express framework to continue
4345
// if any route is matched, and otherwise, it will return a 406 Not
4446
// Acceptable response:
45-
if (req.route != null) next();
46-
return new Response("", { status: 406 });
47+
notAcceptable = true;
48+
next();
49+
return new Response("Not acceptable", {
50+
status: 406,
51+
headers: {
52+
"Content-Type": "text/plain",
53+
Vary: "Accept",
54+
},
55+
});
4756
},
4857
});
49-
setEResponse(res, response);
58+
if (notFound || (notAcceptable && req.route != null)) return;
59+
await setEResponse(res, response);
60+
// Prevent the Express framework from sending the response again:
61+
res.end();
62+
res.status = () => res;
63+
res.send = () => res;
64+
res.end = () => res;
65+
res.json = () => res;
66+
res.removeHeader = () => res;
67+
res.setHeader = () => res;
5068
});
5169
};
5270
}
@@ -64,14 +82,28 @@ function fromERequest(req: ERequest): Request {
6482
return new Request(url, {
6583
method: req.method,
6684
headers,
67-
body: Readable.toWeb(req) as ReadableStream<Uint8Array>,
85+
body:
86+
req.method === "GET" || req.method === "HEAD"
87+
? undefined
88+
: (Readable.toWeb(req) as ReadableStream<Uint8Array>),
6889
});
6990
}
7091

71-
function setEResponse(res: EResponse, response: Response): void {
92+
function setEResponse(res: EResponse, response: Response): Promise<void> {
7293
res.status(response.status);
7394
response.headers.forEach((value, key) => res.setHeader(key, value));
74-
if (response.body == null) return;
75-
// biome-ignore lint/suspicious/noExplicitAny: Readable.fromWeb is untyped
76-
Readable.fromWeb(response.body as WebReadableStream<any>).pipe(res);
95+
if (response.body == null) return Promise.resolve();
96+
const body = response.body;
97+
return new Promise((resolve) => {
98+
const reader = body.getReader();
99+
reader.read().then(function read({ done, value }) {
100+
if (done) {
101+
reader.releaseLock();
102+
resolve();
103+
return;
104+
}
105+
res.write(Buffer.from(value));
106+
reader.read().then(read);
107+
});
108+
});
77109
}

0 commit comments

Comments
 (0)