0
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-03-03 09:31:22 -05:00

fix(std/http): avoid directly modifying the headers object (#5024)

This commit is contained in:
木杉 2020-05-01 22:35:18 +08:00 committed by GitHub
parent be65f6692f
commit e57f0749e7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 23 additions and 25 deletions

View file

@ -11,7 +11,6 @@ import { posix, extname } from "../path/mod.ts";
import { listenAndServe, ServerRequest, Response } from "./server.ts";
import { parse } from "../flags/mod.ts";
import { assert } from "../testing/asserts.ts";
import { setContentLength } from "./io.ts";
interface EntryInfo {
mode: string;
@ -173,7 +172,6 @@ async function serveDir(
body: page,
headers,
};
setContentLength(res);
return res;
}

View file

@ -214,24 +214,6 @@ export async function writeTrailers(
await writer.flush();
}
export function setContentLength(r: Response): void {
if (!r.headers) {
r.headers = new Headers();
}
if (r.body) {
if (!r.headers.has("content-length")) {
// typeof r.body === "string" handled in writeResponse.
if (r.body instanceof Uint8Array) {
const bodyLength = r.body.byteLength;
r.headers.set("content-length", bodyLength.toString());
} else {
r.headers.set("transfer-encoding", "chunked");
}
}
}
}
export async function writeResponse(
w: Deno.Writer,
r: Response
@ -253,14 +235,21 @@ export async function writeResponse(
let out = `HTTP/${protoMajor}.${protoMinor} ${statusCode} ${statusText}\r\n`;
setContentLength(r);
assert(r.headers != null);
const headers = r.headers;
const headers = r.headers ?? new Headers();
if (r.body && !headers.get("content-length")) {
if (r.body instanceof Uint8Array) {
out += `content-length: ${r.body.byteLength}\r\n`;
} else if (!headers.get("transfer-encoding")) {
out += "transfer-encoding: chunked\r\n";
}
}
for (const [key, value] of headers) {
out += `${key}: ${value}\r\n`;
}
out += "\r\n";
out += `\r\n`;
const header = encoder.encode(out);
const n = await writer.write(header);

View file

@ -19,7 +19,7 @@ import { chunkedBodyReader } from "./io.ts";
import { ServerRequest, Response } from "./server.ts";
import { StringReader } from "../io/readers.ts";
import { mockConn } from "./mock.ts";
const { Buffer, test } = Deno;
const { Buffer, test, readAll } = Deno;
test("bodyReader", async () => {
const text = "Hello, Deno";
@ -357,6 +357,17 @@ test("writeResponse with trailer", async () => {
assertEquals(ret, exp);
});
test("writeResponseShouldNotModifyOriginHeaders", async () => {
const headers = new Headers();
const buf = new Deno.Buffer();
await writeResponse(buf, { body: "foo", headers });
assert(decode(await readAll(buf)).includes("content-length: 3"));
await writeResponse(buf, { body: "hello", headers });
assert(decode(await readAll(buf)).includes("content-length: 5"));
});
test("readRequestError", async function (): Promise<void> {
const input = `GET / HTTP/1.1
malformedHeader