Skip to content

Commit

Permalink
Change default ip for dev server from 0.0.0.0 to * (#4307)
Browse files Browse the repository at this point in the history
* Change default ip for dev server from `0.0.0.0` to `*`
Also support ipv6 for dev server

* Only output ipv4 addresses + localhost and :: when starting dev server
  • Loading branch information
jspspike committed Nov 9, 2023
1 parent 9bc52cf commit 7fbe193
Show file tree
Hide file tree
Showing 12 changed files with 100 additions and 106 deletions.
5 changes: 5 additions & 0 deletions .changeset/shiny-rats-hide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"wrangler": patch
---

Change local dev server default ip to `*` instead of `0.0.0.0`. This will cause the dev server to listen on both ipv4 and ipv6 interfaces
5 changes: 5 additions & 0 deletions .changeset/small-gifts-smash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"miniflare": patch
---

Only output ipv4 addresses when starting
4 changes: 2 additions & 2 deletions packages/miniflare/src/http/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ export function getAccessibleHosts(ipv4Only = false): string[] {
// @ts-expect-error the `family` property is numeric as of Node.js 18.0.0
if (family === "IPv4" || family === 4) {
hosts.push(address);
} else if (!ipv4Only && (family === "IPv6" || family === 6)) {
hosts.push(`[${address}]`);
} else if (!ipv4Only) {
hosts.push(address);
}
});
});
Expand Down
15 changes: 8 additions & 7 deletions packages/miniflare/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1181,13 +1181,14 @@ export class Miniflare {
);

if (initial) {
let hosts: string[];
if (host === "::" || host === "*") {
hosts = getAccessibleHosts(false);
} else if (host === "0.0.0.0") {
hosts = getAccessibleHosts(true);
} else {
hosts = [];
const hosts: string[] = [];
if (host === "::" || host === "*" || host === "0.0.0.0") {
hosts.push(...getAccessibleHosts(true));

if (host !== "0.0.0.0") {
hosts.push("localhost");
hosts.push("[::1]");
}
}

for (const h of hosts) {
Expand Down
2 changes: 1 addition & 1 deletion packages/wrangler/src/__tests__/configuration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ describe("normalizeAndValidateConfig()", () => {
constellation: [],
hyperdrive: [],
dev: {
ip: "0.0.0.0",
ip: "*",
local_protocol: "http",
port: undefined, // the default of 8787 is set at runtime
upstream_protocol: "https",
Expand Down
6 changes: 3 additions & 3 deletions packages/wrangler/src/__tests__/dev.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -833,13 +833,13 @@ describe("wrangler dev", () => {
});

describe("ip", () => {
it("should default ip to 0.0.0.0", async () => {
it("should default ip to *", async () => {
writeWranglerToml({
main: "index.js",
});
fs.writeFileSync("index.js", `export default {};`);
await runWrangler("dev");
expect((Dev as jest.Mock).mock.calls[0][0].initialIp).toEqual("0.0.0.0");
expect((Dev as jest.Mock).mock.calls[0][0].initialIp).toEqual("*");
expect(std.out).toMatchInlineSnapshot(`""`);
expect(std.warn).toMatchInlineSnapshot(`""`);
expect(std.err).toMatchInlineSnapshot(`""`);
Expand Down Expand Up @@ -1055,7 +1055,7 @@ describe("wrangler dev", () => {
});
fs.writeFileSync("index.js", `export default {};`);
await runWrangler("dev");
expect((Dev as jest.Mock).mock.calls[0][0].initialIp).toEqual("0.0.0.0");
expect((Dev as jest.Mock).mock.calls[0][0].initialIp).toEqual("*");
expect(std.out).toMatchInlineSnapshot(`
"Your worker has access to the following bindings:
- Durable Objects:
Expand Down
2 changes: 1 addition & 1 deletion packages/wrangler/src/config/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ export interface DevConfig {
/**
* IP address for the local dev server to listen on,
*
* @default `0.0.0.0`
* @default `*`
*/
ip: string;

Expand Down
2 changes: 1 addition & 1 deletion packages/wrangler/src/config/validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ function normalizeAndValidateDev(
rawDev: RawDevConfig
): DevConfig {
const {
ip = "0.0.0.0",
ip = "*",
port,
inspector_port,
local_protocol = "http",
Expand Down
37 changes: 21 additions & 16 deletions packages/wrangler/src/dev/proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import { createServer as createHttpServer } from "node:http";
import { connect } from "node:http2";
import { createServer as createHttpsServer } from "node:https";
import https from "node:https";
import { networkInterfaces } from "node:os";
import { createHttpTerminator } from "http-terminator";
import { getAccessibleHosts } from "miniflare";
import { useEffect, useRef, useState } from "react";
import serveStatic from "serve-static";
import { getHttpsOptions } from "../https-options";
Expand Down Expand Up @@ -166,7 +166,15 @@ export async function startPreviewServer({
const usedPort =
address && typeof address === "object" ? address.port : port;
logger.log(`⬣ Listening at ${localProtocol}://${ip}:${usedPort}`);
const accessibleHosts = ip !== "0.0.0.0" ? [ip] : getAccessibleHosts();
const accessibleHosts = [];
if (ip === "::" || ip === "*" || ip === "0.0.0.0") {
accessibleHosts.push(...getAccessibleHosts(true));

if (ip !== "0.0.0.0") {
accessibleHosts.push("localhost");
accessibleHosts.push("[::1]");
}
}
for (const accessibleHost of accessibleHosts) {
logger.log(`- ${localProtocol}://${accessibleHost}:${usedPort}`);
}
Expand Down Expand Up @@ -299,13 +307,21 @@ export function usePreviewServer({
const usedPort =
address && typeof address === "object" ? address.port : port;
logger.log(`⬣ Listening at ${localProtocol}://${ip}:${usedPort}`);
const accessibleHosts =
ip !== "0.0.0.0" ? [ip] : getAccessibleHosts();
const accessibleHosts = [];
if (ip === "::" || ip === "*" || ip === "0.0.0.0") {
accessibleHosts.push(...getAccessibleHosts(true));

if (ip !== "0.0.0.0") {
accessibleHosts.push("localhost");
accessibleHosts.push("[::1]");
}
}
for (const accessibleHost of accessibleHosts) {
logger.log(`- ${localProtocol}://${accessibleHost}:${usedPort}`);
}
});
proxy.server.listen(port, ip);

proxy.server.listen(port, ip === "*" ? "::" : ip);
})
.catch((err) => {
if ((err as { code: string }).code !== "ABORT_ERR") {
Expand Down Expand Up @@ -681,14 +697,3 @@ export async function waitForPortToBeAvailable(
}
});
}

function getAccessibleHosts(): string[] {
const hosts: string[] = [];
Object.values(networkInterfaces()).forEach((net) => {
net?.forEach(({ family, address }) => {
// @ts-expect-error the `family` property is numeric as of Node.js 18.0.0
if (family === "IPv4" || family === 4) hosts.push(address);
});
});
return hosts;
}
1 change: 1 addition & 0 deletions packages/wrangler/src/dev/remote.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ export function useWorker(
)
);
}

start().catch((err) => {
// instead of logging the raw API error to the user,
// give them friendly instructions
Expand Down
17 changes: 2 additions & 15 deletions packages/wrangler/src/https-options.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as fs from "node:fs";
import os from "node:os";
import * as path from "node:path";
import { promisify } from "node:util";
import { getAccessibleHosts } from "miniflare";
import { getGlobalWranglerConfigPath } from "./global-wrangler-config-path";
import { logger } from "./logger";
import type { Attributes, Options } from "selfsigned";
Expand Down Expand Up @@ -103,7 +103,7 @@ async function generateCertificate() {
name: "subjectAltName",
altNames: [
{ type: 2, value: "localhost" },
...getAccessibleHosts().map((ip) => ({ type: 7, ip })),
...getAccessibleHosts(false).map((ip) => ({ type: 7, ip })),
],
},
],
Expand All @@ -112,16 +112,3 @@ async function generateCertificate() {
const { private: key, cert } = await generate(certAttrs, certOptions);
return { key, cert };
}

/**
* Ask the OS for the addresses of locally accessible hosts.
*/
function getAccessibleHosts(ipv4 = false): string[] {
const hosts: string[] = [];
Object.values(os.networkInterfaces()).forEach((net) =>
net?.forEach(({ family, address }) => {
if (!ipv4 || family === "IPv4") hosts.push(address);
})
);
return hosts;
}
110 changes: 50 additions & 60 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 7fbe193

Please sign in to comment.