forked from torrust/torrust-tracker
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathclient.rs
More file actions
103 lines (86 loc) · 3.13 KB
/
client.rs
File metadata and controls
103 lines (86 loc) · 3.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
use std::net::IpAddr;
use reqwest::{Client as ReqwestClient, Response};
use torrust_tracker::core::auth::Key;
use super::requests::announce::{self, Query};
use super::requests::scrape;
/// HTTP Tracker Client
pub struct Client {
server_addr: std::net::SocketAddr,
reqwest: ReqwestClient,
key: Option<Key>,
}
/// URL components in this context:
///
/// ```text
/// http://127.0.0.1:62304/announce/YZ....rJ?info_hash=%9C8B%22%13%E3%0B%FF%21%2B0%C3%60%D2o%9A%02%13d%22
/// \_____________________/\_______________/ \__________________________________________________________/
/// | | |
/// base url path query
/// ```
impl Client {
pub fn new(server_addr: std::net::SocketAddr) -> Self {
Self {
server_addr,
reqwest: reqwest::Client::builder().build().unwrap(),
key: None,
}
}
/// Creates the new client binding it to an specific local address
pub fn bind(server_addr: std::net::SocketAddr, local_address: IpAddr) -> Self {
Self {
server_addr,
reqwest: reqwest::Client::builder().local_address(local_address).build().unwrap(),
key: None,
}
}
pub fn authenticated(server_addr: std::net::SocketAddr, key: Key) -> Self {
Self {
server_addr,
reqwest: reqwest::Client::builder().build().unwrap(),
key: Some(key),
}
}
pub async fn announce(&self, query: &announce::Query) -> Response {
self.get(&self.build_announce_path_and_query(query)).await
}
pub async fn scrape(&self, query: &scrape::Query) -> Response {
self.get(&self.build_scrape_path_and_query(query)).await
}
pub async fn announce_with_header(&self, query: &Query, key: &str, value: &str) -> Response {
self.get_with_header(&self.build_announce_path_and_query(query), key, value)
.await
}
pub async fn health_check(&self) -> Response {
self.get(&self.build_path("health_check")).await
}
pub async fn get(&self, path: &str) -> Response {
self.reqwest.get(self.build_url(path)).send().await.unwrap()
}
pub async fn get_with_header(&self, path: &str, key: &str, value: &str) -> Response {
self.reqwest
.get(self.build_url(path))
.header(key, value)
.send()
.await
.unwrap()
}
fn build_announce_path_and_query(&self, query: &announce::Query) -> String {
format!("{}?{query}", self.build_path("announce"))
}
fn build_scrape_path_and_query(&self, query: &scrape::Query) -> String {
format!("{}?{query}", self.build_path("scrape"))
}
fn build_path(&self, path: &str) -> String {
match &self.key {
Some(key) => format!("{path}/{key}"),
None => path.to_string(),
}
}
fn build_url(&self, path: &str) -> String {
let base_url = self.base_url();
format!("{base_url}{path}")
}
fn base_url(&self) -> String {
format!("http://{}/", &self.server_addr)
}
}