diff --git a/lib/internal/socketaddress.js b/lib/internal/socketaddress.js index 724ffd90cf77f1..116d5ba20dee36 100644 --- a/lib/internal/socketaddress.js +++ b/lib/internal/socketaddress.js @@ -1,6 +1,7 @@ 'use strict'; const { + NumberParseInt, ObjectSetPrototypeOf, Symbol, } = primordials; @@ -153,18 +154,22 @@ class SocketAddress { // other pieces here that do... the destucturing, the SocketAddress // constructor, etc. So we wrap this in a try/catch to be safe. try { - const { - hostname: address, + // url.port strips default HTTP ports (e.g. 80), so parse the port from + // the raw input string instead. + const { hostname: address } = URLParse(`http://${input}`); + + const isIPv6 = address.startsWith('[') && address.endsWith(']'); + + // For IPv6, indexOf(']:') + 1 points at ':' (or 0 if absent, treated as no port). + // For IPv4, lastIndexOf(':') points at ':' (or -1 if absent). + const sepIdx = isIPv6 ? input.indexOf(']:') + 1 : input.lastIndexOf(':'); + const port = sepIdx > 0 ? NumberParseInt(input.slice(sepIdx + 1), 10) || 0 : 0; + + return new SocketAddress({ + address: isIPv6 ? address.slice(1, -1) : address, port, - } = URLParse(`http://${input}`); - if (address.startsWith('[') && address.endsWith(']')) { - return new SocketAddress({ - address: address.slice(1, -1), - port: port | 0, - family: 'ipv6', - }); - } - return new SocketAddress({ address, port: port | 0 }); + family: isIPv6 ? 'ipv6' : 'ipv4', + }); } catch { // Ignore errors here. Return undefined if the input cannot // be successfully parsed or is not a proper socket address. diff --git a/test/parallel/test-socketaddress.js b/test/parallel/test-socketaddress.js index cf29795a48fcfa..e1f98bea01a8b2 100644 --- a/test/parallel/test-socketaddress.js +++ b/test/parallel/test-socketaddress.js @@ -148,6 +148,10 @@ describe('net.SocketAddress...', () => { { input: '0x.0x.0', address: '0.0.0.0', port: 0, family: 'ipv4' }, { input: '[1:0::]', address: '1::', port: 0, family: 'ipv6' }, { input: '[1::8]:123', address: '1::8', port: 123, family: 'ipv6' }, + { input: '127.0.0.1:80', address: '127.0.0.1', port: 80, family: 'ipv4' }, + { input: '127.0.0.1:443', address: '127.0.0.1', port: 443, family: 'ipv4' }, + { input: '[::1]:80', address: '::1', port: 80, family: 'ipv6' }, + { input: '[::1]:443', address: '::1', port: 443, family: 'ipv6' }, ]; good.forEach((i) => {