From 5c813e6eb353b09fad9d1be9c06071773bd8bd06 Mon Sep 17 00:00:00 2001 From: bcoll Date: Fri, 1 Mar 2024 12:23:09 +0000 Subject: [PATCH] fix: ensure IPv6 addresses can be used as `host`s --- .changeset/tender-nails-tickle.md | 7 +++++++ packages/miniflare/src/index.ts | 2 +- packages/miniflare/test/index.spec.ts | 20 ++++++++++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 .changeset/tender-nails-tickle.md diff --git a/.changeset/tender-nails-tickle.md b/.changeset/tender-nails-tickle.md new file mode 100644 index 000000000000..42ee87bd3528 --- /dev/null +++ b/.changeset/tender-nails-tickle.md @@ -0,0 +1,7 @@ +--- +"miniflare": patch +--- + +fix: ensure IPv6 addresses can be used as `host`s + +Previously, if Miniflare was configured to start on an IPv6 `host`, it could crash. This change ensures IPv6 addresses are handled correctly. This also fixes `wrangler dev` when using IPv6 addresses such as `::1` with the `--ip` flag. diff --git a/packages/miniflare/src/index.ts b/packages/miniflare/src/index.ts index 8d126934e34a..6f863ec6f9e3 100644 --- a/packages/miniflare/src/index.ts +++ b/packages/miniflare/src/index.ts @@ -1000,7 +1000,7 @@ export class Miniflare { requestedPort = this.#socketPorts?.get(id); } // Otherwise, default to a new random port - return `${host}:${requestedPort ?? 0}`; + return `${getURLSafeHost(host)}:${requestedPort ?? 0}`; } async #assembleConfig(loopbackPort: number): Promise { diff --git a/packages/miniflare/test/index.spec.ts b/packages/miniflare/test/index.spec.ts index 61c58892944f..352efca8e182 100644 --- a/packages/miniflare/test/index.spec.ts +++ b/packages/miniflare/test/index.spec.ts @@ -218,6 +218,26 @@ const localInterface = (interfaces["en0"] ?? interfaces["eth0"])?.find( t.is(await res.text(), "body"); } ); +test("Miniflare: can use IPv6 loopback as host", async (t) => { + const mf = new Miniflare({ + host: "::1", + modules: true, + script: `export default { fetch(request, env) { return env.SERVICE.fetch(request); } }`, + serviceBindings: { + SERVICE() { + return new Response("body"); + }, + }, + }); + t.teardown(() => mf.dispose()); + + let res = await mf.dispatchFetch("https://example.com"); + t.is(await res.text(), "body"); + + const worker = await mf.getWorker(); + res = await worker.fetch("https://example.com"); + t.is(await res.text(), "body"); +}); test("Miniflare: routes to multiple workers with fallback", async (t) => { const opts: MiniflareOptions = {