2023-05-26 18:54:30 +02:00
|
|
|
import { bin2hex } from 'uint8-util'
|
2014-12-11 12:53:39 -08:00
|
|
|
|
2023-05-26 18:54:30 +02:00
|
|
|
import common from '../common.js'
|
2014-12-10 00:44:45 +01:00
|
|
|
|
2023-05-26 18:54:30 +02:00
|
|
|
export default function (req, opts) {
|
2015-03-27 16:19:06 +13:00
|
|
|
if (!opts) opts = {}
|
2020-10-28 18:57:47 -10:00
|
|
|
const s = req.url.split('?')
|
|
|
|
|
const params = common.querystringParse(s[1])
|
2016-03-11 17:21:19 -08:00
|
|
|
params.type = 'http'
|
2014-12-10 00:44:45 +01:00
|
|
|
|
2015-03-27 16:19:06 +13:00
|
|
|
if (opts.action === 'announce' || s[0] === '/announce') {
|
2014-12-10 00:44:45 +01:00
|
|
|
params.action = common.ACTIONS.ANNOUNCE
|
2014-12-11 12:53:39 -08:00
|
|
|
|
2015-03-06 18:12:59 -08:00
|
|
|
if (typeof params.info_hash !== 'string' || params.info_hash.length !== 20) {
|
2014-12-12 02:02:11 -08:00
|
|
|
throw new Error('invalid info_hash')
|
2015-03-06 18:12:59 -08:00
|
|
|
}
|
2023-05-26 18:54:30 +02:00
|
|
|
params.info_hash = bin2hex(params.info_hash)
|
2015-03-27 16:19:06 +13:00
|
|
|
|
2015-03-06 18:12:59 -08:00
|
|
|
if (typeof params.peer_id !== 'string' || params.peer_id.length !== 20) {
|
2014-12-12 02:02:11 -08:00
|
|
|
throw new Error('invalid peer_id')
|
2015-03-06 18:12:59 -08:00
|
|
|
}
|
2023-05-26 18:54:30 +02:00
|
|
|
params.peer_id = bin2hex(params.peer_id)
|
2014-12-10 00:44:45 +01:00
|
|
|
|
2014-12-12 02:02:11 -08:00
|
|
|
params.port = Number(params.port)
|
2014-12-10 00:44:45 +01:00
|
|
|
if (!params.port) throw new Error('invalid port')
|
|
|
|
|
|
2016-12-03 21:07:26 -08:00
|
|
|
params.left = Number(params.left)
|
2017-02-02 17:23:46 -08:00
|
|
|
if (Number.isNaN(params.left)) params.left = Infinity
|
2016-12-03 21:07:26 -08:00
|
|
|
|
2015-03-27 16:19:06 +13:00
|
|
|
params.compact = Number(params.compact) || 0
|
2014-12-12 02:02:11 -08:00
|
|
|
params.numwant = Math.min(
|
2015-03-24 01:01:49 -07:00
|
|
|
Number(params.numwant) || common.DEFAULT_ANNOUNCE_PEERS,
|
2014-12-12 02:02:11 -08:00
|
|
|
common.MAX_ANNOUNCE_PEERS
|
|
|
|
|
)
|
2014-12-10 00:44:45 +01:00
|
|
|
|
2023-03-17 01:07:39 +00:00
|
|
|
if (opts.trustProxy) {
|
|
|
|
|
if (req.headers['x-forwarded-for']) {
|
|
|
|
|
const [realIp] = req.headers['x-forwarded-for'].split(',')
|
|
|
|
|
params.ip = realIp.trim()
|
|
|
|
|
} else {
|
|
|
|
|
params.ip = req.connection.remoteAddress
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
params.ip = req.connection.remoteAddress.replace(common.REMOVE_IPV4_MAPPED_IPV6_RE, '') // force ipv4
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-14 20:54:41 -05:00
|
|
|
params.addr = `${common.IPV6_RE.test(params.ip) ? `[${params.ip}]` : params.ip}:${params.port}`
|
2016-03-03 11:10:54 +01:00
|
|
|
|
|
|
|
|
params.headers = req.headers
|
2015-03-27 16:19:06 +13:00
|
|
|
} else if (opts.action === 'scrape' || s[0] === '/scrape') {
|
2014-12-10 00:44:45 +01:00
|
|
|
params.action = common.ACTIONS.SCRAPE
|
|
|
|
|
|
2019-07-05 14:36:14 -07:00
|
|
|
if (typeof params.info_hash === 'string') params.info_hash = [params.info_hash]
|
2014-12-12 02:02:11 -08:00
|
|
|
if (Array.isArray(params.info_hash)) {
|
2021-06-14 20:54:41 -05:00
|
|
|
params.info_hash = params.info_hash.map(binaryInfoHash => {
|
2015-03-06 18:12:59 -08:00
|
|
|
if (typeof binaryInfoHash !== 'string' || binaryInfoHash.length !== 20) {
|
2014-12-10 00:44:45 +01:00
|
|
|
throw new Error('invalid info_hash')
|
2015-03-06 18:12:59 -08:00
|
|
|
}
|
2023-05-26 18:54:30 +02:00
|
|
|
return bin2hex(binaryInfoHash)
|
2014-12-10 00:44:45 +01:00
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
} else {
|
2021-06-14 20:54:41 -05:00
|
|
|
throw new Error(`invalid action in HTTP request: ${req.url}`)
|
2014-12-10 00:44:45 +01:00
|
|
|
}
|
2014-12-12 02:02:11 -08:00
|
|
|
|
|
|
|
|
return params
|
2014-12-10 00:44:45 +01:00
|
|
|
}
|