Skip to content

Commit

Permalink
fix: UDP url parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
alxhotel committed May 20, 2021
1 parent 2a12b75 commit 8e24a8c
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 15 deletions.
2 changes: 1 addition & 1 deletion client.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ class Client extends EventEmitter {
.map(announceUrl => {
let parsedUrl
try {
parsedUrl = new URL(announceUrl)
parsedUrl = common.parseUrl(announceUrl)
} catch (err) {
nextTickWarn(new Error(`Invalid tracker URL: ${announceUrl}`))
return null
Expand Down
15 changes: 1 addition & 14 deletions lib/client/udp-tracker.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,20 +74,7 @@ class UDPTracker extends Tracker {
const self = this
if (!opts) opts = {}

// HACK: Fix for WHATWG URL object not parsing non-standard URL schemes like
// 'udp:'. Just replace it with 'http:' since we only need the `hostname`
// and `port` properties.
//
// Note: Only affects Chrome and Firefox. Works fine in Node.js, Safari, and
// Edge.
//
// Note: UDP trackers aren't used in the normal browser build, but they are
// used in a Chrome App build (i.e. by Brave Browser).
//
// Bug reports:
// - Chrome: https://bugs.chromium.org/p/chromium/issues/detail?id=734880
// - Firefox: https://bugzilla.mozilla.org/show_bug.cgi?id=1374505
let { hostname, port } = new URL(this.announceUrl.replace(/^udp:/, 'http:'))
let { hostname, port } = common.parseUrl(this.announceUrl)
if (port === '') port = 80

let transactionId = genTransactionId()
Expand Down
31 changes: 31 additions & 0 deletions lib/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,36 @@ exports.hexToBinary = function (str) {
return Buffer.from(str, 'hex').toString('binary')
}

// HACK: Fix for WHATWG URL object not parsing non-standard URL schemes like
// 'udp:'. Just replace it with 'http:' since we only need a few properties.
//
// Note: Only affects Chrome and Firefox. Works fine in Node.js, Safari, and
// Edge.
//
// Note: UDP trackers aren't used in the normal browser build, but they are
// used in a Chrome App build (i.e. by Brave Browser).
//
// Bug reports:
// - Chrome: https://bugs.chromium.org/p/chromium/issues/detail?id=734880
// - Firefox: https://bugzilla.mozilla.org/show_bug.cgi?id=1374505
exports.parseUrl = function (str) {
const isUDP = str.match(/^udp:/)
const parsedUrl = (isUDP) ? new URL(str.replace(/^udp:/, 'http:')) : new URL(str)

return {
hash: parsedUrl.hash,
host: parsedUrl.host,
hostname: parsedUrl.hostname,
href: isUDP ? parsedUrl.href.replace(/^http:/, 'udp:') : parsedUrl.href,
origin: isUDP ? parsedUrl.origin.replace(/^http:/, 'udp:') : parsedUrl.origin,
password: parsedUrl.password,
pathname: parsedUrl.pathname,
port: parsedUrl.port,
protocol: isUDP ? 'udp:' : parsedUrl.protocol,
search: parsedUrl.search,
username: parsedUrl.username
}
}

const config = require('./common-node')
Object.assign(exports, config)
24 changes: 24 additions & 0 deletions test/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -534,10 +534,34 @@ test('http: invalid tracker port', function (t) {
testUnsupportedTracker(t, 'http://127.0.0.1:69691337/announce')
})

test('http: invalid tracker url', function (t) {
testUnsupportedTracker(t, 'http:')
})

test('http: invalid tracker url with slash', function (t) {
testUnsupportedTracker(t, 'http://')
})

test('udp: invalid tracker port', function (t) {
testUnsupportedTracker(t, 'udp://127.0.0.1:69691337')
})

test('udp: invalid tracker url', function (t) {
testUnsupportedTracker(t, 'udp:')
})

test('udp: invalid tracker url with slash', function (t) {
testUnsupportedTracker(t, 'udp://')
})

test('ws: invalid tracker port', function (t) {
testUnsupportedTracker(t, 'ws://127.0.0.1:69691337')
})

test('ws: invalid tracker url', function (t) {
testUnsupportedTracker(t, 'ws:')
})

test('ws: invalid tracker url with slash', function (t) {
testUnsupportedTracker(t, 'ws://')
})

0 comments on commit 8e24a8c

Please sign in to comment.