summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron O'Mullan <aaron.omullan@gmail.com>2022-05-17 14:02:45 +0200
committerGitHub <noreply@github.com>2022-05-17 14:02:45 +0200
commit037e46bb51d67210f4928cad4dd12df3dee1fe05 (patch)
treedcaca9cde4713c866f9d5060eeab4e1c674d8aa3
parent1fa75f75c90b744d63e451519311f27ba55c21d7 (diff)
fix(ext/http): skip auto-compression if content-encoding present (#14641)
Regression from #14552
-rw-r--r--cli/tests/unit/http_test.ts58
-rw-r--r--ext/http/lib.rs3
2 files changed, 61 insertions, 0 deletions
diff --git a/cli/tests/unit/http_test.ts b/cli/tests/unit/http_test.ts
index 3f9141470..2a4b7df01 100644
--- a/cli/tests/unit/http_test.ts
+++ b/cli/tests/unit/http_test.ts
@@ -1978,6 +1978,64 @@ Deno.test({
},
});
+Deno.test({
+ name: "http server custom content-encoding is left untouched",
+ permissions: { net: true, run: 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"), "deflate, gzip");
+ const body = new Uint8Array([3, 1, 4, 1]);
+ contentLength = String(body.length);
+ const response = new Response(
+ body,
+ {
+ headers: {
+ "content-length": contentLength,
+ "content-encoding": "arbitrary",
+ },
+ },
+ );
+ await respondWith(response);
+ httpConn.close();
+ listener.close();
+ }
+
+ async function client() {
+ const url = `http://${hostname}:${port}/`;
+ const cmd = [
+ "curl",
+ "-i",
+ "--request",
+ "GET",
+ "--url",
+ url,
+ // "--compressed", // Windows curl does not support --compressed
+ "--header",
+ "Accept-Encoding: deflate, gzip",
+ ];
+ 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: arbitrary\r\n"));
+ proc.close();
+ }
+
+ await Promise.all([server(), client()]);
+ },
+});
+
Deno.test("upgradeHttp tcp", async () => {
async function client() {
const tcpConn = await Deno.connect({ port: 4501 });
diff --git a/ext/http/lib.rs b/ext/http/lib.rs
index edc4c1e83..42211105d 100644
--- a/ext/http/lib.rs
+++ b/ext/http/lib.rs
@@ -680,8 +680,11 @@ fn should_compress(headers: &hyper::HeaderMap) -> bool {
// indicates the contents of the body were negotiated based directly
// with the user code and we can't compress the response
let content_range = headers.contains_key(hyper::header::CONTENT_RANGE);
+ // assume body is already compressed if Content-Encoding header present, thus avoid recompressing
+ let is_precompressed = headers.contains_key(hyper::header::CONTENT_ENCODING);
!content_range
+ && !is_precompressed
&& !cache_control_no_transform(headers).unwrap_or_default()
&& headers
.get(hyper::header::CONTENT_TYPE)