Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: replace deprecated url.parse with new URL #1927

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ coverage
test/typescript/.idea/*
test/typescript/*.js
test/typescript/*.map
test-store*/*
# VS Code stuff
**/typings/**
.vscode/
Expand Down
50 changes: 21 additions & 29 deletions src/lib/connect/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/* eslint-disable @typescript-eslint/no-var-requires */
import _debug from 'debug'
import url from 'url'
import MqttClient, {
IClientOptions,
MqttClientEventCallbacks,
Expand All @@ -18,24 +17,6 @@ const debug = _debug('mqttjs')

let protocols: Record<string, StreamBuilder> = null

/**
* Parse the auth attribute and merge username and password in the options object.
*
* @param {Object} [opts] option object
*/
function parseAuthOptions(opts: IClientOptions) {
let matches: RegExpMatchArray | null
if (opts.auth) {
matches = opts.auth.match(/^(.+):(.+)$/)
if (matches) {
opts.username = matches[1]
opts.password = matches[2]
} else {
opts.username = opts.auth
}
}
}

/**
* connect - connect to an MQTT broker.
*/
Expand All @@ -56,21 +37,35 @@ function connect(

// try to parse the broker url
if (brokerUrl && typeof brokerUrl === 'string') {
// eslint-disable-next-line
const parsedUrl = url.parse(brokerUrl, true)
const parsedUrl = new URL(brokerUrl)
const parsedOptions: Partial<IClientOptions> = {}

if (parsedUrl.port != null) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
parsedOptions.port = Number(parsedUrl.port)
}

parsedOptions.host = parsedUrl.hostname
parsedOptions.query = parsedUrl.query as Record<string, string>
parsedOptions.auth = parsedUrl.auth
parsedOptions.query = Object.fromEntries(
parsedUrl.searchParams,
) as Record<string, string>

if (parsedUrl.username) {
parsedOptions.username = parsedUrl.username
parsedOptions.auth = parsedOptions.username // TODO: is auth still needed?
if (parsedUrl.password) {
parsedOptions.password = parsedUrl.password
parsedOptions.auth = `${parsedOptions.username}:${parsedOptions.password}` // TODO: is auth still needed?
}
}

parsedOptions.protocol = parsedUrl.protocol as MqttProtocol
parsedOptions.path = parsedUrl.path
parsedOptions.path = parsedUrl.pathname // TODO: See note below
// NOTE: new URL().pathname is not the same as url.parse().path. URL.pathname does not include the query string.
// To make this field align with url.parse().path, we would need to append the query string to the path as below
// However I am not sure if this is required or used later in the code.
// if (parsedUrl.search) {
// parsedOptions.path += parsedUrl.search
// }

parsedOptions.protocol = parsedOptions.protocol?.replace(
/:$/,
Expand Down Expand Up @@ -99,9 +94,6 @@ function connect(
delete opts.path
}

// merge in the auth options if supplied
parseAuthOptions(opts)

// support clientId passed in the query string of the url
if (opts.query && typeof opts.query.clientId === 'string') {
opts.clientId = opts.query.clientId
Expand Down
16 changes: 15 additions & 1 deletion src/lib/connect/ws.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,21 @@ const WSS_OPTIONS = [
]

function buildUrl(opts: IClientOptions, client: MqttClient) {
let url = `${opts.protocol}://${opts.hostname}:${opts.port}${opts.path}`
const urlBuilder = new URL(`${opts.protocol}://${opts.host}`)
if (opts.port) {
urlBuilder.port = opts.port.toString()
}
urlBuilder.pathname = opts.path || '/'
Object.keys(opts.query || {}).forEach((key) => {
urlBuilder.searchParams.append(key, opts.query[key])
})
if (opts.username) {
urlBuilder.username = opts.username
if (opts.password) {
urlBuilder.password = opts.password.toString()
}
}
let url = urlBuilder.toString()
if (typeof opts.transformWsUrl === 'function') {
url = opts.transformWsUrl(url, opts, client)
}
Expand Down
2 changes: 1 addition & 1 deletion test/mqtt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ describe('mqtt', () => {

c.should.be.instanceOf(mqtt.MqttClient)
c.options.should.not.have.property('path')
c.options.should.have.property('host', '::1')
c.options.should.have.property('host', '[::1]')
c.end((err) => done(err))
})

Expand Down
Loading