Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(http): file server prints local network address #4604

Merged
merged 7 commits into from
Apr 22, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion http/file_server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -806,21 +806,21 @@

const useTls = !!(keyFile && certFile);

function onListen({ port, hostname }: { port: number; hostname: string }) {
const networkAddress = getNetworkAddress();
const protocol = useTls ? "https" : "http";
let message = `Listening on:\n- Local: ${protocol}://${hostname}:${port}`;
if (networkAddress) {
if (networkAddress && !DENO_DEPLOYMENT_ID) {
message += `\n- Network: ${protocol}://${networkAddress}:${port}`;
}
console.log(message);
}

Check warning on line 817 in http/file_server.ts

View check run for this annotation

Codecov / codecov/patch

http/file_server.ts#L809-L817

Added lines #L809 - L817 were not covered by tests

if (useTls) {
Deno.serve({
port,
hostname: host,
onListen,

Check warning on line 823 in http/file_server.ts

View check run for this annotation

Codecov / codecov/patch

http/file_server.ts#L823

Added line #L823 was not covered by tests
cert: Deno.readTextFileSync(certFile),
key: Deno.readTextFileSync(keyFile),
}, handler);
Expand All @@ -828,7 +828,7 @@
Deno.serve({
port,
hostname: host,
onListen,

Check warning on line 831 in http/file_server.ts

View check run for this annotation

Codecov / codecov/patch

http/file_server.ts#L831

Added line #L831 was not covered by tests
}, handler);
}
}
Expand All @@ -838,13 +838,13 @@
* inspired by the util of the same name in `npm:serve`
* https://github.com/vercel/serve/blob/1ea55b1b5004f468159b54775e4fb3090fedbb2b/source/utilities/http.ts#L33
*/
function getNetworkAddress() {
for (const { family, address } of Deno.networkInterfaces()) {
if (family === "IPv4" && !address.startsWith("127.")) {
return address;
}
}
}

Check warning on line 847 in http/file_server.ts

View check run for this annotation

Codecov / codecov/patch

http/file_server.ts#L841-L847

Added lines #L841 - L847 were not covered by tests

function printUsage() {
console.log(`Deno File Server ${VERSION}
Expand Down
87 changes: 66 additions & 21 deletions http/file_server_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -975,42 +975,87 @@ Deno.test(

Deno.test("file_server prints local and network urls", async () => {
const port = await getAvailablePort();
const process = spawnDeno([
"--allow-net",
"--allow-read",
"--allow-sys=networkInterfaces",
"http/file_server.ts",
"--port",
`${port}`,
]);
const output = await readUntilMatch(process.stdout, "Network:");
const networkAdress = Deno.networkInterfaces().find((i) =>
i.family === "IPv4" && !i.address.startsWith("127")
)?.address;
Comment on lines +987 to +989
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like this should be used as the implementation for getNetworkAddress().

assertEquals(
output,
`Listening on:\n- Local: http://localhost:${port}\n- Network: http://${networkAdress}:${port}\n`,
);
process.stdout.cancel();
process.stderr.cancel();
process.kill();
await process.status;
});

Deno.test("file_server prints only local address on Deploy", async () => {
const port = await getAvailablePort();
const process = spawnDeno([
"--allow-net",
"--allow-read",
"--allow-sys=networkInterfaces",
"--allow-env=DENO_DEPLOYMENT_ID",
"http/file_server.ts",
"--port",
`${port}`,
], {
env: {
DENO_DEPLOYMENT_ID: "abcdef",
},
});
const output = await readUntilMatch(process.stdout, "Local:");
console.log(output);
assertEquals(
output,
`Listening on:\n- Local: http://localhost:${port}\n`,
);
process.stdout.cancel();
process.stderr.cancel();
process.kill();
await process.status;
});

/** Spawn deno child process with the options convenient for testing */
function spawnDeno(args: string[], opts?: Deno.CommandOptions) {
const cmd = new Deno.Command(Deno.execPath(), {
args: [
"run",
"--no-lock",
"--quiet",
"--allow-net",
"--allow-read",
"--allow-sys=networkInterfaces",
"--config",
iuioiua marked this conversation as resolved.
Show resolved Hide resolved
"deno.json",
"http/file_server.ts",
"--port",
`${port}`,
...args,
],
stdout: "piped",
stderr: "piped",
...opts,
});
const process = cmd.spawn();
const reader = process.stdout.getReader();
return cmd.spawn();
}

async function readUntilMatch(
source: ReadableStream,
match: string,
) {
const reader = source.getReader();
let buf = new Uint8Array(0);
const dec = new TextDecoder();
while (!dec.decode(buf).includes("Network:")) {
while (!dec.decode(buf).includes(match)) {
const { value } = await reader.read();
if (!value) {
break;
}
buf = concat([buf, value]);
}
const networkAdress = Deno.networkInterfaces().find((i) =>
i.family === "IPv4" && !i.address.startsWith("127")
)?.address;
assertEquals(
dec.decode(buf),
`Listening on:\n- Local: http://localhost:${port}\n- Network: http://${networkAdress}:${port}\n`,
);

reader.cancel();
process.kill();
await process.status;
});
reader.releaseLock();
return dec.decode(buf);
}