Skip to content

Commit

Permalink
Retain Content-Length for custom Content-Encoding, closes #313
Browse files Browse the repository at this point in the history
  • Loading branch information
mrbbot committed Sep 3, 2022
1 parent 9ce44ba commit d4de3a6
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 4 deletions.
6 changes: 4 additions & 2 deletions packages/http-server/src/index.ts
Expand Up @@ -177,8 +177,6 @@ async function writeResponse(
// we're responsible for doing so.
const encoders: Transform[] = [];
if (headers["content-encoding"] && response.encodeBody === "auto") {
// Content-Length will be wrong as it's for the decoded length
delete headers["content-length"];
// Reverse of https://github.com/nodejs/undici/blob/48d9578f431cbbd6e74f77455ba92184f57096cf/lib/fetch/index.js#L1660
const codings = headers["content-encoding"]
.toString()
Expand All @@ -199,6 +197,10 @@ async function writeResponse(
break;
}
}
if (encoders.length > 0) {
// Content-Length will be wrong as it's for the decoded length
delete headers["content-length"];
}
}

// Add live reload script if enabled, this isn't an already encoded
Expand Down
59 changes: 57 additions & 2 deletions packages/http-server/test/index.spec.ts
Expand Up @@ -523,8 +523,12 @@ const autoEncodeMacro: Macro<
const port = await listen(t, http.createServer(createRequestListener(mf)));
return new Promise<void>((resolve) => {
http.get({ port }, async (res) => {
t.is(res.headers["content-length"], undefined);
t.is(res.headers["transfer-encoding"], "chunked");
if (encodes) {
t.is(res.headers["content-length"], undefined);
t.is(res.headers["transfer-encoding"], "chunked");
} else {
t.not(res.headers["content-length"], undefined);
}
t.is(res.headers["content-encoding"], encoding);
const compressed = await buffer(res);
const decompressed = decompress(compressed);
Expand Down Expand Up @@ -614,6 +618,57 @@ test("createRequestListener: should allow connection close before stream finishe
// This shouldn't throw a premature close
await writer.write(utf8Encode("data: test\n\n"));
});
test("createRequestListener: should include Content-Length header on responses", async (t) => {
// https://github.com/cloudflare/miniflare/issues/313
const mf = useMiniflareWithHandler({ HTTPPlugin }, {}, (globals, req) => {
const url = new globals.URL(req.url);
if (url.pathname === "/content-encoding") {
return new globals.Response("body", {
headers: { "Content-Encoding": "custom", "Content-Length": "4" },
});
} else if (url.pathname === "/encode-body-manual") {
return new globals.Response("body", {
encodeBody: "manual",
headers: { "Content-Length": "4" },
});
} else {
return new globals.Response(null, { status: 404 });
}
});
const port = await listen(t, http.createServer(createRequestListener(mf)));

// Check with custom `Content-Encoding` (https://github.com/cloudflare/miniflare/issues/312)
await new Promise<void>((resolve) => {
http.get({ port, path: "/content-encoding" }, async (res) => {
t.is(res.headers["content-length"], "4");
t.is(res.headers["content-encoding"], "custom");
t.is(await text(res), "body");
resolve();
});
});
await new Promise<void>((resolve) => {
http.get({ port, method: "HEAD", path: "/content-encoding" }, (res) => {
t.is(res.headers["content-length"], "4");
t.is(res.headers["content-encoding"], "custom");
resolve();
});
});

// Check with `encodeBody: "manual"`
await new Promise<void>((resolve) => {
http.get({ port, path: "/encode-body-manual" }, async (res) => {
t.is(res.headers["content-length"], "4");
t.is(await text(res), "body");
resolve();
});
});
await new Promise<void>((resolve) => {
http.get({ port, method: "HEAD", path: "/encode-body-manual" }, (res) => {
t.is(res.headers["content-length"], "4");
resolve();
});
});
});

test("createServer: handles regular requests", async (t) => {
const mf = useMiniflareWithHandler({ HTTPPlugin }, {}, (globals, req) => {
Expand Down

0 comments on commit d4de3a6

Please sign in to comment.