summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--std/http/_io.ts31
-rw-r--r--std/http/_io_test.ts4
2 files changed, 17 insertions, 18 deletions
diff --git a/std/http/_io.ts b/std/http/_io.ts
index 631adafd0..6b3796c5b 100644
--- a/std/http/_io.ts
+++ b/std/http/_io.ts
@@ -113,11 +113,10 @@ export function chunkedBodyReader(h: Headers, r: BufReader): Deno.Reader {
return { read };
}
-const kProhibitedTrailerHeaders = [
- "transfer-encoding",
- "content-length",
- "trailer",
-];
+function isProhibidedForTrailer(key: string): boolean {
+ const s = new Set(["transfer-encoding", "content-length", "trailer"]);
+ return s.has(key.toLowerCase());
+}
/**
* Read trailer headers from reader and append values to headers.
@@ -127,36 +126,36 @@ export async function readTrailers(
headers: Headers,
r: BufReader
): Promise<void> {
- const keys = parseTrailer(headers.get("trailer"));
- if (!keys) return;
+ const headerKeys = parseTrailer(headers.get("trailer"));
+ if (!headerKeys) return;
const tp = new TextProtoReader(r);
const result = await tp.readMIMEHeader();
assert(result !== null, "trailer must be set");
for (const [k, v] of result) {
- if (!keys.has(k)) {
+ if (!headerKeys.has(k)) {
throw new Error("Undeclared trailer field");
}
- keys.delete(k);
+ headerKeys.delete(k);
headers.append(k, v);
}
- assert(keys.size === 0, "Missing trailers");
+ assert(Array.from(headerKeys).length === 0, "Missing trailers");
headers.delete("trailer");
}
-function parseTrailer(field: string | null): Set<string> | undefined {
+function parseTrailer(field: string | null): Headers | undefined {
if (field == null) {
return undefined;
}
- const keys = field.split(",").map((v) => v.trim());
+ const keys = field.split(",").map((v) => v.trim().toLowerCase());
if (keys.length === 0) {
throw new Error("Empty trailer");
}
- for (const invalid of kProhibitedTrailerHeaders) {
- if (keys.includes(invalid)) {
+ for (const key of keys) {
+ if (isProhibidedForTrailer(key)) {
throw new Error(`Prohibited field for trailer`);
}
}
- return new Set(keys);
+ return new Headers(keys.map((key) => [key, ""]));
}
export async function writeChunkedBody(
@@ -199,7 +198,7 @@ export async function writeTrailers(
.map((s) => s.trim().toLowerCase());
for (const f of trailerHeaderFields) {
assert(
- !kProhibitedTrailerHeaders.includes(f),
+ !isProhibidedForTrailer(f),
`"${f}" is prohibited for trailer header`
);
}
diff --git a/std/http/_io_test.ts b/std/http/_io_test.ts
index c22ebdf07..3e74e365d 100644
--- a/std/http/_io_test.ts
+++ b/std/http/_io_test.ts
@@ -82,7 +82,7 @@ test("chunkedBodyReader with trailers", async () => {
test("readTrailers", async () => {
const h = new Headers({
- trailer: "deno,node",
+ trailer: "Deno, Node",
});
const trailer = ["deno: land", "node: js", "", ""].join("\r\n");
await readTrailers(h, new BufReader(new Buffer(encode(trailer))));
@@ -112,7 +112,7 @@ test("readTrailer should throw if undeclared headers found in trailer", async ()
});
test("readTrailer should throw if trailer contains prohibited fields", async () => {
- for (const f of ["content-length", "trailer", "transfer-encoding"]) {
+ for (const f of ["Content-Length", "Trailer", "Transfer-Encoding"]) {
const h = new Headers({
trailer: f,
});