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 c2a711902cd9..ea06da2aa531 100644 --- a/packages/miniflare/src/index.ts +++ b/packages/miniflare/src/index.ts @@ -997,7 +997,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 dbc4fb0b4c9a..c1788b1a3001 100644 --- a/packages/miniflare/test/index.spec.ts +++ b/packages/miniflare/test/index.spec.ts @@ -213,6 +213,21 @@ 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() { 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 = {