1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-01-11 08:33:43 -05:00

fix(ext/http): drop content-length header on compression (#13866)

This commit is contained in:
Satya Rohith 2022-03-07 22:43:15 +05:30 committed by GitHub
parent 4e1da28b39
commit 670aef5c1a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 71 additions and 1 deletions

View file

@ -1672,6 +1672,72 @@ Deno.test({
},
});
Deno.test({
name: "http server updates content-length header if compression is applied",
permissions: { net: true },
async fn() {
const hostname = "localhost";
const port = 4501;
let contentLength: string;
async function server() {
const listener = Deno.listen({ hostname, port });
const tcpConn = await listener.accept();
const httpConn = Deno.serveHttp(tcpConn);
const e = await httpConn.nextRequest();
assert(e);
const { request, respondWith } = e;
assertEquals(request.headers.get("Accept-Encoding"), "gzip, deflate, br");
const body = JSON.stringify({
hello: "deno",
now: "with",
compressed: "body",
});
contentLength = String(body.length);
const response = new Response(
body,
{
headers: {
"content-type": "application/json",
"content-length": contentLength,
},
},
);
await respondWith(response);
httpConn.close();
listener.close();
}
async function client() {
const url = `http://${hostname}:${port}/`;
const cmd = [
"curl",
"-I",
"--request",
"GET",
"--url",
url,
"--header",
"Accept-Encoding: gzip, deflate, br",
];
const proc = Deno.run({ cmd, stdout: "piped", stderr: "null" });
const status = await proc.status();
assert(status.success);
const output = decoder.decode(await proc.output());
assert(output.includes("vary: Accept-Encoding\r\n"));
assert(output.includes("content-encoding: gzip\r\n"));
// Ensure the content-length header is updated.
assert(!output.includes(`content-length: ${contentLength}\r\n`));
assert(output.includes("content-length: 72\r\n"));
console.log(output);
proc.close();
}
await Promise.all([server(), client()]);
},
});
function chunkedBodyReader(h: Headers, r: BufReader): Deno.Reader {
// Based on https://tools.ietf.org/html/rfc2616#section-19.4.6
const tp = new TextProtoReader(r);

View file

@ -610,6 +610,10 @@ async fn op_http_write_headers(
body_compressible && data.len() > 20 && accepts_compression;
if should_compress {
// Drop 'content-length' header. Hyper will update it using compressed body.
if let Some(headers) = builder.headers_mut() {
headers.remove("content-length");
}
// If user provided a ETag header for uncompressed data, we need to
// ensure it is a Weak Etag header ("W/").
if let Some(value) = etag_header {
@ -646,7 +650,7 @@ async fn op_http_write_headers(
// https://nginx.org/en/docs/http/ngx_http_gzip_module.html#gzip_comp_level
let mut writer = GzEncoder::new(Vec::new(), Compression::new(1));
writer.write_all(&data.into_bytes())?;
body = builder.body(writer.finish().unwrap().into())?;
body = builder.body(writer.finish()?.into())?;
}
}
} else {