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
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
},
"dependencies": {
"bencode": "^0.10.0",
"bittorrent-peerid": "^1.0.2",
"bn.js": "^4.4.0",
"compact2string": "^1.2.0",
"debug": "^2.0.0",
Expand Down
48 changes: 46 additions & 2 deletions server.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ var dgram = require('dgram')
var EventEmitter = require('events').EventEmitter
var http = require('http')
var inherits = require('inherits')
var peerid = require('bittorrent-peerid')
var series = require('run-series')
var string2compact = require('string2compact')
var WebSocketServer = require('ws').Server
Expand Down Expand Up @@ -150,6 +151,43 @@ function Server (opts) {
return count
}

function groupByClient () {
var clients = {}
for (var key in allPeers) {
if (allPeers.hasOwnProperty(key)) {
var peer = allPeers[key]

if (!clients[peer.client.client]) {
clients[peer.client.client] = {}
}
var client = clients[peer.client.client]
// If the client is not known show 8 chars from peerId as version
var version = peer.client.version || new Buffer(peer.peerId, 'hex').toString().substring(0, 8)
if (!client[version]) {
client[version] = 0
}
client[version]++
}
}
return clients
}

function printClients (clients) {
var html = '<ul>\n'
for (var name in clients) {
if (clients.hasOwnProperty(name)) {
var client = clients[name]
for (var version in client) {
if (client.hasOwnProperty(version)) {
html += '<li><strong>' + name + '</strong> ' + version + ' : ' + client[version] + '</li>\n'
}
}
}
}
html += '</ul>'
return html
}

if (req.method === 'GET' && (req.url === '/stats' || req.url === '/stats.json')) {
infoHashes.forEach(function (infoHash) {
var peers = self.torrents[infoHash].peers
Expand All @@ -176,6 +214,8 @@ function Server (opts) {
} else {
allPeers[peerId].leecher = true
}
allPeers[peerId].peerId = peer.peerId
allPeers[peerId].client = peerid(peer.peerId)
})
})

Expand All @@ -193,7 +233,8 @@ function Server (opts) {
peersLeecherOnly: countPeers(isLeecherOnly),
peersSeederAndLeecher: countPeers(isSeederAndLeecher),
peersIPv4: countPeers(isIPv4),
peersIPv6: countPeers(isIPv6)
peersIPv6: countPeers(isIPv6),
clients: groupByClient()
}

if (req.url === '/stats.json' || req.headers['content-type'] === 'application/json') {
Expand All @@ -206,7 +247,10 @@ function Server (opts) {
'<h3>Peers Leeching Only: ' + stats.peersLeecherOnly + '</h3>\n' +
'<h3>Peers Seeding & Leeching: ' + stats.peersSeederAndLeecher + '</h3>\n' +
'<h3>IPv4 Peers: ' + stats.peersIPv4 + '</h3>\n' +
'<h3>IPv6 Peers: ' + stats.peersIPv6 + '</h3>\n')
'<h3>IPv6 Peers: ' + stats.peersIPv6 + '</h3>\n' +
'<h3>Clients:</h3>\n' +
printClients(stats.clients)
)
}
}
})
Expand Down
52 changes: 48 additions & 4 deletions test/stats.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,18 @@ var fixtures = require('webtorrent-fixtures')
var get = require('simple-get')
var test = require('tape')

var peerId = Buffer.from('01234567890123456789')
var peerId = Buffer.from('-WW0091-4ea5886ce160')
var unknownPeerId = Buffer.from('01234567890123456789')

function parseHtml (html) {
var extractValue = new RegExp('[^v^h](\\d+)')
var array = html.replace('torrents', '\n').split('\n').filter(function (line) {
return line && line.trim().length > 0
}).map(function (line) {
var a = extractValue.exec(line)
return parseInt(a[1])
if (a) {
return parseInt(a[1])
}
})
var i = 0
return {
Expand Down Expand Up @@ -111,7 +114,7 @@ test('server: get empty stats on stats.json', function (t) {
})

test('server: get leecher stats.json', function (t) {
t.plan(10)
t.plan(11)

commonTest.createServer(t, 'http', function (server, announceUrl) {
// announce a torrent to the tracker
Expand All @@ -134,7 +137,6 @@ test('server: get leecher stats.json', function (t) {

get.concat(opts, function (err, res, stats) {
t.error(err)
console.log(stats)

t.equal(res.statusCode, 200)
t.equal(stats.torrents, 1)
Expand All @@ -143,6 +145,48 @@ test('server: get leecher stats.json', function (t) {
t.equal(stats.peersSeederOnly, 0)
t.equal(stats.peersLeecherOnly, 1)
t.equal(stats.peersSeederAndLeecher, 0)
t.equal(stats.clients['WebTorrent']['0.0.9.1'], 1)

client.destroy(function () { t.pass('client destroyed') })
server.close(function () { t.pass('server closed') })
})
})
})
})

test('server: get leecher stats.json (unknown peerId)', function (t) {
t.plan(11)

commonTest.createServer(t, 'http', function (server, announceUrl) {
// announce a torrent to the tracker
var client = new Client({
infoHash: fixtures.leaves.parsedTorrent.infoHash,
announce: announceUrl,
peerId: unknownPeerId,
port: 6881
})
client.on('error', function (err) { t.error(err) })
client.on('warning', function (err) { t.error(err) })

client.start()

server.once('start', function () {
var opts = {
url: announceUrl.replace('/announce', '/stats.json'),
json: true
}

get.concat(opts, function (err, res, stats) {
t.error(err)

t.equal(res.statusCode, 200)
t.equal(stats.torrents, 1)
t.equal(stats.activeTorrents, 1)
t.equal(stats.peersAll, 1)
t.equal(stats.peersSeederOnly, 0)
t.equal(stats.peersLeecherOnly, 1)
t.equal(stats.peersSeederAndLeecher, 0)
t.equal(stats.clients['unknown']['01234567'], 1)

client.destroy(function () { t.pass('client destroyed') })
server.close(function () { t.pass('server closed') })
Expand Down