diff --git a/client.js b/client.js index 6308a4a..bdff48e 100644 --- a/client.js +++ b/client.js @@ -461,7 +461,7 @@ Tracker.prototype._handleResponse = function (requestUrl, data) { } else if (requestUrl === self._scrapeUrl) { // NOTE: the unofficial spec says to use the 'files' key but i've seen 'host' in practice data = data.files || data.host || {} - data = data[common.bytewiseEncodeURIComponent(self.client._infoHash)] + data = data[self.client._infoHash.toString('binary')] if (!data) { self.client.emit('warning', new Error('invalid scrape response')) diff --git a/server.js b/server.js index 7080d66..4af193f 100644 --- a/server.js +++ b/server.js @@ -94,11 +94,19 @@ Server.prototype.close = function (cb) { } } -Server.prototype._getSwarm = function (infoHash) { +Server.prototype.getSwarm = function (infoHash) { var self = this - var swarm = self.torrents[infoHash] + var binaryInfoHash = Buffer.isBuffer(infoHash) + ? infoHash.toString('binary') + : new Buffer(infoHash, 'hex').toString('binary') + return self._getSwarm(binaryInfoHash) +} + +Server.prototype._getSwarm = function (binaryInfoHash) { + var self = this + var swarm = self.torrents[binaryInfoHash] if (!swarm) { - swarm = self.torrents[infoHash] = { + swarm = self.torrents[binaryInfoHash] = { complete: 0, incomplete: 0, peers: {} @@ -116,13 +124,13 @@ Server.prototype._onHttpRequest = function (req, res) { if (s[0] === '/announce') { var infoHash = typeof params.info_hash === 'string' && - common.bytewiseDecodeURIComponent(params.info_hash).toString('hex') + common.bytewiseDecodeURIComponent(params.info_hash).toString('binary') var port = Number(params.port) var peerId = typeof params.peer_id === 'string' && common.bytewiseDecodeURIComponent(params.peer_id).toString('utf8') if (!infoHash) return error('invalid info_hash') - if (infoHash.length !== 40) return error('invalid info_hash') + if (infoHash.length !== 20) return error('invalid info_hash') if (!port) return error('invalid port') if (!peerId) return error('invalid peer_id') @@ -222,9 +230,7 @@ Server.prototype._onHttpRequest = function (req, res) { params.info_hash = [ params.info_hash ] } else if (params.info_hash == null) { // if info_hash param is omitted, stats for all torrents are returned - params.info_hash = Object.keys(self.torrents).map(function (infoHashHex) { - return common.bytewiseEncodeURIComponent(new Buffer(infoHashHex, 'hex')) - }) + params.info_hash = Object.keys(self.torrents) } if (!Array.isArray(params.info_hash)) return error('invalid info_hash') @@ -237,13 +243,13 @@ Server.prototype._onHttpRequest = function (req, res) { } params.info_hash.some(function (infoHash) { - var infoHashHex = common.bytewiseDecodeURIComponent(infoHash).toString('hex') - if (infoHashHex.length !== 40) { + infoHash = common.bytewiseDecodeURIComponent(infoHash).toString('binary') + if (infoHash.length !== 20) { error('invalid info_hash') return true // early return } - var swarm = self._getSwarm(infoHashHex) + var swarm = self._getSwarm(infoHash) response.files[infoHash] = { complete: swarm.complete, @@ -297,7 +303,7 @@ Server.prototype._onUdpRequest = function (msg, rinfo) { connectionId ])) } else if (action === common.ACTIONS.ANNOUNCE) { - var infoHash = msg.slice(16, 36).toString('hex') // 20 bytes + var infoHash = msg.slice(16, 36).toString('binary') // 20 bytes var peerId = msg.slice(36, 56).toString('utf8') // 20 bytes var downloaded = fromUInt64(msg.slice(56, 64)) var left = fromUInt64(msg.slice(64, 72)) @@ -405,7 +411,7 @@ Server.prototype._onUdpRequest = function (msg, rinfo) { ])) } else if (action === common.ACTIONS.SCRAPE) { // scrape message - var infoHash = msg.slice(16, 36).toString('hex') // 20 bytes + var infoHash = msg.slice(16, 36).toString('binary') // 20 bytes // TODO: support multiple info_hash scrape if (msg.length > 36) { diff --git a/test/scrape.js b/test/scrape.js index 8ce7b7f..cce5a22 100644 --- a/test/scrape.js +++ b/test/scrape.js @@ -14,16 +14,19 @@ var infoHash1 = 'aaa67059ed6bd08362da625b3ae77f6f4a075aaa' var encodedInfoHash1 = common.bytewiseEncodeURIComponent( new Buffer(infoHash1, 'hex') ) +var binaryinfoHash1 = new Buffer(infoHash1, 'hex').toString('binary') var infoHash2 = 'bbb67059ed6bd08362da625b3ae77f6f4a075bbb' var encodedInfoHash2 = common.bytewiseEncodeURIComponent( new Buffer(infoHash2, 'hex') ) +var binaryinfoHash2 = new Buffer(infoHash2, 'hex').toString('binary') var bitlove = fs.readFileSync(__dirname + '/torrents/bitlove-intro.torrent') var parsedBitlove = parseTorrent(bitlove) var encodedBitlove = common.bytewiseEncodeURIComponent( new Buffer(parsedBitlove.infoHash, 'hex') ) +var binaryBitlove = new Buffer(parsedBitlove.infoHash, 'hex').toString('binary') var peerId = new Buffer('01234567890123456789') test('server: single info_hash scrape', function (t) { @@ -50,10 +53,10 @@ test('server: single info_hash scrape', function (t) { data = bencode.decode(data) t.ok(data.files) t.equal(Object.keys(data.files).length, 1) - t.ok(data.files[encodedInfoHash1]) - t.equal(typeof data.files[encodedInfoHash1].complete, 'number') - t.equal(typeof data.files[encodedInfoHash1].incomplete, 'number') - t.equal(typeof data.files[encodedInfoHash1].downloaded, 'number') + t.ok(data.files[binaryinfoHash1]) + t.equal(typeof data.files[binaryinfoHash1].complete, 'number') + t.equal(typeof data.files[binaryinfoHash1].incomplete, 'number') + t.equal(typeof data.files[binaryinfoHash1].downloaded, 'number') server.close(function () { t.end() @@ -91,15 +94,15 @@ test('server: multiple info_hash scrape', function (t) { t.ok(data.files) t.equal(Object.keys(data.files).length, 2) - t.ok(data.files[encodedInfoHash1]) - t.equal(typeof data.files[encodedInfoHash1].complete, 'number') - t.equal(typeof data.files[encodedInfoHash1].incomplete, 'number') - t.equal(typeof data.files[encodedInfoHash1].downloaded, 'number') + t.ok(data.files[binaryinfoHash1]) + t.equal(typeof data.files[binaryinfoHash1].complete, 'number') + t.equal(typeof data.files[binaryinfoHash1].incomplete, 'number') + t.equal(typeof data.files[binaryinfoHash1].downloaded, 'number') - t.ok(data.files[encodedInfoHash2]) - t.equal(typeof data.files[encodedInfoHash2].complete, 'number') - t.equal(typeof data.files[encodedInfoHash2].incomplete, 'number') - t.equal(typeof data.files[encodedInfoHash2].downloaded, 'number') + t.ok(data.files[binaryinfoHash2]) + t.equal(typeof data.files[binaryinfoHash2].complete, 'number') + t.equal(typeof data.files[binaryinfoHash2].incomplete, 'number') + t.equal(typeof data.files[binaryinfoHash2].downloaded, 'number') server.close(function () { t.end() @@ -149,10 +152,10 @@ test('server: all info_hash scrape', function (t) { t.ok(data.files) t.equal(Object.keys(data.files).length, 1) - t.ok(data.files[encodedBitlove]) - t.equal(typeof data.files[encodedBitlove].complete, 'number') - t.equal(typeof data.files[encodedBitlove].incomplete, 'number') - t.equal(typeof data.files[encodedBitlove].downloaded, 'number') + t.ok(data.files[binaryBitlove]) + t.equal(typeof data.files[binaryBitlove].complete, 'number') + t.equal(typeof data.files[binaryBitlove].incomplete, 'number') + t.equal(typeof data.files[binaryBitlove].downloaded, 'number') client.stop() server.close(function () { diff --git a/test/server.js b/test/server.js index 87ba2d8..fb68848 100644 --- a/test/server.js +++ b/test/server.js @@ -49,10 +49,10 @@ test('http server', function (t) { t.equal(data.incomplete, 1) t.equal(Object.keys(server.torrents).length, 1) - t.equal(server.torrents[infoHash].complete, 0) - t.equal(server.torrents[infoHash].incomplete, 1) - t.equal(Object.keys(server.torrents[infoHash].peers).length, 1) - t.deepEqual(server.torrents[infoHash].peers['127.0.0.1:6881'], { + t.equal(server.getSwarm(infoHash).complete, 0) + t.equal(server.getSwarm(infoHash).incomplete, 1) + t.equal(Object.keys(server.getSwarm(infoHash).peers).length, 1) + t.deepEqual(server.getSwarm(infoHash).peers['127.0.0.1:6881'], { ip: '127.0.0.1', port: 6881, peerId: peerId diff --git a/test/udp-server.js b/test/udp-server.js index c06a6ec..af03bb9 100644 --- a/test/udp-server.js +++ b/test/udp-server.js @@ -49,10 +49,10 @@ test('udp server', function (t) { t.equal(data.incomplete, 1) t.equal(Object.keys(server.torrents).length, 1) - t.equal(server.torrents[infoHash].complete, 0) - t.equal(server.torrents[infoHash].incomplete, 1) - t.equal(Object.keys(server.torrents[infoHash].peers).length, 1) - t.deepEqual(server.torrents[infoHash].peers['127.0.0.1:6881'], { + t.equal(server.getSwarm(infoHash).complete, 0) + t.equal(server.getSwarm(infoHash).incomplete, 1) + t.equal(Object.keys(server.getSwarm(infoHash).peers).length, 1) + t.deepEqual(server.getSwarm(infoHash).peers['127.0.0.1:6881'], { ip: '127.0.0.1', port: 6881, peerId: peerId