Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 6 additions & 9 deletions lib/client/http-tracker.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,11 +190,11 @@ HTTPTracker.prototype._onAnnounceResponse = function (data) {
self._trackerId = trackerId
}

self.client.emit('update', {
var response = Object.assign({}, data, {
announce: self.announceUrl,
complete: data.complete,
incomplete: data.incomplete
infoHash: common.binaryToHex(data.info_hash)
})
self.client.emit('update', response)

var addrs
if (Buffer.isBuffer(data.peers)) {
Expand Down Expand Up @@ -248,15 +248,12 @@ HTTPTracker.prototype._onScrapeResponse = function (data) {
}

keys.forEach(function (infoHash) {
var response = data[infoHash]
// TODO: optionally handle data.flags.min_request_interval
// (separate from announce interval)
self.client.emit('scrape', {
var response = Object.assign(data[infoHash], {
announce: self.announceUrl,
infoHash: common.binaryToHex(infoHash),
complete: response.complete,
incomplete: response.incomplete,
downloaded: response.downloaded
infoHash: common.binaryToHex(infoHash)
})
self.client.emit('scrape', response)
})
}
16 changes: 8 additions & 8 deletions lib/client/websocket-tracker.js
Original file line number Diff line number Diff line change
Expand Up @@ -266,8 +266,11 @@ WebSocketTracker.prototype._onAnnounceResponse = function (data) {
}

if (data.complete != null) {
data.announce = self.announceUrl
self.client.emit('update', data)
var response = Object.assign({}, data, {
announce: self.announceUrl,
infoHash: common.binaryToHex(data.info_hash)
})
self.client.emit('update', response)
}

var peer
Expand Down Expand Up @@ -323,16 +326,13 @@ WebSocketTracker.prototype._onScrapeResponse = function (data) {
}

keys.forEach(function (infoHash) {
var response = data[infoHash]
// TODO: optionally handle data.flags.min_request_interval
// (separate from announce interval)
self.client.emit('scrape', {
var response = Object.assign(data[infoHash], {
announce: self.announceUrl,
infoHash: common.binaryToHex(infoHash),
complete: response.complete,
incomplete: response.incomplete,
downloaded: response.downloaded
infoHash: common.binaryToHex(infoHash)
})
self.client.emit('scrape', response)
})
}

Expand Down
35 changes: 11 additions & 24 deletions server.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,14 @@ inherits(Server, EventEmitter)
* metrics from clients that help the tracker keep overall statistics about the torrent.
* Responses include a peer list that helps the client participate in the torrent.
*
* @param {Object} opts options object
* @param {Number} opts.interval tell clients to announce on this interval (ms)
* @param {Number} opts.trustProxy trust 'x-forwarded-for' header from reverse proxy
* @param {boolean} opts.http start an http server? (default: true)
* @param {boolean} opts.udp start a udp server? (default: true)
* @param {boolean} opts.ws start a websocket server? (default: true)
* @param {boolean} opts.stats enable web-based statistics? (default: true)
* @param {function} opts.filter black/whitelist fn for disallowing/allowing torrents
* @param {function} opts.requestHandler functions to handle params / response
* @param {Object} opts options object
* @param {Number} opts.interval tell clients to announce on this interval (ms)
* @param {Number} opts.trustProxy trust 'x-forwarded-for' header from reverse proxy
* @param {boolean} opts.http start an http server? (default: true)
* @param {boolean} opts.udp start a udp server? (default: true)
* @param {boolean} opts.ws start a websocket server? (default: true)
* @param {boolean} opts.stats enable web-based statistics? (default: true)
* @param {function} opts.filter black/whitelist fn for disallowing/allowing torrents
*/
function Server (opts) {
var self = this
Expand Down Expand Up @@ -65,18 +64,6 @@ function Server (opts) {
self.udp6 = null
self.ws = null

self._reqHandler = opts.requestHandler || {}
if (!self._reqHandler.getParams) {
self._reqHandler.getParams = function (params) {
return params
}
}
if (!self._reqHandler.getResponse) {
self._reqHandler.getResponse = function (params, cb) {
return cb
}
}

// start an http tracker unless the user explictly says no
if (opts.http !== false) {
self.http = http.createServer()
Expand Down Expand Up @@ -293,6 +280,8 @@ function Server (opts) {
}
}

Server.Swarm = Swarm

Server.prototype._onError = function (err) {
var self = this
self.emit('error', err)
Expand Down Expand Up @@ -365,7 +354,7 @@ Server.prototype.createSwarm = function (infoHash, cb) {
if (Buffer.isBuffer(infoHash)) infoHash = infoHash.toString('hex')

process.nextTick(function () {
var swarm = self.torrents[infoHash] = new Swarm(infoHash, self)
var swarm = self.torrents[infoHash] = new Server.Swarm(infoHash, self)
cb(null, swarm)
})
}
Expand Down Expand Up @@ -649,8 +638,6 @@ Server.prototype._onWebSocketError = function (socket, err) {

Server.prototype._onRequest = function (params, cb) {
var self = this
params = self._reqHandler.getParams(params)
cb = self._reqHandler.getResponse(params, cb)
if (params && params.action === common.ACTIONS.CONNECT) {
cb(null, { action: common.ACTIONS.CONNECT })
} else if (params && params.action === common.ACTIONS.ANNOUNCE) {
Expand Down
36 changes: 21 additions & 15 deletions test/request-handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,33 @@ var Client = require('../')
var common = require('./common')
var fixtures = require('webtorrent-fixtures')
var test = require('tape')
var Server = require('../server')

var peerId = Buffer.from('01234567890123456789')

function testRequestHandler (t, serverType) {
t.plan(4)
t.plan(5)

var opts = { serverType: serverType } // this is test-suite-only option
opts.requestHandler = {
getParams: function (params) {
params.extra = 123
return params
},
getResponse: function (params, cb) {
return function (err, response) {
response.complete = params.extra * 2
cb(err, response)
}

class Swarm extends Server.Swarm {
announce (params, cb) {
super.announce(params, function (err, response) {
if (err) return cb(response)
response.complete = 246
response.extraData = 'hi'
cb(null, response)
})
}
}

// Use a custom Swarm implementation for this test only
var OldSwarm = Server.Swarm
Server.Swarm = Swarm
t.on('end', function () {
Server.Swarm = OldSwarm
})

common.createServer(t, opts, function (server, announceUrl) {
var client1 = new Client({
infoHash: fixtures.alice.parsedTorrent.infoHash,
Expand All @@ -41,6 +48,7 @@ function testRequestHandler (t, serverType) {

client1.once('update', function (data) {
t.equal(data.complete, 246)
t.equal(data.extraData.toString(), 'hi')

client1.destroy(function () {
t.pass('client1 destroyed')
Expand All @@ -59,10 +67,8 @@ test('http: request handler option intercepts announce requests and responses',
testRequestHandler(t, 'http')
})

test('udp: request handler option intercepts announce requests and responses', function (t) {
testRequestHandler(t, 'udp')
})

test('ws: request handler option intercepts announce requests and responses', function (t) {
testRequestHandler(t, 'ws')
})

// NOTE: it's not possible to include extra data in a UDP response, because it's compact and accepts only params that are in the spec!