From cce2634e70d81b2cb9027366f4f63d5943ac2215 Mon Sep 17 00:00:00 2001 From: Cotton Hou Date: Wed, 23 Nov 2022 19:19:01 +0800 Subject: [PATCH] support port ranges --- bin.ts | 16 ++++++++++------ mod.test.ts | 4 ++-- mod.ts | 33 ++++++++++++++++++++++++--------- 3 files changed, 36 insertions(+), 17 deletions(-) diff --git a/bin.ts b/bin.ts index e3dc218..c700d1b 100644 --- a/bin.ts +++ b/bin.ts @@ -1,17 +1,18 @@ -import { main, safe_int } from './mod.ts' +import { main, safe_int, port_verify, parse_range } from './mod.ts'; -import { parse } from 'https://deno.land/std@0.160.0/flags/mod.ts'; +import { parse } from 'https://deno.land/std@0.165.0/flags/mod.ts'; +import { mapNotNullish } from 'https://deno.land/std@0.165.0/collections/map_not_nullish.ts'; const { port: port_, timeout: timeout_, ...rest } = parse(Deno.args, { - string: [ 'auth', 'crt', 'key' ], + string: [ 'auth', 'crt', 'key', 'port.http', 'port.https' ], default: { port: { - http: 0, - https: 0, + http: '', + https: '', }, timeout: 500, // milliseconds crt: 'server.crt', @@ -19,7 +20,10 @@ const { port: port_, timeout: timeout_, ...rest } = parse(Deno.args, { } }); -const port = { http: 0, https: 0, ...port_ ?? {} }; +const port = { + http: new Set(mapNotNullish(parse_range(port_.http), port_verify)), + https: new Set(mapNotNullish(parse_range(port_.https), port_verify)), +}; const timeout = safe_int ({ min: 0 }) (Number(timeout_)); diff --git a/mod.test.ts b/mod.test.ts index 39f74d5..050c2b7 100644 --- a/mod.test.ts +++ b/mod.test.ts @@ -497,7 +497,7 @@ Deno.test('main', { permissions: { net: true, read: [ '.' ] } }, async () => { const signal = AbortSignal.abort(); - await main({ port: { http: 65535 } }, { signal }); + await main({ port: { http: [ 65535 ] } }, { signal }); } @@ -579,7 +579,7 @@ Deno.test('main', { permissions: { net: true, read: [ '.' ] } }, async () => { ast.assertExists(port_echo); ast.assertExists(port_proxy); - main({ port: { http: port_proxy } }, { signal }); + main({ port: { http: [ port_proxy ] } }, { signal }); await delay(10); diff --git a/mod.ts b/mod.ts index 4572467..a443a6c 100644 --- a/mod.ts +++ b/mod.ts @@ -16,32 +16,47 @@ import { -export type Opts = Partial<{ +export type MainOpts = Partial<{ auth: string, port: Partial<{ - http: number, - https: number, + http: Iterable, + https: Iterable, }>, timeout: number, crt: string, key: string, }> +type OptsWithoutPort = Omit; + +export type Opts = OptsWithoutPort & Partial<{ + port: Partial<{ + http: number, + https: number, + }>, +}>; + export async function main ( - opts: Opts, + { port, ...opts }: MainOpts, { signal } = new AbortController() as { readonly signal: AbortSignal }, ) { const handle = await on_request(opts); - const services = await Promise.allSettled([ - serve_http(opts), - serve_https(opts), - ]); + const services = await Promise.allSettled( + + Array.from(port?.http ?? []) + .map(http => serve_http({ ...opts, port: { http } })) + + .concat(Array.from(port?.https ?? []) + .map(https => serve_https({ ...opts, port: { https } })) + ) + + ); if (services.every(settling.rejected)) { @@ -147,7 +162,7 @@ export function pre_on_request({ tunnel = tunnel_to, }) { - return async function ({ auth, timeout }: Opts) { + return async function ({ auth, timeout }: OptsWithoutPort) { const check = auth && await verify(toFileUrl(toAbsolute(auth)));