chore: update std submodule to efa94f2 (#13260)

This commit is contained in:
Bartek Iwańczuk 2022-01-02 14:04:40 +01:00
parent 7f0a4ea68a
commit 82e4f9d885
No known key found for this signature in database
GPG Key ID: 0C6BCDDC3B3AD750
3 changed files with 150 additions and 20 deletions

View File

@ -1,35 +1,31 @@
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
import {
serve,
ServerRequest,
} from "../../../test_util/std/http/server_legacy.ts";
import { Server } from "../../../test_util/std/http/server.ts";
import { assertEquals } from "../../../test_util/std/testing/asserts.ts";
const addr = Deno.args[1] || "127.0.0.1:4555";
const addr = Deno.args[1] || "localhost:4555";
async function proxyServer() {
const server = serve(addr);
const [hostname, p] = addr.split(":");
const port = parseInt(p ?? 4555);
const server = new Server({ hostname, port, handler });
console.log(`Proxy server listening on http://${addr}/`);
for await (const req of server) {
proxyRequest(req);
}
await server.listenAndServe();
}
async function proxyRequest(req: ServerRequest) {
async function handler(req: Request): Promise<Response> {
console.log(`Proxy request to: ${req.url}`);
const proxyAuthorization = req.headers.get("proxy-authorization");
const headers = new Headers(req.headers);
const proxyAuthorization = headers.get("proxy-authorization");
if (proxyAuthorization) {
console.log(`proxy-authorization: ${proxyAuthorization}`);
req.headers.delete("proxy-authorization");
headers.delete("proxy-authorization");
}
const resp = await fetch(req.url, {
method: req.method,
headers: req.headers,
headers: headers,
});
req.respond({
return new Response(new Uint8Array(await resp.arrayBuffer()), {
status: resp.status,
body: new Uint8Array(await resp.arrayBuffer()),
headers: resp.headers,
});
}

View File

@ -1,7 +1,9 @@
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
import { chunkedBodyReader } from "../../../test_util/std/http/_io.ts";
import { BufReader, BufWriter } from "../../../test_util/std/io/bufio.ts";
import { Buffer } from "../../../test_util/std/io/buffer.ts";
import {
Buffer,
BufReader,
BufWriter,
} from "../../../test_util/std/io/buffer.ts";
import { TextProtoReader } from "../../../test_util/std/textproto/mod.ts";
import {
assert,
@ -1139,3 +1141,135 @@ Deno.test(
await promise;
},
);
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);
let finished = false;
const chunks: Array<{
offset: number;
data: Uint8Array;
}> = [];
async function read(buf: Uint8Array): Promise<number | null> {
if (finished) return null;
const [chunk] = chunks;
if (chunk) {
const chunkRemaining = chunk.data.byteLength - chunk.offset;
const readLength = Math.min(chunkRemaining, buf.byteLength);
for (let i = 0; i < readLength; i++) {
buf[i] = chunk.data[chunk.offset + i];
}
chunk.offset += readLength;
if (chunk.offset === chunk.data.byteLength) {
chunks.shift();
// Consume \r\n;
if ((await tp.readLine()) === null) {
throw new Deno.errors.UnexpectedEof();
}
}
return readLength;
}
const line = await tp.readLine();
if (line === null) throw new Deno.errors.UnexpectedEof();
// TODO(bartlomieju): handle chunk extension
const [chunkSizeString] = line.split(";");
const chunkSize = parseInt(chunkSizeString, 16);
if (Number.isNaN(chunkSize) || chunkSize < 0) {
throw new Deno.errors.InvalidData("Invalid chunk size");
}
if (chunkSize > 0) {
if (chunkSize > buf.byteLength) {
let eof = await r.readFull(buf);
if (eof === null) {
throw new Deno.errors.UnexpectedEof();
}
const restChunk = new Uint8Array(chunkSize - buf.byteLength);
eof = await r.readFull(restChunk);
if (eof === null) {
throw new Deno.errors.UnexpectedEof();
} else {
chunks.push({
offset: 0,
data: restChunk,
});
}
return buf.byteLength;
} else {
const bufToFill = buf.subarray(0, chunkSize);
const eof = await r.readFull(bufToFill);
if (eof === null) {
throw new Deno.errors.UnexpectedEof();
}
// Consume \r\n
if ((await tp.readLine()) === null) {
throw new Deno.errors.UnexpectedEof();
}
return chunkSize;
}
} else {
assert(chunkSize === 0);
// Consume \r\n
if ((await r.readLine()) === null) {
throw new Deno.errors.UnexpectedEof();
}
await readTrailers(h, r);
finished = true;
return null;
}
}
return { read };
}
async function readTrailers(
headers: Headers,
r: BufReader,
) {
const trailers = parseTrailer(headers.get("trailer"));
if (trailers == null) return;
const trailerNames = [...trailers.keys()];
const tp = new TextProtoReader(r);
const result = await tp.readMIMEHeader();
if (result == null) {
throw new Deno.errors.InvalidData("Missing trailer header.");
}
const undeclared = [...result.keys()].filter(
(k) => !trailerNames.includes(k),
);
if (undeclared.length > 0) {
throw new Deno.errors.InvalidData(
`Undeclared trailers: ${Deno.inspect(undeclared)}.`,
);
}
for (const [k, v] of result) {
headers.append(k, v);
}
const missingTrailers = trailerNames.filter((k) => !result.has(k));
if (missingTrailers.length > 0) {
throw new Deno.errors.InvalidData(
`Missing trailers: ${Deno.inspect(missingTrailers)}.`,
);
}
headers.delete("trailer");
}
function parseTrailer(field: string | null): Headers | undefined {
if (field == null) {
return undefined;
}
const trailerNames = field.split(",").map((v) => v.trim().toLowerCase());
if (trailerNames.length === 0) {
throw new Deno.errors.InvalidData("Empty trailer header.");
}
const prohibited = trailerNames.filter((k) => isProhibitedForTrailer(k));
if (prohibited.length > 0) {
throw new Deno.errors.InvalidData(
`Prohibited trailer names: ${Deno.inspect(prohibited)}.`,
);
}
return new Headers(trailerNames.map((key) => [key, ""]));
}
function isProhibitedForTrailer(key: string): boolean {
const s = new Set(["transfer-encoding", "content-length", "trailer"]);
return s.has(key.toLowerCase());
}

@ -1 +1 @@
Subproject commit e59b24543e670752701cd6b7d35ebb857d100210
Subproject commit efa94f2ccc2df51f9437e14bc5e3455b013b99b9