Description
Hi, I am getting an exception when connecting to IPv6 localhost address ::1
I have found this was reported and fixed in #1130 / #1147 (commit 70a247c) however it seems to have been reverted and the current V4.3.7 is once more using the depreciated url.parse
as you can see here: https://github.com/mqttjs/MQTT.js/blob/main/lib/connect/index.js#L64
Here is a minimal repro...
const userEnteredURL = 'ws://[::1]:8883'
const client = mqtt.connect(userEnteredURL, this.brokerConfig)
Here is why I think the underlying issue exists: mqtt.js
manually rebuilds the broker URL using hostname + port in
https://github.com/mqttjs/MQTT.js/blob/main/lib/connect/ws.js#L20
let url = opts.protocol + '://' + opts.hostname + ':' + opts.port + opts.path
... but, url.parse().hostname
drops the squarebrackets off [::1]
which causes the above code to generate the url http://::1:8883
. Further downstream, the ws
package uses new URL(...)
with this re-assembled URL string & the ERR_INVALID_URL
error occurs.
For anyone else reading, here is a minimal (hacky) workaround...
const userEnteredURL = 'ws://[::1]:8883'
const tempNewURL= new URL(userEnteredURL)
const brokerURL = url.parse(userEnteredURL)
brokerURL.hostname = tempNewURL.hostname // force the hostname back to [::1]
const client = mqtt.connect(brokerURL, this.brokerConfig)
Additional info...
- Calling
mqtt.connect(new URL('http://[::1]:8883'))
fails becauseconnect
only accepts astring
orurl.parse
object - Calling
mqtt.connect(url.parse('http://[::1]:8883')
fails because unlikenew URL
,url.parse
drops the square brackets offhostname
andmqtt.js uses
hostnameto reassemble the
url` - websocket code uses
new URL
so whenmqtt.js
passes the reassembled IPhttp://::1:8883
it failes with error ERR_INVALID_URL
url.parse
vs new URL
url.parse('http://[::1]:8883')
Url {
protocol: 'ws:',
slashes: true,
auth: null,
host: '[::1]:8883',
port: '8883',
hostname: '::1', //<< square brackets are dropped
hash: null,
search: null,
query: null,
pathname: '/',
path: '/',
href: 'ws://[::1]:8883/'
}
new URL('http://[::1]:8883')
URL {
href: 'ws://[::1]:8883/',
origin: 'ws://[::1]:8883',
protocol: 'ws:',
username: '',
password: '',
host: '[::1]:8883',
hostname: '[::1]', //<< square brackets are kept
port: '8883',
pathname: '/',
search: '',
searchParams: URLSearchParams {},
hash: ''
}
Activity