Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add timeouts to Tracker API Client requests #483

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 26 additions & 31 deletions src/tracker/api.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use std::time::Duration;

use reqwest::{Error, Response};
pub struct ConnectionInfo {
/// The URL of the tracker. Eg: <https://tracker:7070> or <udp://tracker:6969>
/// The URL of the tracker API. Eg: <https://tracker:1212>.
pub url: String,
/// The token used to authenticate with the tracker API.
pub token: String,
Expand All @@ -15,17 +17,26 @@ impl ConnectionInfo {

pub struct Client {
pub connection_info: ConnectionInfo,
base_url: String,
api_base_url: String,
client: reqwest::Client,
token_param: [(String, String); 1],
}

impl Client {
#[must_use]
pub fn new(connection_info: ConnectionInfo) -> Self {
/// # Errors
///
/// Will fails if it can't build a HTTP client with a timeout.
pub fn new(connection_info: ConnectionInfo) -> Result<Self, Error> {
let base_url = format!("{}/api/v1", connection_info.url);
Self {
let client = reqwest::Client::builder().timeout(Duration::from_secs(5)).build()?;
let token_param = [("token".to_string(), connection_info.token.to_string())];

Ok(Self {
connection_info,
base_url,
}
api_base_url: base_url,
client,
token_param,
})
}

/// Add a torrent to the tracker whitelist.
Expand All @@ -34,13 +45,9 @@ impl Client {
///
/// Will return an error if the HTTP request fails.
pub async fn whitelist_torrent(&self, info_hash: &str) -> Result<Response, Error> {
let request_url = format!("{}/whitelist/{}", self.base_url, info_hash);

let client = reqwest::Client::new();

let params = [("token", &self.connection_info.token)];
let request_url = format!("{}/whitelist/{}", self.api_base_url, info_hash);

client.post(request_url).query(&params).send().await
self.client.post(request_url).query(&self.token_param).send().await
}

/// Remove a torrent from the tracker whitelist.
Expand All @@ -49,13 +56,9 @@ impl Client {
///
/// Will return an error if the HTTP request fails.
pub async fn remove_torrent_from_whitelist(&self, info_hash: &str) -> Result<Response, Error> {
let request_url = format!("{}/whitelist/{}", self.base_url, info_hash);
let request_url = format!("{}/whitelist/{}", self.api_base_url, info_hash);

let client = reqwest::Client::new();

let params = [("token", &self.connection_info.token)];

client.delete(request_url).query(&params).send().await
self.client.delete(request_url).query(&self.token_param).send().await
}

/// Retrieve a new tracker key.
Expand All @@ -64,13 +67,9 @@ impl Client {
///
/// Will return an error if the HTTP request fails.
pub async fn retrieve_new_tracker_key(&self, token_valid_seconds: u64) -> Result<Response, Error> {
let request_url = format!("{}/key/{}", self.base_url, token_valid_seconds);

let client = reqwest::Client::new();
let request_url = format!("{}/key/{}", self.api_base_url, token_valid_seconds);

let params = [("token", &self.connection_info.token)];

client.post(request_url).query(&params).send().await
self.client.post(request_url).query(&self.token_param).send().await
}

/// Retrieve the info for a torrent.
Expand All @@ -79,12 +78,8 @@ impl Client {
///
/// Will return an error if the HTTP request fails.
pub async fn get_torrent_info(&self, info_hash: &str) -> Result<Response, Error> {
let request_url = format!("{}/torrent/{}", self.base_url, info_hash);

let client = reqwest::Client::new();

let params = [("token", &self.connection_info.token)];
let request_url = format!("{}/torrent/{}", self.api_base_url, info_hash);

client.get(request_url).query(&params).send().await
self.client.get(request_url).query(&self.token_param).send().await
}
}
6 changes: 5 additions & 1 deletion src/tracker/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,16 @@ pub struct Service {
}

impl Service {
/// # Panics
///
/// Will panic if it can't build a Tracker API client.
pub async fn new(cfg: Arc<Configuration>, database: Arc<Box<dyn Database>>) -> Service {
let settings = cfg.settings.read().await;
let api_client = Client::new(ConnectionInfo::new(
settings.tracker.api_url.clone(),
settings.tracker.token.clone(),
));
))
.expect("a reqwest client should be provided");
let token_valid_seconds = settings.tracker.token_valid_seconds;
let tracker_url = settings.tracker.url.clone();
drop(settings);
Expand Down
Loading