summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBartek IwaƄczuk <biwanczuk@gmail.com>2022-01-02 14:04:40 +0100
committerGitHub <noreply@github.com>2022-01-02 14:04:40 +0100
commita721c34c19a07ece6677f4efc8aa0db881b310f0 (patch)
tree10ae7a30ca4a1e2d43d572acc98997109e1ce95c
parent6ab46b559c7668071c37decfc3fe304e4fb034cb (diff)
chore: update std submodule to efa94f2 (#13260)
-rw-r--r--cli/tests/testdata/045_proxy_test.ts28
-rw-r--r--cli/tests/unit/http_test.ts140
m---------test_util/std0
3 files changed, 149 insertions, 19 deletions
diff --git a/cli/tests/testdata/045_proxy_test.ts b/cli/tests/testdata/045_proxy_test.ts
index 1433b426a..e185b04f0 100644
--- a/cli/tests/testdata/045_proxy_test.ts
+++ b/cli/tests/testdata/045_proxy_test.ts
@@ -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,
});
}
diff --git a/cli/tests/unit/http_test.ts b/cli/tests/unit/http_test.ts
index a52ea3cc7..4d1ad4ab6 100644
--- a/cli/tests/unit/http_test.ts
+++ b/cli/tests/unit/http_test.ts
@@ -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());
+}
diff --git a/test_util/std b/test_util/std
-Subproject e59b24543e670752701cd6b7d35ebb857d10021
+Subproject efa94f2ccc2df51f9437e14bc5e3455b013b99b