I am trying to generate the info_hash of bittorent protocol for communicating with a tracker.
But I keep getting a invalid info_hash error. The issue seems to be at the urlencoded part of my code but I'm not sure.
I generate a sha1 of the bencoded metainfo.info and I use axios to send my announce.
Does axios further encode the param what's the best way to urlencode a 20bytes array?
Below my code:
const axios = require('axios').default;
const bencode = require('bencode');
const crypto = require('crypto');
const urlencode = require('urlencode');
class TrackerMessenger {
constructor(metainfo) {
this.url = metainfo.announce.toString();
this.info = this.unbufferer(metainfo.info);
// this.info = metainfo.info;
// console.log(this.info)
this.left = metainfo.info?.files?.length || metainfo.info?.length;
}
async announce(peer_id, hostinfos) {
const port = hostinfos.port;
const compact = 1;
const event = 'started';
const trackerid = undefined;
// console.log(encodeURIComponent(this.info_hash))
let hash = this.urlencode(this.info_hash);
const res = await axios.get(this.url, {
params: {
info_hash: hash,
peer_id,
port,
left: this.left,
compact,
event,
trackerid
}
});
console.log(res.data);
return res;
}
get info_hash() {
let info = bencode.encode(this.info).toString('utf8');
const info_hash = crypto.createHash('sha1').update(info, 'utf8').digest();
console.log(info_hash.length);
return info_hash;
}
unbufferer(obj) {
const unbuffered = {};
Object.entries(obj).forEach(entry => {
const [key, value] = entry;
unbuffered[key] = this.unbuffer(value);
});
return unbuffered;
}
unbuffer(value) {
let result = undefined;
if(value == undefined)
return result;
if(typeof value === 'object')
result = this.unbufferer(value);
else if(Array.isArray(value))
result = value.forEach(item => this.unbuffer(item));
else
result = (Buffer.isBuffer(value))? value.toString('utf8'): value;
return result;
}
urlencode(buffer) {
return urlencode(buffer);
}
}
module.exports = TrackerMessenger;