Skip to content

Commit b96c2c3

Browse files
committed
refactor: [#661] move HTTP Tracker Client mod
1 parent 0960ff2 commit b96c2c3

File tree

4 files changed

+105
-92
lines changed

4 files changed

+105
-92
lines changed

src/bin/http_tracker_client.rs

+3-92
Original file line numberDiff line numberDiff line change
@@ -1,96 +1,7 @@
1-
//! HTTP Tracker client:
2-
//!
3-
//! Examples:
4-
//!
5-
//! `Announce` request:
6-
//!
7-
//! ```text
8-
//! cargo run --bin http_tracker_client announce http://127.0.0.1:7070 9c38422213e30bff212b30c360d26f9a02136422 | jq
9-
//! ```
10-
//!
11-
//! `Scrape` request:
12-
//!
13-
//! ```text
14-
//! cargo run --bin http_tracker_client scrape http://127.0.0.1:7070 9c38422213e30bff212b30c360d26f9a02136422 | jq
15-
//! ```
16-
use std::str::FromStr;
17-
18-
use anyhow::Context;
19-
use clap::{Parser, Subcommand};
20-
use reqwest::Url;
21-
use torrust_tracker::shared::bit_torrent::info_hash::InfoHash;
22-
use torrust_tracker::shared::bit_torrent::tracker::http::client::requests::announce::QueryBuilder;
23-
use torrust_tracker::shared::bit_torrent::tracker::http::client::responses::announce::Announce;
24-
use torrust_tracker::shared::bit_torrent::tracker::http::client::responses::scrape;
25-
use torrust_tracker::shared::bit_torrent::tracker::http::client::{requests, Client};
26-
27-
#[derive(Parser, Debug)]
28-
#[command(author, version, about, long_about = None)]
29-
struct Args {
30-
#[command(subcommand)]
31-
command: Command,
32-
}
33-
34-
#[derive(Subcommand, Debug)]
35-
enum Command {
36-
Announce { tracker_url: String, info_hash: String },
37-
Scrape { tracker_url: String, info_hashes: Vec<String> },
38-
}
1+
//! Program to make request to HTTP trackers.
2+
use torrust_tracker::console::clients::http::app;
393

404
#[tokio::main]
415
async fn main() -> anyhow::Result<()> {
42-
let args = Args::parse();
43-
44-
match args.command {
45-
Command::Announce { tracker_url, info_hash } => {
46-
announce_command(tracker_url, info_hash).await?;
47-
}
48-
Command::Scrape {
49-
tracker_url,
50-
info_hashes,
51-
} => {
52-
scrape_command(&tracker_url, &info_hashes).await?;
53-
}
54-
}
55-
Ok(())
56-
}
57-
58-
async fn announce_command(tracker_url: String, info_hash: String) -> anyhow::Result<()> {
59-
let base_url = Url::parse(&tracker_url).context("failed to parse HTTP tracker base URL")?;
60-
let info_hash =
61-
InfoHash::from_str(&info_hash).expect("Invalid infohash. Example infohash: `9c38422213e30bff212b30c360d26f9a02136422`");
62-
63-
let response = Client::new(base_url)
64-
.announce(&QueryBuilder::with_default_values().with_info_hash(&info_hash).query())
65-
.await;
66-
67-
let body = response.bytes().await.unwrap();
68-
69-
let announce_response: Announce = serde_bencode::from_bytes(&body)
70-
.unwrap_or_else(|_| panic!("response body should be a valid announce response, got: \"{:#?}\"", &body));
71-
72-
let json = serde_json::to_string(&announce_response).context("failed to serialize scrape response into JSON")?;
73-
74-
println!("{json}");
75-
76-
Ok(())
77-
}
78-
79-
async fn scrape_command(tracker_url: &str, info_hashes: &[String]) -> anyhow::Result<()> {
80-
let base_url = Url::parse(tracker_url).context("failed to parse HTTP tracker base URL")?;
81-
82-
let query = requests::scrape::Query::try_from(info_hashes).context("failed to parse infohashes")?;
83-
84-
let response = Client::new(base_url).scrape(&query).await;
85-
86-
let body = response.bytes().await.unwrap();
87-
88-
let scrape_response = scrape::Response::try_from_bencoded(&body)
89-
.unwrap_or_else(|_| panic!("response body should be a valid scrape response, got: \"{:#?}\"", &body));
90-
91-
let json = serde_json::to_string(&scrape_response).context("failed to serialize scrape response into JSON")?;
92-
93-
println!("{json}");
94-
95-
Ok(())
6+
app::run().await
967
}

src/console/clients/http/app.rs

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
//! HTTP Tracker client:
2+
//!
3+
//! Examples:
4+
//!
5+
//! `Announce` request:
6+
//!
7+
//! ```text
8+
//! cargo run --bin http_tracker_client announce http://127.0.0.1:7070 9c38422213e30bff212b30c360d26f9a02136422 | jq
9+
//! ```
10+
//!
11+
//! `Scrape` request:
12+
//!
13+
//! ```text
14+
//! cargo run --bin http_tracker_client scrape http://127.0.0.1:7070 9c38422213e30bff212b30c360d26f9a02136422 | jq
15+
//! ```
16+
use std::str::FromStr;
17+
18+
use anyhow::Context;
19+
use clap::{Parser, Subcommand};
20+
use reqwest::Url;
21+
22+
use crate::shared::bit_torrent::info_hash::InfoHash;
23+
use crate::shared::bit_torrent::tracker::http::client::requests::announce::QueryBuilder;
24+
use crate::shared::bit_torrent::tracker::http::client::responses::announce::Announce;
25+
use crate::shared::bit_torrent::tracker::http::client::responses::scrape;
26+
use crate::shared::bit_torrent::tracker::http::client::{requests, Client};
27+
28+
#[derive(Parser, Debug)]
29+
#[command(author, version, about, long_about = None)]
30+
struct Args {
31+
#[command(subcommand)]
32+
command: Command,
33+
}
34+
35+
#[derive(Subcommand, Debug)]
36+
enum Command {
37+
Announce { tracker_url: String, info_hash: String },
38+
Scrape { tracker_url: String, info_hashes: Vec<String> },
39+
}
40+
41+
/// # Errors
42+
///
43+
/// Will return an error if the command fails.
44+
pub async fn run() -> anyhow::Result<()> {
45+
let args = Args::parse();
46+
47+
match args.command {
48+
Command::Announce { tracker_url, info_hash } => {
49+
announce_command(tracker_url, info_hash).await?;
50+
}
51+
Command::Scrape {
52+
tracker_url,
53+
info_hashes,
54+
} => {
55+
scrape_command(&tracker_url, &info_hashes).await?;
56+
}
57+
}
58+
59+
Ok(())
60+
}
61+
62+
async fn announce_command(tracker_url: String, info_hash: String) -> anyhow::Result<()> {
63+
let base_url = Url::parse(&tracker_url).context("failed to parse HTTP tracker base URL")?;
64+
let info_hash =
65+
InfoHash::from_str(&info_hash).expect("Invalid infohash. Example infohash: `9c38422213e30bff212b30c360d26f9a02136422`");
66+
67+
let response = Client::new(base_url)
68+
.announce(&QueryBuilder::with_default_values().with_info_hash(&info_hash).query())
69+
.await;
70+
71+
let body = response.bytes().await.unwrap();
72+
73+
let announce_response: Announce = serde_bencode::from_bytes(&body)
74+
.unwrap_or_else(|_| panic!("response body should be a valid announce response, got: \"{:#?}\"", &body));
75+
76+
let json = serde_json::to_string(&announce_response).context("failed to serialize scrape response into JSON")?;
77+
78+
println!("{json}");
79+
80+
Ok(())
81+
}
82+
83+
async fn scrape_command(tracker_url: &str, info_hashes: &[String]) -> anyhow::Result<()> {
84+
let base_url = Url::parse(tracker_url).context("failed to parse HTTP tracker base URL")?;
85+
86+
let query = requests::scrape::Query::try_from(info_hashes).context("failed to parse infohashes")?;
87+
88+
let response = Client::new(base_url).scrape(&query).await;
89+
90+
let body = response.bytes().await.unwrap();
91+
92+
let scrape_response = scrape::Response::try_from_bencoded(&body)
93+
.unwrap_or_else(|_| panic!("response body should be a valid scrape response, got: \"{:#?}\"", &body));
94+
95+
let json = serde_json::to_string(&scrape_response).context("failed to serialize scrape response into JSON")?;
96+
97+
println!("{json}");
98+
99+
Ok(())
100+
}

src/console/clients/http/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub mod app;

src/console/clients/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
//! Console clients.
22
pub mod checker;
3+
pub mod http;

0 commit comments

Comments
 (0)