|
1 | 1 | module.exports = Server |
2 | 2 |
|
3 | 3 | var bencode = require('bencode') |
4 | | -var common = require('./lib/common') |
5 | 4 | var debug = require('debug')('bittorrent-tracker') |
6 | 5 | var dgram = require('dgram') |
7 | 6 | var EventEmitter = require('events').EventEmitter |
8 | 7 | var http = require('http') |
9 | 8 | var inherits = require('inherits') |
10 | 9 | var ipLib = require('ip') |
11 | 10 | var portfinder = require('portfinder') |
12 | | -var string2compact = require('string2compact') |
| 11 | +var series = require('run-series') |
13 | 12 |
|
| 13 | +var common = require('./lib/common') |
| 14 | +var Swarm = require('./lib/swarm') |
14 | 15 | var parseHttpRequest = require('./lib/parse_http') |
15 | 16 | var parseUdpRequest = require('./lib/parse_udp') |
16 | 17 |
|
@@ -119,11 +120,7 @@ Server.prototype.getSwarm = function (binaryInfoHash) { |
119 | 120 | if (Buffer.isBuffer(binaryInfoHash)) binaryInfoHash = binaryInfoHash.toString('binary') |
120 | 121 | var swarm = self.torrents[binaryInfoHash] |
121 | 122 | if (!swarm) { |
122 | | - swarm = self.torrents[binaryInfoHash] = { |
123 | | - complete: 0, |
124 | | - incomplete: 0, |
125 | | - peers: {} |
126 | | - } |
| 123 | + swarm = self.torrents[binaryInfoHash] = new Swarm(binaryInfoHash, this) |
127 | 124 | } |
128 | 125 | return swarm |
129 | 126 | } |
@@ -214,89 +211,13 @@ Server.prototype._onRequest = function (params, cb) { |
214 | 211 |
|
215 | 212 | Server.prototype._onAnnounce = function (params, cb) { |
216 | 213 | var self = this |
217 | | - |
218 | 214 | var swarm = self.getSwarm(params.info_hash) |
219 | | - var peer = swarm.peers[params.addr] |
220 | | - |
221 | | - var start = function () { |
222 | | - if (peer) { |
223 | | - debug('unexpected `started` event from peer that is already in swarm') |
224 | | - return update() // treat as an update |
| 215 | + swarm.announce(params, function (err, response) { |
| 216 | + if (response) { |
| 217 | + if (!response.action) response.action = common.ACTIONS.ANNOUNCE |
| 218 | + if (!response.intervalMs) response.intervalMs = self._intervalMs |
225 | 219 | } |
226 | | - if (params.left === 0) swarm.complete += 1 |
227 | | - else swarm.incomplete += 1 |
228 | | - peer = swarm.peers[params.addr] = { |
229 | | - ip: params.ip, |
230 | | - port: params.port, |
231 | | - peerId: params.peer_id |
232 | | - } |
233 | | - self.emit('start', params.addr) |
234 | | - } |
235 | | - |
236 | | - var stop = function () { |
237 | | - if (!peer) { |
238 | | - debug('unexpected `stopped` event from peer that is not in swarm') |
239 | | - return // do nothing |
240 | | - } |
241 | | - if (peer.complete) swarm.complete -= 1 |
242 | | - else swarm.incomplete -= 1 |
243 | | - swarm.peers[params.addr] = null |
244 | | - self.emit('stop', params.addr) |
245 | | - } |
246 | | - |
247 | | - var complete = function () { |
248 | | - if (!peer) { |
249 | | - debug('unexpected `completed` event from peer that is not in swarm') |
250 | | - return start() // treat as a start |
251 | | - } |
252 | | - if (peer.complete) { |
253 | | - debug('unexpected `completed` event from peer that is already marked as completed') |
254 | | - return // do nothing |
255 | | - } |
256 | | - swarm.complete += 1 |
257 | | - swarm.incomplete -= 1 |
258 | | - peer.complete = true |
259 | | - self.emit('complete', params.addr) |
260 | | - } |
261 | | - |
262 | | - var update = function () { |
263 | | - if (!peer) { |
264 | | - debug('unexpected `update` event from peer that is not in swarm') |
265 | | - return start() // treat as a start |
266 | | - } |
267 | | - self.emit('update', params.addr) |
268 | | - } |
269 | | - |
270 | | - switch (params.event) { |
271 | | - case 'started': |
272 | | - start() |
273 | | - break |
274 | | - case 'stopped': |
275 | | - stop() |
276 | | - break |
277 | | - case 'completed': |
278 | | - complete() |
279 | | - break |
280 | | - case '': case undefined: case 'empty': case 'update': // update |
281 | | - update() |
282 | | - break |
283 | | - default: |
284 | | - return cb(new Error('invalid event')) // early return |
285 | | - } |
286 | | - |
287 | | - if (params.left === 0 && peer) peer.complete = true |
288 | | - |
289 | | - // send peers |
290 | | - var peers = params.compact === 1 |
291 | | - ? self._getPeersCompact(swarm, params.numwant) |
292 | | - : self._getPeers(swarm, params.numwant) |
293 | | - |
294 | | - cb(null, { |
295 | | - action: common.ACTIONS.ANNOUNCE, |
296 | | - complete: swarm.complete, |
297 | | - incomplete: swarm.incomplete, |
298 | | - peers: peers, |
299 | | - intervalMs: self._intervalMs |
| 220 | + cb(err, response) |
300 | 221 | }) |
301 | 222 | } |
302 | 223 |
|
@@ -324,46 +245,31 @@ Server.prototype._onScrape = function (params, cb) { |
324 | 245 | min_request_interval: self._intervalMs |
325 | 246 | } |
326 | 247 | } |
327 | | - |
328 | | - params.info_hash.some(function (infoHash) { |
| 248 | + |
| 249 | + series(params.info_hash.map(function (infoHash) { |
329 | 250 | var swarm = self.getSwarm(infoHash) |
330 | | - |
331 | | - response.files[infoHash] = { |
332 | | - complete: swarm.complete, |
333 | | - incomplete: swarm.incomplete, |
334 | | - downloaded: swarm.complete // TODO: this only provides a lower-bound |
| 251 | + return function (cb) { |
| 252 | + swarm.scrape(infoHash, params, function (err, scrapeInfo) { |
| 253 | + cb(err, scrapeInfo && { |
| 254 | + infoHash: infoHash, |
| 255 | + complete: scrapeInfo.complete || 0, |
| 256 | + incomplete: scrapeInfo.incomplete || 0 |
| 257 | + }) |
| 258 | + }) |
335 | 259 | } |
336 | | - }) |
337 | | - |
338 | | - cb(null, response) |
339 | | -} |
340 | | - |
341 | | -Server.prototype._getPeers = function (swarm, numwant) { |
342 | | - var peers = [] |
343 | | - for (var peerId in swarm.peers) { |
344 | | - if (peers.length >= numwant) break |
345 | | - var peer = swarm.peers[peerId] |
346 | | - if (!peer) continue // ignore null values |
347 | | - peers.push({ |
348 | | - 'peer id': peer.peerId, |
349 | | - ip: peer.ip, |
350 | | - port: peer.port |
| 260 | + }), function (err, results) { |
| 261 | + if (err) return cb(err) |
| 262 | + |
| 263 | + results.forEach(function (result) { |
| 264 | + response.files[result.infoHash] = { |
| 265 | + complete: result.complete, |
| 266 | + incomplete: result.incomplete, |
| 267 | + downloaded: result.complete // TODO: this only provides a lower-bound |
| 268 | + } |
351 | 269 | }) |
352 | | - } |
353 | | - return peers |
354 | | -} |
355 | 270 |
|
356 | | -Server.prototype._getPeersCompact = function (swarm, numwant) { |
357 | | - var peers = [] |
358 | | - |
359 | | - for (var peerId in swarm.peers) { |
360 | | - if (peers.length >= numwant) break |
361 | | - var peer = swarm.peers[peerId] |
362 | | - if (!peer) continue // ignore null values |
363 | | - peers.push(peer.ip + ':' + peer.port) |
364 | | - } |
365 | | - |
366 | | - return string2compact(peers) |
| 271 | + cb(null, response) |
| 272 | + }) |
367 | 273 | } |
368 | 274 |
|
369 | 275 |
|
|
0 commit comments