Skip to content

When connecting ws://[::1]:8883, an error is thrown - Uncaught TypeError TypeError [ERR_INVALID_URL]: Invalid URL #1569

Open
@Steve-Mcl

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 because connect only accepts a string or url.parse object
  • Calling mqtt.connect(url.parse('http://[::1]:8883') fails because unlike new URL, url.parse drops the square brackets off hostname and mqtt.js uses hostnameto reassemble theurl`
  • websocket code uses new URL so when mqtt.js passes the reassembled IP http://::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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions