correctly detect UDP tracker scrape support

Before this fix, udp tracker urls needed to contain “/announce” or else
we would assume the tracker doesn’t support scrape. (This is correct
behavior for http trackers, but not udp)
This commit is contained in:
Feross Aboukhadijeh 2014-07-20 04:34:32 -07:00
parent 8a6744f276
commit 231ff5709c
3 changed files with 23 additions and 14 deletions

View File

@ -197,14 +197,7 @@ Tracker.prototype._announce = function (opts) {
Tracker.prototype.scrape = function () { Tracker.prototype.scrape = function () {
var self = this var self = this
if (!self._scrapeUrl) { self._scrapeUrl = self._scrapeUrl || getScrapeUrl(self._announceUrl)
var announce = 'announce'
var i = self._announceUrl.lastIndexOf('/') + 1
if (i >= 1 && self._announceUrl.slice(i, i + announce.length) === announce) {
self._scrapeUrl = self._announceUrl.slice(0, i) + 'scrape' + self._announceUrl.slice(i + announce.length)
}
}
if (!self._scrapeUrl) { if (!self._scrapeUrl) {
debug('scrape not supported by ' + self._announceUrl) debug('scrape not supported by ' + self._announceUrl)
@ -213,7 +206,7 @@ Tracker.prototype.scrape = function () {
} }
debug('sent `scrape` to ' + self._announceUrl) debug('sent `scrape` to ' + self._announceUrl)
self._requestImpl(self._scrapeUrl) self._requestImpl(self._scrapeUrl, { _scrape: true })
} }
Tracker.prototype.setInterval = function (intervalMs) { Tracker.prototype.setInterval = function (intervalMs) {
@ -229,7 +222,7 @@ Tracker.prototype.setInterval = function (intervalMs) {
Tracker.prototype._requestHttp = function (requestUrl, opts) { Tracker.prototype._requestHttp = function (requestUrl, opts) {
var self = this var self = this
if (isScrapeUrl(requestUrl)) { if (opts._scrape) {
opts = extend({ opts = extend({
info_hash: self.client._infoHash.toString('binary') info_hash: self.client._infoHash.toString('binary')
}, opts) }, opts)
@ -307,7 +300,7 @@ Tracker.prototype._requestUdp = function (requestUrl, opts) {
return error('invalid udp handshake') return error('invalid udp handshake')
} }
if (isScrapeUrl(requestUrl)) { if (opts._scrape) {
scrape(msg.slice(8, 16)) scrape(msg.slice(8, 16))
} else { } else {
announce(msg.slice(8, 16), opts) announce(msg.slice(8, 16), opts)
@ -511,3 +504,16 @@ function toUInt64 (n) {
function isScrapeUrl (u) { function isScrapeUrl (u) {
return u.substr(u.lastIndexOf('/') + 1, 'scrape'.length) === 'scrape' return u.substr(u.lastIndexOf('/') + 1, 'scrape'.length) === 'scrape'
} }
var UDP_TRACKER = /^udp:\/\//
var HTTP_SCRAPE_SUPPORT = /\/(announce)[^\/]*$/
function getScrapeUrl (announceUrl) {
if (announceUrl.match(UDP_TRACKER)) return announceUrl
var match
if (match = announceUrl.match(HTTP_SCRAPE_SUPPORT)) {
var i = match.index
return announceUrl.slice(0, i) + '/scrape' + announceUrl.slice(i + 9)
}
return null
}

View File

@ -27,7 +27,7 @@ test('large torrent: client.start()', function (t) {
server.listen(port) server.listen(port)
// remove all tracker servers except a single UDP one, for now // remove all tracker servers except a single UDP one, for now
parsedTorrent.announce = [ 'udp://127.0.0.1:' + port + '/announce' ] parsedTorrent.announce = [ 'udp://127.0.0.1:' + port ]
var client = new Client(peerId, 6881, parsedTorrent) var client = new Client(peerId, 6881, parsedTorrent)
@ -36,7 +36,7 @@ test('large torrent: client.start()', function (t) {
}) })
client.once('update', function (data) { client.once('update', function (data) {
t.equal(data.announce, 'udp://127.0.0.1:' + port + '/announce') t.equal(data.announce, 'udp://127.0.0.1:' + port)
t.equal(typeof data.complete, 'number') t.equal(typeof data.complete, 'number')
t.equal(typeof data.incomplete, 'number') t.equal(typeof data.incomplete, 'number')
}) })

View File

@ -28,7 +28,10 @@ function createServer (t, serverType, cb) {
portfinder.getPort(function (err, port) { portfinder.getPort(function (err, port) {
if (err) return t.error(err) if (err) return t.error(err)
announceUrl = serverType + '://127.0.0.1:' + port + '/announce' announceUrl = serverType === 'http'
? 'http://127.0.0.1:' + port + '/announce'
: 'udp://127.0.0.1:' + port
parsedTorrent.announce = [ announceUrl ] parsedTorrent.announce = [ announceUrl ]
server.listen(port) server.listen(port)