You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
94 lines
2.5 KiB
94 lines
2.5 KiB
const got = require('got')
|
|
const cacheManager = require('cache-manager')
|
|
const querystring = require('querystring')
|
|
const pkg = require('../package.json')
|
|
const addSeconds = require('date-fns/add_seconds')
|
|
|
|
class Onionoo {
|
|
|
|
// Constructor returns a new object so instance properties are private
|
|
constructor (options = {}) {
|
|
// Set default options
|
|
this.options = Object.assign({}, {
|
|
baseUrl: 'https://onionoo.torproject.org',
|
|
endpoints: [
|
|
'summary',
|
|
'details',
|
|
'bandwidth',
|
|
'weights',
|
|
'clients',
|
|
'uptime'
|
|
]
|
|
}, options)
|
|
if (options.cache !== false) {
|
|
this.options.cache = cacheManager.caching(Object.assign({}, {
|
|
store: 'memory',
|
|
max: 500
|
|
}, options.cache))
|
|
}
|
|
|
|
// Return object containing endpoint methods
|
|
return this.options.endpoints.reduce((onionoo, endpoint) => {
|
|
onionoo[endpoint] = this.createEndpointMethod(endpoint)
|
|
|
|
return onionoo
|
|
}, {})
|
|
}
|
|
|
|
// Returns expirey date from response headers
|
|
expires (headers) {
|
|
const originDate = new Date(headers.date)
|
|
|
|
// Get max age ms
|
|
let maxAge = headers['cache-control'] && headers['cache-control'].match(/max-age=(\d+)/)
|
|
maxAge = parseInt(maxAge ? maxAge[1] : 0)
|
|
|
|
// Calculate expirey date
|
|
return addSeconds(new Date(originDate), maxAge)
|
|
}
|
|
|
|
// Returns a function to make requests to a given endpoint
|
|
createEndpointMethod (endpoint) {
|
|
return options => {
|
|
// Build query string (don't encode ':' for search filters)
|
|
const qs = querystring.encode(options).replace(/%3A/g, ':')
|
|
|
|
// Build url
|
|
const url = `${this.options.baseUrl}/${endpoint}?${qs}`
|
|
|
|
// Check for url in cache
|
|
if (this.options.cache) {
|
|
return this.options.cache.get(url).then(cachedResult => cachedResult || this.makeRequest(url))
|
|
} else {
|
|
return this.makeRequest(url)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Returns a promise for a request
|
|
makeRequest (url) {
|
|
const options = {
|
|
headers: {
|
|
'user-agent': `onionoo-node-client v${pkg.version} (${pkg.homepage})`
|
|
}
|
|
}
|
|
return got(url, options)
|
|
.then(response => {
|
|
// Format response
|
|
response = {
|
|
statusCode: response.statusCode,
|
|
statusMessage: response.statusMessage,
|
|
headers: response.headers,
|
|
body: JSON.parse(response.body)
|
|
}
|
|
|
|
// Cache response
|
|
this.options.cache && this.options.cache.set(url, response)
|
|
|
|
// Resolve response
|
|
return response
|
|
})
|
|
}
|
|
}
|
|
|
|
module.exports = Onionoo
|
|
|