mirror of
https://github.com/webtorrent/bittorrent-tracker.git
synced 2025-02-21 20:59:02 +00:00
Support async createSwarm() and getSwarm()
Fix #95. Make server.getSwarm() and server.createSwarm() into async functions that take a callback.
This commit is contained in:
parent
9d4c404dc6
commit
b5096e91c3
@ -4,7 +4,7 @@ var debug = require('debug')('bittorrent-tracker')
|
||||
var randomIterate = require('random-iterate')
|
||||
|
||||
// Regard this as the default implementation of an interface that you
|
||||
// need to support when overriding Server.getSwarm()
|
||||
// need to support when overriding Server.createSwarm() and Server.getSwarm()
|
||||
function Swarm (infoHash, server) {
|
||||
this.peers = {}
|
||||
this.complete = 0
|
||||
|
110
server.js
110
server.js
@ -196,17 +196,23 @@ Server.prototype.close = function (cb) {
|
||||
else cb(null)
|
||||
}
|
||||
|
||||
Server.prototype.createSwarm = function (infoHash) {
|
||||
Server.prototype.createSwarm = function (infoHash, cb) {
|
||||
var self = this
|
||||
if (Buffer.isBuffer(infoHash)) infoHash = infoHash.toString('hex')
|
||||
var swarm = self.torrents[infoHash] = new Swarm(infoHash, self)
|
||||
return swarm
|
||||
|
||||
process.nextTick(function () {
|
||||
var swarm = self.torrents[infoHash] = new Swarm(infoHash, self)
|
||||
cb(null, swarm)
|
||||
})
|
||||
}
|
||||
|
||||
Server.prototype.getSwarm = function (infoHash) {
|
||||
Server.prototype.getSwarm = function (infoHash, cb) {
|
||||
var self = this
|
||||
if (Buffer.isBuffer(infoHash)) infoHash = infoHash.toString('hex')
|
||||
return self.torrents[infoHash]
|
||||
|
||||
process.nextTick(function () {
|
||||
cb(null, self.torrents[infoHash])
|
||||
})
|
||||
}
|
||||
|
||||
Server.prototype.onHttpRequest = function (req, res, opts) {
|
||||
@ -358,26 +364,35 @@ Server.prototype._onWebSocketRequest = function (socket, params) {
|
||||
if (params.answer) {
|
||||
debug('got answer %s from %s', JSON.stringify(params.answer), params.peer_id)
|
||||
|
||||
var swarm = self.getSwarm(params.info_hash)
|
||||
if (!swarm) {
|
||||
return self.emit('warning', new Error('no swarm with that `info_hash`'))
|
||||
}
|
||||
var toPeer = swarm.peers[params.to_peer_id]
|
||||
if (!toPeer) {
|
||||
return self.emit('warning', new Error('no peer with that `to_peer_id`'))
|
||||
}
|
||||
self.getSwarm(params.info_hash, function (err, swarm) {
|
||||
if (err) return self.emit('warning', err)
|
||||
if (!swarm) {
|
||||
return self.emit('warning', new Error('no swarm with that `info_hash`'))
|
||||
}
|
||||
var toPeer = swarm.peers[params.to_peer_id]
|
||||
if (!toPeer) {
|
||||
return self.emit('warning', new Error('no peer with that `to_peer_id`'))
|
||||
}
|
||||
|
||||
toPeer.socket.send(JSON.stringify({
|
||||
answer: params.answer,
|
||||
offer_id: params.offer_id,
|
||||
peer_id: common.hexToBinary(params.peer_id),
|
||||
info_hash: common.hexToBinary(params.info_hash)
|
||||
}), toPeer.socket.onSend)
|
||||
debug('sent answer to %s from %s', toPeer.peerId, params.peer_id)
|
||||
toPeer.socket.send(JSON.stringify({
|
||||
answer: params.answer,
|
||||
offer_id: params.offer_id,
|
||||
peer_id: common.hexToBinary(params.peer_id),
|
||||
info_hash: common.hexToBinary(params.info_hash)
|
||||
}), toPeer.socket.onSend)
|
||||
debug('sent answer to %s from %s', toPeer.peerId, params.peer_id)
|
||||
|
||||
done()
|
||||
})
|
||||
} else {
|
||||
done()
|
||||
}
|
||||
|
||||
if (params.action === common.ACTIONS.ANNOUNCE) {
|
||||
self.emit(common.EVENT_NAMES[params.event], params.peer_id, params)
|
||||
function done () {
|
||||
// emit event once the announce is fully "processed"
|
||||
if (params.action === common.ACTIONS.ANNOUNCE) {
|
||||
self.emit(common.EVENT_NAMES[params.event], params.peer_id, params)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -398,9 +413,14 @@ Server.prototype._onRequest = function (params, cb) {
|
||||
Server.prototype._onAnnounce = function (params, cb) {
|
||||
var self = this
|
||||
|
||||
var swarm = self.getSwarm(params.info_hash)
|
||||
if (swarm) announce()
|
||||
else createSwarm()
|
||||
self.getSwarm(params.info_hash, function (err, swarm) {
|
||||
if (err) return cb(err)
|
||||
if (swarm) {
|
||||
announce(swarm)
|
||||
} else {
|
||||
createSwarm()
|
||||
}
|
||||
})
|
||||
|
||||
function createSwarm () {
|
||||
if (self._filter) {
|
||||
@ -410,17 +430,21 @@ Server.prototype._onAnnounce = function (params, cb) {
|
||||
} else if (!allowed) {
|
||||
cb(new Error('disallowed info_hash'))
|
||||
} else {
|
||||
swarm = self.createSwarm(params.info_hash)
|
||||
announce()
|
||||
self.createSwarm(params.info_hash, function (err, swarm) {
|
||||
if (err) return cb(err)
|
||||
announce(swarm)
|
||||
})
|
||||
}
|
||||
})
|
||||
} else {
|
||||
swarm = self.createSwarm(params.info_hash)
|
||||
announce()
|
||||
self.createSwarm(params.info_hash, function (err, swarm) {
|
||||
if (err) return cb(err)
|
||||
announce(swarm)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function announce () {
|
||||
function announce (swarm) {
|
||||
if (!params.event || params.event === 'empty') params.event = 'update'
|
||||
swarm.announce(params, function (err, response) {
|
||||
if (err) return cb(err)
|
||||
@ -470,19 +494,21 @@ Server.prototype._onScrape = function (params, cb) {
|
||||
|
||||
series(params.info_hash.map(function (infoHash) {
|
||||
return function (cb) {
|
||||
var swarm = self.getSwarm(infoHash)
|
||||
if (swarm) {
|
||||
swarm.scrape(params, function (err, scrapeInfo) {
|
||||
if (err) return cb(err)
|
||||
cb(null, {
|
||||
infoHash: infoHash,
|
||||
complete: (scrapeInfo && scrapeInfo.complete) || 0,
|
||||
incomplete: (scrapeInfo && scrapeInfo.incomplete) || 0
|
||||
self.getSwarm(infoHash, function (err, swarm) {
|
||||
if (err) return cb(err)
|
||||
if (swarm) {
|
||||
swarm.scrape(params, function (err, scrapeInfo) {
|
||||
if (err) return cb(err)
|
||||
cb(null, {
|
||||
infoHash: infoHash,
|
||||
complete: (scrapeInfo && scrapeInfo.complete) || 0,
|
||||
incomplete: (scrapeInfo && scrapeInfo.incomplete) || 0
|
||||
})
|
||||
})
|
||||
})
|
||||
} else {
|
||||
cb(null, { infoHash: infoHash, complete: 0, incomplete: 0 })
|
||||
}
|
||||
} else {
|
||||
cb(null, { infoHash: infoHash, complete: 0, incomplete: 0 })
|
||||
}
|
||||
})
|
||||
}
|
||||
}), function (err, results) {
|
||||
if (err) return cb(err)
|
||||
|
@ -8,7 +8,7 @@ var peerId2 = new Buffer('12345678901234567890')
|
||||
var torrentLength = 50000
|
||||
|
||||
function serverTest (t, serverType, serverFamily) {
|
||||
t.plan(25)
|
||||
t.plan(26)
|
||||
|
||||
var opts = serverType === 'http' ? { udp: false, ws: false } : { http: false, ws: false }
|
||||
var server = new Server(opts)
|
||||
@ -49,65 +49,67 @@ function serverTest (t, serverType, serverFamily) {
|
||||
t.equal(data.complete, 0)
|
||||
t.equal(data.incomplete, 1)
|
||||
|
||||
var swarm = server.getSwarm(infoHash)
|
||||
server.getSwarm(infoHash, function (err, swarm) {
|
||||
t.error(err)
|
||||
|
||||
t.equal(Object.keys(server.torrents).length, 1)
|
||||
t.equal(swarm.complete, 0)
|
||||
t.equal(swarm.incomplete, 1)
|
||||
t.equal(Object.keys(swarm.peers).length, 1)
|
||||
t.deepEqual(swarm.peers[clientAddr + ':6881'], {
|
||||
ip: clientIp,
|
||||
port: 6881,
|
||||
peerId: peerId.toString('hex'),
|
||||
complete: false,
|
||||
socket: undefined
|
||||
})
|
||||
t.equal(Object.keys(server.torrents).length, 1)
|
||||
t.equal(swarm.complete, 0)
|
||||
t.equal(swarm.incomplete, 1)
|
||||
t.equal(Object.keys(swarm.peers).length, 1)
|
||||
t.deepEqual(swarm.peers[clientAddr + ':6881'], {
|
||||
ip: clientIp,
|
||||
port: 6881,
|
||||
peerId: peerId.toString('hex'),
|
||||
complete: false,
|
||||
socket: undefined
|
||||
})
|
||||
|
||||
client1.complete()
|
||||
client1.complete()
|
||||
|
||||
client1.once('update', function (data) {
|
||||
t.equal(data.announce, announceUrl)
|
||||
t.equal(data.complete, 1)
|
||||
t.equal(data.incomplete, 0)
|
||||
|
||||
client1.scrape()
|
||||
|
||||
client1.once('scrape', function (data) {
|
||||
client1.once('update', function (data) {
|
||||
t.equal(data.announce, announceUrl)
|
||||
t.equal(typeof data.complete, 'number')
|
||||
t.equal(typeof data.incomplete, 'number')
|
||||
t.equal(typeof data.downloaded, 'number')
|
||||
t.equal(data.complete, 1)
|
||||
t.equal(data.incomplete, 0)
|
||||
|
||||
var client2 = new Client(peerId2, 6882, {
|
||||
infoHash: infoHash,
|
||||
length: torrentLength,
|
||||
announce: [ announceUrl ]
|
||||
})
|
||||
client1.scrape()
|
||||
|
||||
client2.start()
|
||||
client1.once('scrape', function (data) {
|
||||
t.equal(data.announce, announceUrl)
|
||||
t.equal(typeof data.complete, 'number')
|
||||
t.equal(typeof data.incomplete, 'number')
|
||||
t.equal(typeof data.downloaded, 'number')
|
||||
|
||||
server.once('start', function () {
|
||||
t.pass('got start message from client2')
|
||||
})
|
||||
var client2 = new Client(peerId2, 6882, {
|
||||
infoHash: infoHash,
|
||||
length: torrentLength,
|
||||
announce: [ announceUrl ]
|
||||
})
|
||||
|
||||
client2.once('peer', function (addr) {
|
||||
t.ok(addr === clientAddr + ':6881' || addr === clientAddr + ':6882')
|
||||
client2.start()
|
||||
|
||||
client2.stop()
|
||||
client2.once('update', function (data) {
|
||||
t.equal(data.announce, announceUrl)
|
||||
t.equal(data.complete, 1)
|
||||
t.equal(data.incomplete, 0)
|
||||
client2.destroy()
|
||||
server.once('start', function () {
|
||||
t.pass('got start message from client2')
|
||||
})
|
||||
|
||||
client1.stop()
|
||||
client1.once('update', function (data) {
|
||||
client2.once('peer', function (addr) {
|
||||
t.ok(addr === clientAddr + ':6881' || addr === clientAddr + ':6882')
|
||||
|
||||
client2.stop()
|
||||
client2.once('update', function (data) {
|
||||
t.equal(data.announce, announceUrl)
|
||||
t.equal(data.complete, 0)
|
||||
t.equal(data.complete, 1)
|
||||
t.equal(data.incomplete, 0)
|
||||
client2.destroy()
|
||||
|
||||
client1.destroy()
|
||||
server.close()
|
||||
client1.stop()
|
||||
client1.once('update', function (data) {
|
||||
t.equal(data.announce, announceUrl)
|
||||
t.equal(data.complete, 0)
|
||||
t.equal(data.incomplete, 0)
|
||||
|
||||
client1.destroy()
|
||||
server.close()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user