Compare commits
2 Commits
5ca91ed6cb
...
ca70aa3815
Author | SHA1 | Date | |
---|---|---|---|
ca70aa3815 | |||
22f4b576b7 |
2
.gitignore
vendored
2
.gitignore
vendored
@ -99,7 +99,7 @@ target/
|
|||||||
|
|
||||||
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
|
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
|
||||||
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
|
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
|
||||||
Cargo.lock
|
#Cargo.lock
|
||||||
|
|
||||||
# These are backup files generated by rustfmt
|
# These are backup files generated by rustfmt
|
||||||
**/*.rs.bk
|
**/*.rs.bk
|
||||||
|
1434
Cargo.lock
generated
Normal file
1434
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -6,6 +6,9 @@ edition = "2021"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0.86"
|
anyhow = "1.0.86"
|
||||||
sha1 = "0.10.6"
|
sha1 = "0.10.6"
|
||||||
|
reqwest = { version = "0.12.5", features = ["blocking"] }
|
||||||
|
rand = "0.8.5"
|
||||||
|
urlencoding = "2.1.3"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
hex-literal = "0.4.1"
|
hex-literal = "0.4.1"
|
||||||
|
@ -5,7 +5,7 @@ use anyhow::{anyhow, ensure, Result};
|
|||||||
use sha1::{Digest, Sha1};
|
use sha1::{Digest, Sha1};
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
|
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone)]
|
||||||
pub struct ByteString(Vec<u8>);
|
pub struct ByteString(Vec<u8>);
|
||||||
|
|
||||||
impl Display for ByteString {
|
impl Display for ByteString {
|
||||||
@ -91,8 +91,12 @@ impl Bencode {
|
|||||||
}
|
}
|
||||||
Bencode::Dict(d) => {
|
Bencode::Dict(d) => {
|
||||||
let mut result = vec!['d' as u8];
|
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())));
|
result.extend(Self::compose(&Bencode::Bytes(k.clone())));
|
||||||
|
let v = &d[k];
|
||||||
result.extend(v.compose());
|
result.extend(v.compose());
|
||||||
}
|
}
|
||||||
result.push('e' as u8);
|
result.push('e' as u8);
|
||||||
@ -110,7 +114,8 @@ impl Bencode {
|
|||||||
pub fn sha1(&self) -> [u8; 20] {
|
pub fn sha1(&self) -> [u8; 20] {
|
||||||
let mut hasher = Sha1::new();
|
let mut hasher = Sha1::new();
|
||||||
|
|
||||||
hasher.update(self.compose());
|
let composed = self.compose();
|
||||||
|
hasher.update(composed);
|
||||||
|
|
||||||
hasher.finalize().into()
|
hasher.finalize().into()
|
||||||
}
|
}
|
||||||
|
43
src/main.rs
43
src/main.rs
@ -2,6 +2,9 @@ use std::{env, fs, path};
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
|
use rand::prelude::*;
|
||||||
|
use reqwest::blocking::Client;
|
||||||
|
use reqwest::Url;
|
||||||
|
|
||||||
use crate::bencode::{Bencode, ByteString};
|
use crate::bencode::{Bencode, ByteString};
|
||||||
|
|
||||||
@ -177,7 +180,45 @@ fn main() -> Result<()> {
|
|||||||
|
|
||||||
let torrent = Torrent::from(&torrent_parsed)?;
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user