Skip to content

Commit

Permalink
Fix IPv6 hostname formatting in CLI (#43491)
Browse files Browse the repository at this point in the history
Co-authored-by: Jan Kaifer <jan@kaifer.cz>
Fixes #21979
  • Loading branch information
akshitsinha authored Jan 10, 2023
1 parent c7162c4 commit 9dedc94
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 3 deletions.
7 changes: 6 additions & 1 deletion packages/next/src/cli/next-dev.ts
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import path from 'path'
import type { NextConfig } from '../../types'
import type { NextConfigComplete } from '../server/config-shared'
import { traceGlobals } from '../trace/shared'
import { isIPv6 } from 'net'
import cluster from 'cluster'
import { Telemetry } from '../telemetry/storage'
import loadConfig from '../server/config'
Expand Down Expand Up @@ -403,7 +404,11 @@ If you cannot make the changes above, but still want to try out\nNext.js v13 wit
startServer(devServerOptions)
.then(async (app) => {
const appUrl = `http://${app.hostname}:${app.port}`
startedDevelopmentServer(appUrl, `${host || '0.0.0.0'}:${app.port}`)
const hostname = host || '0.0.0.0'
startedDevelopmentServer(
appUrl,
`${isIPv6(hostname) ? `[${hostname}]` : hostname}:${app.port}`
)
// Start preflight after server is listening and ignore errors:
preflight().catch(() => {})
// Finalize server bootup:
Expand Down
4 changes: 3 additions & 1 deletion packages/next/src/cli/next-start.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import * as Log from '../build/output/log'
import isError from '../lib/is-error'
import { getProjectDir } from '../lib/get-project-dir'
import { CliCommand } from '../lib/commands'
import { isIPv6 } from 'net'

const nextStart: CliCommand = (argv) => {
const validArgs: arg.Spec = {
Expand Down Expand Up @@ -80,7 +81,8 @@ const nextStart: CliCommand = (argv) => {
})
.then(async (app) => {
const appUrl = `http://${app.hostname}:${app.port}`
Log.ready(`started server on ${host}:${app.port}, url: ${appUrl}`)
const hostname = isIPv6(host) ? `[${host}]` : host
Log.ready(`started server on ${hostname}:${app.port}, url: ${appUrl}`)
await app.prepare()
})
.catch((err) => {
Expand Down
7 changes: 6 additions & 1 deletion packages/next/src/server/lib/start-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ import type { NextServerOptions, NextServer, RequestHandler } from '../next'
import { warn } from '../../build/output/log'
import http from 'http'
import next from '../next'
import { isIPv6 } from 'net'
import cluster from 'cluster'
import v8 from 'v8'

interface StartServerOptions extends NextServerOptions {
allowRetry?: boolean
keepAliveTimeout?: number
Expand Down Expand Up @@ -60,10 +62,13 @@ export function startServer(opts: StartServerOptions) {

server.on('listening', () => {
const addr = server.address()
const hostname =
let hostname =
!opts.hostname || opts.hostname === '0.0.0.0'
? 'localhost'
: opts.hostname
if (isIPv6(hostname)) {
hostname = hostname === '::' ? '[::1]' : `[${hostname}]`
}

const app = next({
...opts,
Expand Down
22 changes: 22 additions & 0 deletions test/integration/cli/test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,16 @@ describe('CLI Usage', () => {
expect(output).toMatch(new RegExp(`http://localhost:${port}`))
})

test('should format IPv6 addresses correctly', async () => {
const port = await findPort()
const output = await runNextCommandDev(
[dir, '--hostname', '::', '--port', port],
true
)
expect(output).toMatch(new RegExp(`on \\[::\\]:${port}`))
expect(output).toMatch(new RegExp(`http://\\[::1\\]:${port}`))
})

test('should warn when unknown argument provided', async () => {
const { stderr } = await runNextCommand(['dev', '--random'], {
stderr: true,
Expand Down Expand Up @@ -346,6 +356,18 @@ describe('CLI Usage', () => {
expect(help.stdout).toMatch(/Starts the application in production mode/)
})

test('should format IPv6 addresses correctly', async () => {
const port = await findPort()
const output = await runNextCommand(
['start', '--hostname', '::', '--port', port],
{
stdout: true,
}
)
expect(output.stdout).toMatch(new RegExp(`on \\[::\\]:${port}`))
expect(output.stdout).toMatch(new RegExp(`http://\\[::1\\]:${port}`))
})

test('should warn when unknown argument provided', async () => {
const { stderr } = await runNextCommand(['start', '--random'], {
stderr: true,
Expand Down

0 comments on commit 9dedc94

Please sign in to comment.