diff options
author | Yusuke Sakurai <kerokerokerop@gmail.com> | 2020-05-29 21:40:54 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-05-29 14:40:54 +0200 |
commit | b97459b5ae3918aae21f0c02342fd7c18189ad3e (patch) | |
tree | 137dee6006b3895509741ef1f28933fb8f5be6e2 /std/http/_io.ts | |
parent | 49c70774012e929b3c77b808edc5a7908bcb6fa2 (diff) |
fix: readTrailer didn't evaluate header names by case-insensitive (#4902)
Diffstat (limited to 'std/http/_io.ts')
-rw-r--r-- | std/http/_io.ts | 31 |
1 files changed, 15 insertions, 16 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` ); } |