11"use strict" ;
22
3+ const http = require ( "http" ) ;
34const webpack = require ( "webpack" ) ;
45const Server = require ( "../../lib/Server" ) ;
56const config = require ( "../fixtures/client-config/webpack.config" ) ;
67const runBrowser = require ( "../helpers/run-browser" ) ;
78const port = require ( "../ports-map" ) . host ;
89
9- const ipv4 = Server . findIp ( "v4" ) ;
10- const ipv6 = Server . findIp ( "v6" ) ;
11- // macos requires root for using ip v6
12- const isMacOS = process . platform === "darwin" ;
10+ const ipv4 = Server . findIp ( "v4" , false ) ;
11+ const ipv6 = Server . findIp ( "v6" , false ) ;
1312
14- function getAddress ( host , hostname ) {
13+ async function getAddress ( host , hostname ) {
1514 let address ;
1615
1716 if (
1817 typeof host === "undefined" ||
19- ( typeof host === "string" && host === "<not-specified>" )
18+ ( typeof host === "string" && ( host === "<not-specified>" || host === "::" ) )
2019 ) {
2120 address = "::" ;
22- } else if ( typeof host === "string" && host === "0.0.0.0" ) {
21+ } else if ( host === "0.0.0.0" ) {
2322 address = "0.0.0.0" ;
24- } else if ( typeof host === "string" && host === "localhost" ) {
25- address = parseFloat ( process . versions . node ) >= 18 ? "::1" : "127.0.0.1" ;
23+ } else if ( host === "::1" ) {
24+ address = "::1" ;
25+ } else if ( host === "localhost" ) {
26+ // It can be `127.0.0.1` or `::1` on different OS
27+ const server = http . createServer ( ( req , res ) => {
28+ res . statusCode = 200 ;
29+ res . setHeader ( "Content-Type" , "text/plain" ) ;
30+ res . end ( "Hello World\n" ) ;
31+ } ) ;
32+
33+ await new Promise ( ( resolve ) => {
34+ server . listen ( { host : "localhost" , port : 23100 } , resolve ) ;
35+ } ) ;
36+
37+ address = server . address ( ) . address ;
38+
39+ await new Promise ( ( resolve , reject ) => {
40+ server . close ( ( err ) => {
41+ if ( err ) {
42+ reject ( err ) ;
43+ return ;
44+ }
45+
46+ resolve ( ) ;
47+ } ) ;
48+ } ) ;
49+ } else if ( host === "local-ipv6" ) {
50+ address = "::" ;
2651 } else {
2752 address = hostname ;
2853 }
@@ -37,28 +62,17 @@ describe("host", () => {
3762 undefined ,
3863 "0.0.0.0" ,
3964 "::" ,
40- "localhost" ,
4165 "::1" ,
66+ "localhost" ,
4267 "127.0.0.1" ,
4368 "local-ip" ,
4469 "local-ipv4" ,
4570 "local-ipv6" ,
4671 ] ;
4772
48- for ( let host of hosts ) {
73+ for ( const host of hosts ) {
4974 it ( `should work using "${ host } " host and port as number` , async ( ) => {
5075 const compiler = webpack ( config ) ;
51-
52- if ( ! ipv6 || isMacOS ) {
53- if ( host === "::" ) {
54- host = "127.0.0.1" ;
55- } else if ( host === "::1" ) {
56- host = "127.0.0.1" ;
57- } else if ( host === "local-ipv6" ) {
58- host = "127.0.0.1" ;
59- }
60- }
61-
6276 const devServerOptions = { port } ;
6377
6478 if ( host !== "<not-specified>" ) {
@@ -69,24 +83,28 @@ describe("host", () => {
6983
7084 let hostname = host ;
7185
72- if ( hostname === "0.0.0.0" ) {
73- hostname = "127.0.0.1" ;
74- } else if (
75- hostname === "<not-specified>" ||
76- typeof hostname === "undefined" ||
77- hostname === "::" ||
78- hostname === "::1"
79- ) {
86+ if ( hostname === "<not-specified>" || typeof hostname === "undefined" ) {
87+ // If host is omitted, the server will accept connections on the unspecified IPv6 address (::) when IPv6 is available, or the unspecified IPv4 address (0.0.0.0) otherwise.
88+ hostname = ipv6 ? `[${ ipv6 } ]` : ipv4 ;
89+ } else if ( hostname === "0.0.0.0" ) {
90+ hostname = ipv4 ;
91+ } else if ( hostname === "::" ) {
92+ // In most operating systems, listening to the unspecified IPv6 address (::) may cause the net.Server to also listen on the unspecified IPv4 address (0.0.0.0).
93+ hostname = ipv6 ? `[${ ipv6 } ]` : ipv4 ;
94+ } else if ( hostname === "::1" ) {
8095 hostname = "[::1]" ;
8196 } else if ( hostname === "local-ip" || hostname === "local-ipv4" ) {
8297 hostname = ipv4 ;
8398 } else if ( hostname === "local-ipv6" ) {
84- hostname = `[${ ipv6 } ]` ;
99+ // For test env where network ipv6 doesn't work
100+ hostname = ipv6 ? `[${ ipv6 } ]` : "[::1]" ;
85101 }
86102
87103 await server . start ( ) ;
88104
89- expect ( server . server . address ( ) ) . toMatchObject ( getAddress ( host , hostname ) ) ;
105+ expect ( server . server . address ( ) ) . toMatchObject (
106+ await getAddress ( host , hostname ) ,
107+ ) ;
90108
91109 const { page, browser } = await runBrowser ( ) ;
92110
@@ -121,17 +139,6 @@ describe("host", () => {
121139
122140 it ( `should work using "${ host } " host and port as string` , async ( ) => {
123141 const compiler = webpack ( config ) ;
124-
125- if ( ! ipv6 || isMacOS ) {
126- if ( host === "::" ) {
127- host = "127.0.0.1" ;
128- } else if ( host === "::1" ) {
129- host = "127.0.0.1" ;
130- } else if ( host === "local-ipv6" ) {
131- host = "127.0.0.1" ;
132- }
133- }
134-
135142 const devServerOptions = { port : `${ port } ` } ;
136143
137144 if ( host !== "<not-specified>" ) {
@@ -142,24 +149,28 @@ describe("host", () => {
142149
143150 let hostname = host ;
144151
145- if ( hostname === "0.0.0.0" ) {
146- hostname = "127.0.0.1" ;
147- } else if (
148- hostname === "<not-specified>" ||
149- typeof hostname === "undefined" ||
150- hostname === "::" ||
151- hostname === "::1"
152- ) {
152+ if ( hostname === "<not-specified>" || typeof hostname === "undefined" ) {
153+ // If host is omitted, the server will accept connections on the unspecified IPv6 address (::) when IPv6 is available, or the unspecified IPv4 address (0.0.0.0) otherwise.
154+ hostname = ipv6 ? `[${ ipv6 } ]` : ipv4 ;
155+ } else if ( hostname === "0.0.0.0" ) {
156+ hostname = ipv4 ;
157+ } else if ( hostname === "::" ) {
158+ // In most operating systems, listening to the unspecified IPv6 address (::) may cause the net.Server to also listen on the unspecified IPv4 address (0.0.0.0).
159+ hostname = ipv6 ? `[${ ipv6 } ]` : ipv4 ;
160+ } else if ( hostname === "::1" ) {
153161 hostname = "[::1]" ;
154162 } else if ( hostname === "local-ip" || hostname === "local-ipv4" ) {
155163 hostname = ipv4 ;
156164 } else if ( hostname === "local-ipv6" ) {
157- hostname = `[${ ipv6 } ]` ;
165+ // For test env where network ipv6 doesn't work
166+ hostname = ipv6 ? `[${ ipv6 } ]` : "[::1]" ;
158167 }
159168
160169 await server . start ( ) ;
161170
162- expect ( server . server . address ( ) ) . toMatchObject ( getAddress ( host , hostname ) ) ;
171+ expect ( server . server . address ( ) ) . toMatchObject (
172+ await getAddress ( host , hostname ) ,
173+ ) ;
163174
164175 const { page, browser } = await runBrowser ( ) ;
165176
@@ -197,16 +208,6 @@ describe("host", () => {
197208
198209 process . env . WEBPACK_DEV_SERVER_BASE_PORT = port ;
199210
200- if ( ! ipv6 || isMacOS ) {
201- if ( host === "::" ) {
202- host = "127.0.0.1" ;
203- } else if ( host === "::1" ) {
204- host = "127.0.0.1" ;
205- } else if ( host === "local-ipv6" ) {
206- host = "127.0.0.1" ;
207- }
208- }
209-
210211 const devServerOptions = { port : "auto" } ;
211212
212213 if ( host !== "<not-specified>" ) {
@@ -217,24 +218,28 @@ describe("host", () => {
217218
218219 let hostname = host ;
219220
220- if ( hostname === "0.0.0.0" ) {
221- hostname = "127.0.0.1" ;
222- } else if (
223- hostname === "<not-specified>" ||
224- typeof hostname === "undefined" ||
225- hostname === "::" ||
226- hostname === "::1"
227- ) {
221+ if ( hostname === "<not-specified>" || typeof hostname === "undefined" ) {
222+ // If host is omitted, the server will accept connections on the unspecified IPv6 address (::) when IPv6 is available, or the unspecified IPv4 address (0.0.0.0) otherwise.
223+ hostname = ipv6 ? `[${ ipv6 } ]` : ipv4 ;
224+ } else if ( hostname === "0.0.0.0" ) {
225+ hostname = ipv4 ;
226+ } else if ( hostname === "::" ) {
227+ // In most operating systems, listening to the unspecified IPv6 address (::) may cause the net.Server to also listen on the unspecified IPv4 address (0.0.0.0).
228+ hostname = ipv6 ? `[${ ipv6 } ]` : ipv4 ;
229+ } else if ( hostname === "::1" ) {
228230 hostname = "[::1]" ;
229231 } else if ( hostname === "local-ip" || hostname === "local-ipv4" ) {
230232 hostname = ipv4 ;
231233 } else if ( hostname === "local-ipv6" ) {
232- hostname = `[${ ipv6 } ]` ;
234+ // For test env where network ipv6 doesn't work
235+ hostname = ipv6 ? `[${ ipv6 } ]` : "[::1]" ;
233236 }
234237
235238 await server . start ( ) ;
236239
237- expect ( server . server . address ( ) ) . toMatchObject ( getAddress ( host , hostname ) ) ;
240+ expect ( server . server . address ( ) ) . toMatchObject (
241+ await getAddress ( host , hostname ) ,
242+ ) ;
238243
239244 const address = server . server . address ( ) ;
240245 const { page, browser } = await runBrowser ( ) ;
0 commit comments