diff --git a/server.js b/server.js
index 1ec53da4..8d39ca99 100644
--- a/server.js
+++ b/server.js
@@ -136,147 +136,148 @@ class Server extends EventEmitter {
}
// Http handler for '/stats' route
- this.http.on('request', (req, res) => {
- if (res.headersSent) return
+ this.http.on('request', this.onStats);
+ }
+
+ let num = !!this.http + !!this.udp4 + !!this.udp6
+ const self = this
+ function onListening () {
+ num -= 1
+ if (num === 0) {
+ self.listening = true
+ debug('listening')
+ self.emit('listening')
+ }
+ }
+ }
- const infoHashes = Object.keys(this.torrents)
- let activeTorrents = 0
- const allPeers = {}
+ onStats = (req, res) => {
+ if (res.headersSent) return
- function countPeers (filterFunction) {
- let count = 0
- let key
+ const infoHashes = Object.keys(this.torrents)
+ let activeTorrents = 0
+ const allPeers = {}
- for (key in allPeers) {
- if (hasOwnProperty.call(allPeers, key) && filterFunction(allPeers[key])) {
- count++
- }
- }
+ function countPeers (filterFunction) {
+ let count = 0
+ let key
- return count
+ for (key in allPeers) {
+ if (hasOwnProperty.call(allPeers, key) && filterFunction(allPeers[key])) {
+ count++
}
+ }
- function groupByClient () {
- const clients = {}
- for (const key in allPeers) {
- if (hasOwnProperty.call(allPeers, key)) {
- const peer = allPeers[key]
-
- if (!clients[peer.client.client]) {
- clients[peer.client.client] = {}
- }
- const client = clients[peer.client.client]
- // If the client is not known show 8 chars from peerId as version
- const version = peer.client.version || Buffer.from(peer.peerId, 'hex').toString().substring(0, 8)
- if (!client[version]) {
- client[version] = 0
- }
- client[version]++
- }
+ return count
+ }
+
+ function groupByClient () {
+ const clients = {}
+ for (const key in allPeers) {
+ if (hasOwnProperty.call(allPeers, key)) {
+ const peer = allPeers[key]
+
+ if (!clients[peer.client.client]) {
+ clients[peer.client.client] = {}
+ }
+ const client = clients[peer.client.client]
+ // If the client is not known show 8 chars from peerId as version
+ const version = peer.client.version || Buffer.from(peer.peerId, 'hex').toString().substring(0, 8)
+ if (!client[version]) {
+ client[version] = 0
}
- return clients
+ client[version]++
}
+ }
+ return clients
+ }
- function printClients (clients) {
- let html = '
\n'
- for (const name in clients) {
- if (hasOwnProperty.call(clients, name)) {
- const client = clients[name]
- for (const version in client) {
- if (hasOwnProperty.call(client, version)) {
- html += `- ${name} ${version} : ${client[version]}
\n`
- }
- }
+ function printClients (clients) {
+ let html = '\n'
+ for (const name in clients) {
+ if (hasOwnProperty.call(clients, name)) {
+ const client = clients[name]
+ for (const version in client) {
+ if (hasOwnProperty.call(client, version)) {
+ html += `- ${name} ${version} : ${client[version]}
\n`
}
}
- html += '
'
- return html
}
+ }
+ html += '
'
+ return html
+ }
- if (req.method === 'GET' && (req.url === '/stats' || req.url === '/stats.json')) {
- infoHashes.forEach(infoHash => {
- const peers = this.torrents[infoHash].peers
- const keys = peers.keys
- if (keys.length > 0) activeTorrents++
-
- keys.forEach(peerId => {
- // Don't mark the peer as most recently used for stats
- const peer = peers.peek(peerId)
- if (peer == null) return // peers.peek() can evict the peer
-
- if (!hasOwnProperty.call(allPeers, peerId)) {
- allPeers[peerId] = {
- ipv4: false,
- ipv6: false,
- seeder: false,
- leecher: false
- }
- }
-
- if (peer.ip.includes(':')) {
- allPeers[peerId].ipv6 = true
- } else {
- allPeers[peerId].ipv4 = true
- }
-
- if (peer.complete) {
- allPeers[peerId].seeder = true
- } else {
- allPeers[peerId].leecher = true
- }
-
- allPeers[peerId].peerId = peer.peerId
- allPeers[peerId].client = peerid(peer.peerId)
- })
- })
+ if (req.method === 'GET' && (req.url === '/stats' || req.url === '/stats.json')) {
+ infoHashes.forEach(infoHash => {
+ const peers = this.torrents[infoHash].peers
+ const keys = peers.keys
+ if (keys.length > 0) activeTorrents++
+
+ keys.forEach(peerId => {
+ // Don't mark the peer as most recently used for stats
+ const peer = peers.peek(peerId)
+ if (peer == null) return // peers.peek() can evict the peer
+
+ if (!hasOwnProperty.call(allPeers, peerId)) {
+ allPeers[peerId] = {
+ ipv4: false,
+ ipv6: false,
+ seeder: false,
+ leecher: false
+ }
+ }
- const isSeederOnly = peer => { return peer.seeder && peer.leecher === false }
- const isLeecherOnly = peer => { return peer.leecher && peer.seeder === false }
- const isSeederAndLeecher = peer => { return peer.seeder && peer.leecher }
- const isIPv4 = peer => { return peer.ipv4 }
- const isIPv6 = peer => { return peer.ipv6 }
-
- const stats = {
- torrents: infoHashes.length,
- activeTorrents,
- peersAll: Object.keys(allPeers).length,
- peersSeederOnly: countPeers(isSeederOnly),
- peersLeecherOnly: countPeers(isLeecherOnly),
- peersSeederAndLeecher: countPeers(isSeederAndLeecher),
- peersIPv4: countPeers(isIPv4),
- peersIPv6: countPeers(isIPv6),
- clients: groupByClient()
+ if (peer.ip.includes(':')) {
+ allPeers[peerId].ipv6 = true
+ } else {
+ allPeers[peerId].ipv4 = true
}
- if (req.url === '/stats.json' || req.headers.accept === 'application/json') {
- res.setHeader('Content-Type', 'application/json')
- res.end(JSON.stringify(stats))
- } else if (req.url === '/stats') {
- res.setHeader('Content-Type', 'text/html')
- res.end(`
- ${stats.torrents} torrents (${stats.activeTorrents} active)
- Connected Peers: ${stats.peersAll}
- Peers Seeding Only: ${stats.peersSeederOnly}
- Peers Leeching Only: ${stats.peersLeecherOnly}
- Peers Seeding & Leeching: ${stats.peersSeederAndLeecher}
- IPv4 Peers: ${stats.peersIPv4}
- IPv6 Peers: ${stats.peersIPv6}
- Clients:
- ${printClients(stats.clients)}
- `.replace(/^\s+/gm, '')) // trim left
+ if (peer.complete) {
+ allPeers[peerId].seeder = true
+ } else {
+ allPeers[peerId].leecher = true
}
- }
+
+ allPeers[peerId].peerId = peer.peerId
+ allPeers[peerId].client = peerid(peer.peerId)
+ })
})
- }
- let num = !!this.http + !!this.udp4 + !!this.udp6
- const self = this
- function onListening () {
- num -= 1
- if (num === 0) {
- self.listening = true
- debug('listening')
- self.emit('listening')
+ const isSeederOnly = peer => { return peer.seeder && peer.leecher === false }
+ const isLeecherOnly = peer => { return peer.leecher && peer.seeder === false }
+ const isSeederAndLeecher = peer => { return peer.seeder && peer.leecher }
+ const isIPv4 = peer => { return peer.ipv4 }
+ const isIPv6 = peer => { return peer.ipv6 }
+
+ const stats = {
+ torrents: infoHashes.length,
+ activeTorrents,
+ peersAll: Object.keys(allPeers).length,
+ peersSeederOnly: countPeers(isSeederOnly),
+ peersLeecherOnly: countPeers(isLeecherOnly),
+ peersSeederAndLeecher: countPeers(isSeederAndLeecher),
+ peersIPv4: countPeers(isIPv4),
+ peersIPv6: countPeers(isIPv6),
+ clients: groupByClient()
+ }
+
+ if (req.url === '/stats.json' || req.headers.accept === 'application/json') {
+ res.write(JSON.stringify(stats))
+ res.end()
+ } else if (req.url === '/stats') {
+ res.end(`
+ ${stats.torrents} torrents (${stats.activeTorrents} active)
+ Connected Peers: ${stats.peersAll}
+ Peers Seeding Only: ${stats.peersSeederOnly}
+ Peers Leeching Only: ${stats.peersLeecherOnly}
+ Peers Seeding & Leeching: ${stats.peersSeederAndLeecher}
+ IPv4 Peers: ${stats.peersIPv4}
+ IPv6 Peers: ${stats.peersIPv6}
+ Clients:
+ ${printClients(stats.clients)}
+ `.replace(/^\s+/gm, '')) // trim left
}
}
}
@@ -363,6 +364,10 @@ class Server extends EventEmitter {
onHttpRequest (req, res, opts = {}) {
opts.trustProxy = opts.trustProxy || this._trustProxy
+ if (req.originalUrl === "/stats" || req.originalUrl === "/stats.json") {
+ return this.onStats(req, res);
+ }
+
let params
try {
params = parseHttpRequest(req, opts)