diff options
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | lib/torrent.js | 4 | ||||
-rw-r--r-- | test/blocklist-dht.js | 8 | ||||
-rw-r--r-- | test/blocklist.js | 268 | ||||
-rw-r--r-- | test/content/blocklist.txt | 2 | ||||
-rw-r--r-- | test/download-dht-magnet.js | 8 | ||||
-rw-r--r-- | test/download-dht-torrent.js | 8 |
7 files changed, 287 insertions, 13 deletions
@@ -339,6 +339,8 @@ Alias for `client.remove(torrent)`. Adds a peer to the underlying [bittorrent-swarm](https://github.com/feross/bittorrent-swarm) instance. +Returns `true` if peer was added, `false` if peer was blocked by the loaded blocklist. + #### `torrent.select(start, end, [priority], [notify])` Selects a range of pieces to prioritize starting with `start` and ending with `end` (both inclusive) diff --git a/lib/torrent.js b/lib/torrent.js index 9f6edde..bf110f9 100644 --- a/lib/torrent.js +++ b/lib/torrent.js @@ -326,19 +326,21 @@ Torrent.prototype.destroy = function (cb) { /** * Add a peer to the swarm * @param {string|SimplePeer} peer + * @return {boolean} true if peer was added, false if peer was blocked */ Torrent.prototype.addPeer = function (peer) { var self = this - // TODO: extract IP address from peer object and check blocklist if (typeof peer === 'string' && self.client.blocked && self.client.blocked.contains(addrToIPPort(peer)[0])) { self.numBlockedPeers += 1 self.emit('blocked-peer', peer) + return false } else { self.emit('peer', peer) self.swarm.addPeer(peer) + return true } } diff --git a/test/blocklist-dht.js b/test/blocklist-dht.js index b48d200..33b0805 100644 --- a/test/blocklist-dht.js +++ b/test/blocklist-dht.js @@ -8,13 +8,13 @@ var WebTorrent = require('../') var leavesTorrent = fs.readFileSync(__dirname + '/torrents/leaves.torrent') var leavesParsed = parseTorrent(leavesTorrent) +// remove trackers from .torrent file +leavesParsed.announce = [] +leavesParsed.announceList = [] + test('blocklist blocks peers discovered via DHT', function (t) { t.plan(6) - // remove trackers from .torrent file - leavesParsed.announce = [] - leavesParsed.announceList = [] - var dhtServer = new DHT({ bootstrap: false }) dhtServer.on('error', function (err) { diff --git a/test/blocklist.js b/test/blocklist.js new file mode 100644 index 0000000..5ae6950 --- /dev/null +++ b/test/blocklist.js @@ -0,0 +1,268 @@ +var http = require('http') +var fs = require('fs') +var parseTorrent = require('parse-torrent') +var portfinder = require('portfinder') +var test = require('tape') +var WebTorrent = require('../') +var zlib = require('zlib') + +var blocklistPath = __dirname + '/content/blocklist.txt' +var blocklistGzipPath = __dirname + '/content/blocklist.txt.gz' + +var leavesTorrent = fs.readFileSync(__dirname + '/torrents/leaves.torrent') +var leavesParsed = parseTorrent(leavesTorrent) + +// remove trackers from .torrent file +leavesParsed.announce = [] +leavesParsed.announceList = [] + +function assertBlocked (t, torrent, addr) { + torrent.once('blocked-peer', function (_addr) { + t.equal(addr, _addr) + }) + t.notOk(torrent.addPeer(addr)) +} + +function assertReachable (t, torrent, addr) { + torrent.once('peer', function (_addr) { + t.equal(addr, _addr) + }) + t.ok(torrent.addPeer(addr)) +} + +test('blocklist (single IP)', function (t) { + t.plan(8) + + var client = new WebTorrent({ + dht: false, + tracker: false, + blocklist: [ '1.2.3.4' ] + }) + .on('error', function (err) { t.fail(err) }) + .on('ready', function () { + var torrent = client.add(leavesParsed) + + assertBlocked(t, torrent, '1.2.3.4:1234') + assertBlocked(t, torrent, '1.2.3.4:6969') + assertReachable(t, torrent, '1.1.1.1:1234') + assertReachable(t, torrent, '1.1.1.1:6969') + + client.destroy() + }) +}) + +test('blocklist (array of IPs)', function (t) { + t.plan(12) + + var client = new WebTorrent({ + dht: false, + tracker: false, + blocklist: [ '1.2.3.4', '5.6.7.8' ] + }) + .on('error', function (err) { t.fail(err) }) + .on('ready', function () { + var torrent = client.add(leavesParsed) + + assertBlocked(t, torrent, '1.2.3.4:1234') + assertBlocked(t, torrent, '1.2.3.4:6969') + assertBlocked(t, torrent, '5.6.7.8:1234') + assertBlocked(t, torrent, '5.6.7.8:6969') + assertReachable(t, torrent, '1.1.1.1:1234') + assertReachable(t, torrent, '1.1.1.1:6969') + + client.destroy() + }) +}) + +// 48 asserts +function assertList (t, torrent) { + assertBlocked(t, torrent, '1.2.3.0:1234') + assertBlocked(t, torrent, '1.2.3.0:6969') + + assertBlocked(t, torrent, '1.2.3.1:1234') + assertBlocked(t, torrent, '1.2.3.1:6969') + + assertBlocked(t, torrent, '1.2.3.1:1234') + assertBlocked(t, torrent, '1.2.3.1:6969') + + assertBlocked(t, torrent, '1.2.3.254:1234') + assertBlocked(t, torrent, '1.2.3.254:6969') + + assertBlocked(t, torrent, '1.2.3.255:1234') + assertBlocked(t, torrent, '1.2.3.255:6969') + + assertBlocked(t, torrent, '5.6.7.0:1234') + assertBlocked(t, torrent, '5.6.7.0:6969') + + assertBlocked(t, torrent, '5.6.7.128:1234') + assertBlocked(t, torrent, '5.6.7.128:6969') + + assertBlocked(t, torrent, '5.6.7.255:1234') + assertBlocked(t, torrent, '5.6.7.255:6969') + + assertReachable(t, torrent, '1.1.1.1:1234') + assertReachable(t, torrent, '1.1.1.1:6969') + + assertReachable(t, torrent, '2.2.2.2:1234') + assertReachable(t, torrent, '2.2.2.2:6969') + + assertReachable(t, torrent, '1.2.4.0:1234') + assertReachable(t, torrent, '1.2.4.0:6969') + + assertReachable(t, torrent, '1.2.2.0:1234') + assertReachable(t, torrent, '1.2.2.0:6969') +} + +test('blocklist (array of IP ranges)', function (t) { + t.plan(48) + var client = new WebTorrent({ + dht: false, + tracker: false, + blocklist: [ + { start: '1.2.3.0', end: '1.2.3.255' }, + { start: '5.6.7.0', end: '5.6.7.255' } + ] + }) + .on('error', function (err) { t.fail(err) }) + .on('ready', function () { + var torrent = client.add(leavesParsed) + + assertList(t, torrent) + + client.destroy() + }) +}) + +test('blocklist (http url)', function (t) { + t.plan(49) + var server = http.createServer(function (req, res) { + // Check that WebTorrent declares a user agent + t.equal(req.headers['user-agent'], 'WebTorrent (http://webtorrent.io)') + + fs.createReadStream(blocklistPath) + .pipe(res) + }) + portfinder.getPort(function (err, port) { + if (err) throw err + var url = 'http://127.0.0.1:' + port + + server.listen(port, function () { + var client = new WebTorrent({ + dht: false, + tracker: false, + blocklist: url + }) + .on('error', function (err) { t.fail(err) }) + .on('ready', function () { + var torrent = client.add(leavesParsed) + + assertList(t, torrent) + + client.destroy() + server.close() + }) + }) + }) +}) + +test('blocklist (http url with gzip encoding)', function (t) { + t.plan(49) + var server = http.createServer(function (req, res) { + // Check that WebTorrent declares a user agent + t.equal(req.headers['user-agent'], 'WebTorrent (http://webtorrent.io)') + + res.setHeader('content-encoding', 'gzip') + fs.createReadStream(blocklistPath) + .pipe(zlib.createGzip()) + .pipe(res) + }) + portfinder.getPort(function (err, port) { + if (err) throw err + var url = 'http://127.0.0.1:' + port + + server.listen(port, function () { + var client = new WebTorrent({ + dht: false, + tracker: false, + blocklist: url + }) + .on('error', function (err) { t.fail(err) }) + .on('ready', function () { + var torrent = client.add(leavesParsed) + + assertList(t, torrent) + + client.destroy() + server.close() + }) + }) + }) +}) + +test('blocklist (http url with deflate encoding)', function (t) { + t.plan(49) + var server = http.createServer(function (req, res) { + // Check that WebTorrent declares a user agent + t.equal(req.headers['user-agent'], 'WebTorrent (http://webtorrent.io)') + + res.setHeader('content-encoding', 'deflate') + fs.createReadStream(blocklistPath) + .pipe(zlib.createDeflate()) + .pipe(res) + }) + portfinder.getPort(function (err, port) { + if (err) throw err + var url = 'http://127.0.0.1:' + port + + server.listen(port, function () { + var client = new WebTorrent({ + dht: false, + tracker: false, + blocklist: url + }) + .on('error', function (err) { t.fail(err) }) + .on('ready', function () { + var torrent = client.add(leavesParsed) + + assertList(t, torrent) + + client.destroy() + server.close() + }) + }) + }) +}) + +test('blocklist (fs path)', function (t) { + t.plan(48) + var client = new WebTorrent({ + dht: false, + tracker: false, + blocklist: blocklistPath + }) + .on('error', function (err) { t.fail(err) }) + .on('ready', function () { + var torrent = client.add(leavesParsed) + + assertList(t, torrent) + + client.destroy() + }) +}) + +test('blocklist (fs path with gzip)', function (t) { + t.plan(48) + var client = new WebTorrent({ + dht: false, + tracker: false, + blocklist: blocklistGzipPath + }) + .on('error', function (err) { t.fail(err) }) + .on('ready', function () { + var torrent = client.add(leavesParsed) + + assertList(t, torrent) + + client.destroy() + }) +}) diff --git a/test/content/blocklist.txt b/test/content/blocklist.txt new file mode 100644 index 0000000..167627d --- /dev/null +++ b/test/content/blocklist.txt @@ -0,0 +1,2 @@ +Blah blah description:1.2.3.0-1.2.3.255 +Blah blah different description:5.6.7.0-5.6.7.255 diff --git a/test/download-dht-magnet.js b/test/download-dht-magnet.js index f76a8de..1a0b3bc 100644 --- a/test/download-dht-magnet.js +++ b/test/download-dht-magnet.js @@ -9,13 +9,13 @@ var leavesFile = __dirname + '/content/Leaves of Grass by Walt Whitman.epub' var leavesTorrent = fs.readFileSync(__dirname + '/torrents/leaves.torrent') var leavesParsed = parseTorrent(leavesTorrent) +// remove trackers from .torrent file +leavesParsed.announce = [] +leavesParsed.announceList = [] + test('Download using DHT (via magnet uri)', function (t) { t.plan(7) - // remove trackers from .torrent file - leavesParsed.announce = [] - leavesParsed.announceList = [] - var dhtServer = new DHT({ bootstrap: false }) dhtServer.on('error', function (err) { t.fail(err) diff --git a/test/download-dht-torrent.js b/test/download-dht-torrent.js index 74f8971..19b998e 100644 --- a/test/download-dht-torrent.js +++ b/test/download-dht-torrent.js @@ -9,13 +9,13 @@ var leavesFile = __dirname + '/content/Leaves of Grass by Walt Whitman.epub' var leavesTorrent = fs.readFileSync(__dirname + '/torrents/leaves.torrent') var leavesParsed = parseTorrent(leavesTorrent) +// remove trackers from .torrent file +leavesParsed.announce = [] +leavesParsed.announceList = [] + test('Download using DHT (via .torrent file)', function (t) { t.plan(7) - // remove trackers from .torrent file - leavesParsed.announce = [] - leavesParsed.announceList = [] - var dhtServer = new DHT({ bootstrap: false }) dhtServer.on('error', function (err) { |