Fix URL constructor on udp:// urls in Chrome App environment

For: https://github.com/brave/brave-browser/issues/5604

`bittorrent-tracker` is broken when run in a Chrome App environment.

The issue is that the `URL` constructor is buggy Chromium. https://bugs.chromium.org/p/chromium/issues/detail?id=734880

We switched to `URL` from `require('url')` in `bittorrent-tracker@9.13.0`. Commit: 93b41391a9

This code path was not exercised by `bittorrent-tracker`'s tests because UDP trackers are normally only used in a Node.js environment. Braves run the code in a Chrome extension environment which we don't test.
This commit is contained in:
Feross Aboukhadijeh 2019-08-08 20:04:41 -07:00
parent 91148ce40b
commit ddee6b96b5

View File

@ -71,7 +71,23 @@ class UDPTracker extends Tracker {
_request (opts) {
const self = this
if (!opts) opts = {}
const parsedUrl = new URL(this.announceUrl)
// 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:'))
if (port === '') port = 80
let transactionId = genTransactionId()
let socket = dgram.createSocket('udp4')
@ -204,10 +220,7 @@ class UDPTracker extends Tracker {
}
function send (message) {
if (!parsedUrl.port) {
parsedUrl.port = 80
}
socket.send(message, 0, message.length, parsedUrl.port, parsedUrl.hostname)
socket.send(message, 0, message.length, port, hostname)
}
function announce (connectionId, opts) {