Skip to content

Commit 231ff57

Browse files
committed
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)
1 parent 8a6744f commit 231ff57

File tree

3 files changed

+23
-14
lines changed

3 files changed

+23
-14
lines changed

client.js

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -197,14 +197,7 @@ Tracker.prototype._announce = function (opts) {
197197
Tracker.prototype.scrape = function () {
198198
var self = this
199199

200-
if (!self._scrapeUrl) {
201-
var announce = 'announce'
202-
var i = self._announceUrl.lastIndexOf('/') + 1
203-
204-
if (i >= 1 && self._announceUrl.slice(i, i + announce.length) === announce) {
205-
self._scrapeUrl = self._announceUrl.slice(0, i) + 'scrape' + self._announceUrl.slice(i + announce.length)
206-
}
207-
}
200+
self._scrapeUrl = self._scrapeUrl || getScrapeUrl(self._announceUrl)
208201

209202
if (!self._scrapeUrl) {
210203
debug('scrape not supported by ' + self._announceUrl)
@@ -213,7 +206,7 @@ Tracker.prototype.scrape = function () {
213206
}
214207

215208
debug('sent `scrape` to ' + self._announceUrl)
216-
self._requestImpl(self._scrapeUrl)
209+
self._requestImpl(self._scrapeUrl, { _scrape: true })
217210
}
218211

219212
Tracker.prototype.setInterval = function (intervalMs) {
@@ -229,7 +222,7 @@ Tracker.prototype.setInterval = function (intervalMs) {
229222
Tracker.prototype._requestHttp = function (requestUrl, opts) {
230223
var self = this
231224

232-
if (isScrapeUrl(requestUrl)) {
225+
if (opts._scrape) {
233226
opts = extend({
234227
info_hash: self.client._infoHash.toString('binary')
235228
}, opts)
@@ -307,7 +300,7 @@ Tracker.prototype._requestUdp = function (requestUrl, opts) {
307300
return error('invalid udp handshake')
308301
}
309302

310-
if (isScrapeUrl(requestUrl)) {
303+
if (opts._scrape) {
311304
scrape(msg.slice(8, 16))
312305
} else {
313306
announce(msg.slice(8, 16), opts)
@@ -511,3 +504,16 @@ function toUInt64 (n) {
511504
function isScrapeUrl (u) {
512505
return u.substr(u.lastIndexOf('/') + 1, 'scrape'.length) === 'scrape'
513506
}
507+
508+
var UDP_TRACKER = /^udp:\/\//
509+
var HTTP_SCRAPE_SUPPORT = /\/(announce)[^\/]*$/
510+
511+
function getScrapeUrl (announceUrl) {
512+
if (announceUrl.match(UDP_TRACKER)) return announceUrl
513+
var match
514+
if (match = announceUrl.match(HTTP_SCRAPE_SUPPORT)) {
515+
var i = match.index
516+
return announceUrl.slice(0, i) + '/scrape' + announceUrl.slice(i + 9)
517+
}
518+
return null
519+
}

test/client-large-torrent.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ test('large torrent: client.start()', function (t) {
2727
server.listen(port)
2828

2929
// remove all tracker servers except a single UDP one, for now
30-
parsedTorrent.announce = [ 'udp://127.0.0.1:' + port + '/announce' ]
30+
parsedTorrent.announce = [ 'udp://127.0.0.1:' + port ]
3131

3232
var client = new Client(peerId, 6881, parsedTorrent)
3333

@@ -36,7 +36,7 @@ test('large torrent: client.start()', function (t) {
3636
})
3737

3838
client.once('update', function (data) {
39-
t.equal(data.announce, 'udp://127.0.0.1:' + port + '/announce')
39+
t.equal(data.announce, 'udp://127.0.0.1:' + port)
4040
t.equal(typeof data.complete, 'number')
4141
t.equal(typeof data.incomplete, 'number')
4242
})

test/client.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,10 @@ function createServer (t, serverType, cb) {
2828
portfinder.getPort(function (err, port) {
2929
if (err) return t.error(err)
3030

31-
announceUrl = serverType + '://127.0.0.1:' + port + '/announce'
31+
announceUrl = serverType === 'http'
32+
? 'http://127.0.0.1:' + port + '/announce'
33+
: 'udp://127.0.0.1:' + port
34+
3235
parsedTorrent.announce = [ announceUrl ]
3336

3437
server.listen(port)

0 commit comments

Comments
 (0)