Successful tracker communication

This commit is contained in:
Fabian 2024-07-27 22:22:05 +02:00
parent 5ca91ed6cb
commit 22f4b576b7
3 changed files with 53 additions and 4 deletions

View File

@ -6,6 +6,9 @@ edition = "2021"
[dependencies]
anyhow = "1.0.86"
sha1 = "0.10.6"
reqwest = { version = "0.12.5", features = ["blocking"] }
rand = "0.8.5"
urlencoding = "2.1.3"
[dev-dependencies]
hex-literal = "0.4.1"

View File

@ -5,7 +5,7 @@ use anyhow::{anyhow, ensure, Result};
use sha1::{Digest, Sha1};
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone)]
pub struct ByteString(Vec<u8>);
impl Display for ByteString {
@ -91,8 +91,12 @@ impl Bencode {
}
Bencode::Dict(d) => {
let mut result = vec!['d' as u8];
for (k, v) in d {
let mut sorted_keys = d.keys().collect::<Vec<_>>();
sorted_keys.sort();
for k in sorted_keys {
result.extend(Self::compose(&Bencode::Bytes(k.clone())));
let v = &d[k];
result.extend(v.compose());
}
result.push('e' as u8);
@ -110,7 +114,8 @@ impl Bencode {
pub fn sha1(&self) -> [u8; 20] {
let mut hasher = Sha1::new();
hasher.update(self.compose());
let composed = self.compose();
hasher.update(composed);
hasher.finalize().into()
}

View File

@ -2,6 +2,9 @@ use std::{env, fs, path};
use std::collections::HashMap;
use anyhow::{anyhow, Result};
use rand::prelude::*;
use reqwest::blocking::Client;
use reqwest::Url;
use crate::bencode::{Bencode, ByteString};
@ -177,7 +180,45 @@ fn main() -> Result<()> {
let torrent = Torrent::from(&torrent_parsed)?;
println!("torrent decoded: {torrent:?}");
// println!("torrent decoded: {torrent:?}");
let torrent_length= torrent.info.length.unwrap_or(
torrent.info.files.unwrap().iter().map(|x| x.length).sum()
);
let mut peer_id= [0u8; 20];
thread_rng().fill_bytes(&mut peer_id);
println!("Generated peer id: {}",
peer_id.iter().map(|x| {format!("{x:02x}")}).collect::<Vec<_>>().join(""));
println!("Making request to tracker");
println!("info hash: {}", torrent.info_hash.iter().map(|x| {format!("{x:02x}")}).collect::<Vec<_>>().join(""));
let mut url = Url::parse(&torrent.announce)?;
url.query_pairs_mut()
.append_pair("port", "6885")
.append_pair("uploaded", "0")
.append_pair("downloaded", "0")
.append_pair("compact", "1")
.append_pair("left", &format!("{torrent_length}"));
let mut query = url.query().unwrap().to_string();
query = format!("{query}&peer_id={}&info_hash={}",
urlencoding::encode_binary(&peer_id[..]),
urlencoding::encode_binary(&torrent.info_hash[..]));
url.set_query(Some(&query));
println!("url: {}", url);
let client = Client::new();
let resp = client.get(url).send()?;
let status = resp.status();
let body = resp.text()?;
println!("Response: {} {}", status, body);
Ok(())
}