Skip to content

Commit 56c1eb7

Browse files
committed
fix(dev): ignore link-local addresses in network urls
1 parent 3bb7f12 commit 56c1eb7

2 files changed

Lines changed: 53 additions & 5 deletions

File tree

‎packages/nuxt-cli/src/dev/listen.ts‎

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,22 @@ export interface Listener {
5555

5656
constANY_HOSTS=newSet(['','0.0.0.0','::'])
5757

58+
/**
59+
* External IPv4 addresses other devices can reach. IPv4 link-local addresses
60+
* (169.254.0.0/16, from a macOS Thunderbolt Bridge or an unconfigured adapter)
61+
* are excluded because they are unreachable from the rest of the network.
62+
*/
63+
exportfunctiongetNetworkAddresses(): string[]{
64+
constaddresses: string[]=[]
65+
for(constinfoofObject.values(networkInterfaces()).flat()){
66+
if(!info||info.internal||info.family!=='IPv4'||info.address.startsWith('169.254.')){
67+
continue
68+
}
69+
addresses.push(info.address)
70+
}
71+
returnaddresses
72+
}
73+
5874
/**
5975
* OpenSSL 3 moved the ciphers used by older PKCS#12 exports (RC2-40, RC4, DES)
6076
* into the legacy provider, which Node does not load, so such keystores fail
@@ -137,11 +153,8 @@ export async function listen(handler: RequestListener, options: ListenOptions =
137153
}
138154
if(anyHost){
139155
urls.push({url: formatURL('localhost'),type: 'local'})
140-
for(constinfoofObject.values(networkInterfaces()).flat()){
141-
if(!info||info.internal||info.family!=='IPv4'){
142-
continue
143-
}
144-
urls.push({url: formatURL(info.address),type: 'network'})
156+
for(constaddressofgetNetworkAddresses()){
157+
urls.push({url: formatURL(address),type: 'network'})
145158
}
146159
}
147160
else{
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import{networkInterfaces}from'node:os'
2+
3+
import{describe,expect,it,vi}from'vitest'
4+
5+
import{getNetworkAddresses}from'../../src/dev/listen'
6+
7+
vi.mock('node:os',()=>({
8+
networkInterfaces: vi.fn(),
9+
release: ()=>'test',
10+
}))
11+
12+
constmocked=vi.mocked(networkInterfaces)
13+
14+
describe('getNetworkAddresses',()=>{
15+
it('should return external IPv4 addresses',()=>{
16+
mocked.mockReturnValue({
17+
lo0: [{address: '127.0.0.1',family: 'IPv4',internal: true}asany],
18+
en0: [
19+
{address: '192.168.1.20',family: 'IPv4',internal: false}asany,
20+
{address: 'fe80::1',family: 'IPv6',internal: false}asany,
21+
],
22+
})
23+
24+
expect(getNetworkAddresses()).toEqual(['192.168.1.20'])
25+
})
26+
27+
it('should ignore IPv4 link-local addresses',()=>{
28+
mocked.mockReturnValue({
29+
bridge0: [{address: '169.254.13.37',family: 'IPv4',internal: false}asany],
30+
en0: [{address: '192.168.1.20',family: 'IPv4',internal: false}asany],
31+
})
32+
33+
expect(getNetworkAddresses()).toEqual(['192.168.1.20'])
34+
})
35+
})

0 commit comments

Comments
 (0)