mirror of
https://github.com/kristoferssolo/transmission-rpc.git
synced 2025-10-21 20:10:37 +00:00
Handle CSRF protection according to 2.3.1. CSRF Protection spec.
This commit is contained in:
parent
88e5c91452
commit
2eafef4fe1
@ -10,7 +10,7 @@ async fn main() -> Result<()> {
|
|||||||
dotenv().ok();
|
dotenv().ok();
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
let url = env::var("TURL")?;
|
let url = env::var("TURL")?;
|
||||||
let client;
|
let mut client;
|
||||||
if let (Ok(user), Ok(password)) = (env::var("TUSER"), env::var("TPWD")) {
|
if let (Ok(user), Ok(password)) = (env::var("TUSER"), env::var("TPWD")) {
|
||||||
client = TransClient::with_auth(&url, BasicAuth {user, password});
|
client = TransClient::with_auth(&url, BasicAuth {user, password});
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -11,7 +11,7 @@ async fn main() -> Result<()> {
|
|||||||
env_logger::init();
|
env_logger::init();
|
||||||
let url = env::var("TURL")?;
|
let url = env::var("TURL")?;
|
||||||
let dir = env::var("TDIR")?;
|
let dir = env::var("TDIR")?;
|
||||||
let client;
|
let mut client;
|
||||||
if let (Ok(user), Ok(password)) = (env::var("TUSER"), env::var("TPWD")) {
|
if let (Ok(user), Ok(password)) = (env::var("TUSER"), env::var("TPWD")) {
|
||||||
client = TransClient::with_auth(&url, BasicAuth {user, password});
|
client = TransClient::with_auth(&url, BasicAuth {user, password});
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -10,7 +10,7 @@ async fn main() -> Result<()> {
|
|||||||
dotenv().ok();
|
dotenv().ok();
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
let url = env::var("TURL")?;
|
let url = env::var("TURL")?;
|
||||||
let client;
|
let mut client;
|
||||||
if let (Ok(user), Ok(password)) = (env::var("TUSER"), env::var("TPWD")) {
|
if let (Ok(user), Ok(password)) = (env::var("TUSER"), env::var("TPWD")) {
|
||||||
client = TransClient::with_auth(&url, BasicAuth {user, password});
|
client = TransClient::with_auth(&url, BasicAuth {user, password});
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -10,7 +10,7 @@ async fn main() -> Result<()> {
|
|||||||
dotenv().ok();
|
dotenv().ok();
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
let url = env::var("TURL")?;
|
let url = env::var("TURL")?;
|
||||||
let client;
|
let mut client;
|
||||||
if let (Ok(user), Ok(password)) = (env::var("TUSER"), env::var("TPWD")) {
|
if let (Ok(user), Ok(password)) = (env::var("TUSER"), env::var("TPWD")) {
|
||||||
client = TransClient::with_auth(&url, BasicAuth {user, password});
|
client = TransClient::with_auth(&url, BasicAuth {user, password});
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -10,7 +10,7 @@ async fn main() -> Result<()> {
|
|||||||
dotenv().ok();
|
dotenv().ok();
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
let url = env::var("TURL")?;
|
let url = env::var("TURL")?;
|
||||||
let client;
|
let mut client;
|
||||||
if let (Ok(user), Ok(password)) = (env::var("TUSER"), env::var("TPWD")) {
|
if let (Ok(user), Ok(password)) = (env::var("TUSER"), env::var("TPWD")) {
|
||||||
client = TransClient::with_auth(&url, BasicAuth {user, password});
|
client = TransClient::with_auth(&url, BasicAuth {user, password});
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -10,7 +10,7 @@ async fn main() -> Result<()> {
|
|||||||
dotenv().ok();
|
dotenv().ok();
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
let url = env::var("TURL")?;
|
let url = env::var("TURL")?;
|
||||||
let client;
|
let mut client;
|
||||||
if let (Ok(user), Ok(password)) = (env::var("TUSER"), env::var("TPWD")) {
|
if let (Ok(user), Ok(password)) = (env::var("TUSER"), env::var("TPWD")) {
|
||||||
client = TransClient::with_auth(&url, BasicAuth {user, password});
|
client = TransClient::with_auth(&url, BasicAuth {user, password});
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -11,7 +11,7 @@ async fn main() -> Result<()> {
|
|||||||
dotenv().ok();
|
dotenv().ok();
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
let url = env::var("TURL")?;
|
let url = env::var("TURL")?;
|
||||||
let client;
|
let mut client;
|
||||||
if let (Ok(user), Ok(password)) = (env::var("TUSER"), env::var("TPWD")) {
|
if let (Ok(user), Ok(password)) = (env::var("TUSER"), env::var("TPWD")) {
|
||||||
client = TransClient::with_auth(&url, BasicAuth {user, password});
|
client = TransClient::with_auth(&url, BasicAuth {user, password});
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -11,7 +11,7 @@ async fn main() -> Result<()> {
|
|||||||
dotenv().ok();
|
dotenv().ok();
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
let url = env::var("TURL")?;
|
let url = env::var("TURL")?;
|
||||||
let client;
|
let mut client;
|
||||||
if let (Ok(user), Ok(password)) = (env::var("TUSER"), env::var("TPWD")) {
|
if let (Ok(user), Ok(password)) = (env::var("TUSER"), env::var("TPWD")) {
|
||||||
client = TransClient::with_auth(&url, BasicAuth {user, password});
|
client = TransClient::with_auth(&url, BasicAuth {user, password});
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -11,7 +11,7 @@ async fn main() -> Result<()> {
|
|||||||
dotenv().ok();
|
dotenv().ok();
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
let url = env::var("TURL")?;
|
let url = env::var("TURL")?;
|
||||||
let client;
|
let mut client;
|
||||||
if let (Ok(user), Ok(password)) = (env::var("TUSER"), env::var("TPWD")) {
|
if let (Ok(user), Ok(password)) = (env::var("TUSER"), env::var("TPWD")) {
|
||||||
client = TransClient::with_auth(&url, BasicAuth {user, password});
|
client = TransClient::with_auth(&url, BasicAuth {user, password});
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -11,7 +11,7 @@ async fn main() -> Result<()> {
|
|||||||
dotenv().ok();
|
dotenv().ok();
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
let url = env::var("TURL")?;
|
let url = env::var("TURL")?;
|
||||||
let client;
|
let mut client;
|
||||||
if let (Ok(user), Ok(password)) = (env::var("TUSER"), env::var("TPWD")) {
|
if let (Ok(user), Ok(password)) = (env::var("TUSER"), env::var("TPWD")) {
|
||||||
client = TransClient::with_auth(&url, BasicAuth {user, password});
|
client = TransClient::with_auth(&url, BasicAuth {user, password});
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -12,7 +12,7 @@ async fn main() -> Result<()> {
|
|||||||
env_logger::init();
|
env_logger::init();
|
||||||
let url= env::var("TURL")?;
|
let url= env::var("TURL")?;
|
||||||
let basic_auth = BasicAuth{user: env::var("TUSER")?, password: env::var("TPWD")?};
|
let basic_auth = BasicAuth{user: env::var("TUSER")?, password: env::var("TPWD")?};
|
||||||
let client = TransClient::with_auth(&url, basic_auth);
|
let mut client = TransClient::with_auth(&url, basic_auth);
|
||||||
let res: RpcResponse<TorrentRenamePath> = client.torrent_rename_path(vec![Id::Id(1)], String::from("Folder/OldFile.jpg"), String::from("NewFile.jpg")).await?;
|
let res: RpcResponse<TorrentRenamePath> = client.torrent_rename_path(vec![Id::Id(1)], String::from("Folder/OldFile.jpg"), String::from("NewFile.jpg")).await?;
|
||||||
println!("rename-path result: {:#?}", res);
|
println!("rename-path result: {:#?}", res);
|
||||||
|
|
||||||
|
|||||||
@ -11,7 +11,7 @@ async fn main() -> Result<()> {
|
|||||||
dotenv().ok();
|
dotenv().ok();
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
let url = env::var("TURL")?;
|
let url = env::var("TURL")?;
|
||||||
let client;
|
let mut client;
|
||||||
if let (Ok(user), Ok(password)) = (env::var("TUSER"), env::var("TPWD")) {
|
if let (Ok(user), Ok(password)) = (env::var("TUSER"), env::var("TPWD")) {
|
||||||
client = TransClient::with_auth(&url, BasicAuth {user, password});
|
client = TransClient::with_auth(&url, BasicAuth {user, password});
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
169
src/lib.rs
169
src/lib.rs
@ -4,6 +4,7 @@ extern crate log;
|
|||||||
extern crate reqwest;
|
extern crate reqwest;
|
||||||
|
|
||||||
use reqwest::header::CONTENT_TYPE;
|
use reqwest::header::CONTENT_TYPE;
|
||||||
|
use reqwest::{Client, StatusCode};
|
||||||
use serde::de::DeserializeOwned;
|
use serde::de::DeserializeOwned;
|
||||||
|
|
||||||
pub mod types;
|
pub mod types;
|
||||||
@ -20,9 +21,30 @@ use types::{Id, Torrent, TorrentGetField, Torrents};
|
|||||||
use types::{Nothing, Result, RpcRequest, RpcResponse, RpcResponseArgument, TorrentRenamePath};
|
use types::{Nothing, Result, RpcRequest, RpcResponse, RpcResponseArgument, TorrentRenamePath};
|
||||||
use types::{TorrentAddArgs, TorrentAdded};
|
use types::{TorrentAddArgs, TorrentAdded};
|
||||||
|
|
||||||
|
const MAX_RETRIES: usize = 5;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
enum TransError {
|
||||||
|
MaxRetriesReached,
|
||||||
|
NoSessionIdReceived,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for TransError {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match *self {
|
||||||
|
TransError::MaxRetriesReached => write!(f, "Max retries reached!"),
|
||||||
|
TransError::NoSessionIdReceived => write!(f, "No session id received!"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::error::Error for TransError {}
|
||||||
|
|
||||||
pub struct TransClient {
|
pub struct TransClient {
|
||||||
url: String,
|
url: String,
|
||||||
auth: Option<BasicAuth>,
|
auth: Option<BasicAuth>,
|
||||||
|
session_id: Option<String>,
|
||||||
|
client: Client,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TransClient {
|
impl TransClient {
|
||||||
@ -31,6 +53,8 @@ impl TransClient {
|
|||||||
TransClient {
|
TransClient {
|
||||||
url: url.to_string(),
|
url: url.to_string(),
|
||||||
auth: Some(basic_auth),
|
auth: Some(basic_auth),
|
||||||
|
session_id: None,
|
||||||
|
client: Client::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,45 +63,19 @@ impl TransClient {
|
|||||||
TransClient {
|
TransClient {
|
||||||
url: url.to_string(),
|
url: url.to_string(),
|
||||||
auth: None,
|
auth: None,
|
||||||
|
session_id: None,
|
||||||
|
client: Client::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Prepares a request for provided server and auth
|
/// Prepares a request for provided server and auth
|
||||||
fn rpc_request(&self) -> reqwest::RequestBuilder {
|
fn rpc_request(&self) -> reqwest::RequestBuilder {
|
||||||
let client = reqwest::Client::new();
|
|
||||||
if let Some(auth) = &self.auth {
|
if let Some(auth) = &self.auth {
|
||||||
client
|
self.client.post(&self.url)
|
||||||
.post(&self.url)
|
|
||||||
.basic_auth(&auth.user, Some(&auth.password))
|
.basic_auth(&auth.user, Some(&auth.password))
|
||||||
} else {
|
} else {
|
||||||
client.post(&self.url)
|
self.client.post(&self.url)
|
||||||
}
|
}.header(CONTENT_TYPE, "application/json")
|
||||||
.header(CONTENT_TYPE, "application/json")
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Performs session-get call and takes the x-transmission-session-id
|
|
||||||
/// header to perform calls, using it's value
|
|
||||||
///
|
|
||||||
/// # Errors
|
|
||||||
///
|
|
||||||
/// If response is impossible to unwrap then it will return an empty session_id
|
|
||||||
async fn get_session_id(&self) -> String {
|
|
||||||
info!("Requesting session id info");
|
|
||||||
let response: reqwest::Result<reqwest::Response> = self
|
|
||||||
.rpc_request()
|
|
||||||
.json(&RpcRequest::session_get())
|
|
||||||
.send()
|
|
||||||
.await;
|
|
||||||
let session_id = match response {
|
|
||||||
Ok(ref resp) => match resp.headers().get("x-transmission-session-id") {
|
|
||||||
Some(res) => res.to_str().expect("header value should be a string"),
|
|
||||||
_ => "",
|
|
||||||
},
|
|
||||||
_ => "",
|
|
||||||
}
|
|
||||||
.to_owned();
|
|
||||||
info!("Received session id: {}", session_id);
|
|
||||||
session_id
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Performs a session get call
|
/// Performs a session get call
|
||||||
@ -102,7 +100,7 @@ impl TransClient {
|
|||||||
/// env_logger::init();
|
/// env_logger::init();
|
||||||
/// let url= env::var("TURL")?;
|
/// let url= env::var("TURL")?;
|
||||||
/// let basic_auth = BasicAuth{user: env::var("TUSER")?, password: env::var("TPWD")?};
|
/// let basic_auth = BasicAuth{user: env::var("TUSER")?, password: env::var("TPWD")?};
|
||||||
/// let client = TransClient::with_auth(&url, basic_auth);
|
/// let mut client = TransClient::with_auth(&url, basic_auth);
|
||||||
/// let response: Result<RpcResponse<SessionGet>> = client.session_get().await;
|
/// let response: Result<RpcResponse<SessionGet>> = client.session_get().await;
|
||||||
/// match response {
|
/// match response {
|
||||||
/// Ok(_) => println!("Yay!"),
|
/// Ok(_) => println!("Yay!"),
|
||||||
@ -112,7 +110,7 @@ impl TransClient {
|
|||||||
/// Ok(())
|
/// Ok(())
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub async fn session_get(&self) -> Result<RpcResponse<SessionGet>> {
|
pub async fn session_get(&mut self) -> Result<RpcResponse<SessionGet>> {
|
||||||
self.call(RpcRequest::session_get()).await
|
self.call(RpcRequest::session_get()).await
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,7 +136,7 @@ impl TransClient {
|
|||||||
/// env_logger::init();
|
/// env_logger::init();
|
||||||
/// let url= env::var("TURL")?;
|
/// let url= env::var("TURL")?;
|
||||||
/// let basic_auth = BasicAuth{user: env::var("TUSER")?, password: env::var("TPWD")?};
|
/// let basic_auth = BasicAuth{user: env::var("TUSER")?, password: env::var("TPWD")?};
|
||||||
/// let client = TransClient::with_auth(&url, basic_auth);
|
/// let mut client = TransClient::with_auth(&url, basic_auth);
|
||||||
/// let response: Result<RpcResponse<SessionStats>> = client.session_stats().await;
|
/// let response: Result<RpcResponse<SessionStats>> = client.session_stats().await;
|
||||||
/// match response {
|
/// match response {
|
||||||
/// Ok(_) => println!("Yay!"),
|
/// Ok(_) => println!("Yay!"),
|
||||||
@ -148,7 +146,7 @@ impl TransClient {
|
|||||||
/// Ok(())
|
/// Ok(())
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub async fn session_stats(&self) -> Result<RpcResponse<SessionStats>> {
|
pub async fn session_stats(&mut self) -> Result<RpcResponse<SessionStats>> {
|
||||||
self.call(RpcRequest::session_stats()).await
|
self.call(RpcRequest::session_stats()).await
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,7 +172,7 @@ impl TransClient {
|
|||||||
/// env_logger::init();
|
/// env_logger::init();
|
||||||
/// let url= env::var("TURL")?;
|
/// let url= env::var("TURL")?;
|
||||||
/// let basic_auth = BasicAuth{user: env::var("TUSER")?, password: env::var("TPWD")?};
|
/// let basic_auth = BasicAuth{user: env::var("TUSER")?, password: env::var("TPWD")?};
|
||||||
/// let client = TransClient::with_auth(&url, basic_auth);
|
/// let mut client = TransClient::with_auth(&url, basic_auth);
|
||||||
/// let response: Result<RpcResponse<SessionClose>> = client.session_close().await;
|
/// let response: Result<RpcResponse<SessionClose>> = client.session_close().await;
|
||||||
/// match response {
|
/// match response {
|
||||||
/// Ok(_) => println!("Yay!"),
|
/// Ok(_) => println!("Yay!"),
|
||||||
@ -184,7 +182,7 @@ impl TransClient {
|
|||||||
/// Ok(())
|
/// Ok(())
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub async fn session_close(&self) -> Result<RpcResponse<SessionClose>> {
|
pub async fn session_close(&mut self) -> Result<RpcResponse<SessionClose>> {
|
||||||
self.call(RpcRequest::session_close()).await
|
self.call(RpcRequest::session_close()).await
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,7 +208,7 @@ impl TransClient {
|
|||||||
/// env_logger::init();
|
/// env_logger::init();
|
||||||
/// let url= env::var("TURL")?;
|
/// let url= env::var("TURL")?;
|
||||||
/// let basic_auth = BasicAuth{user: env::var("TUSER")?, password: env::var("TPWD")?};
|
/// let basic_auth = BasicAuth{user: env::var("TUSER")?, password: env::var("TPWD")?};
|
||||||
/// let client = TransClient::with_auth(&url, basic_auth);
|
/// let mut client = TransClient::with_auth(&url, basic_auth);
|
||||||
/// let response: Result<RpcResponse<BlocklistUpdate>> = client.blocklist_update().await;
|
/// let response: Result<RpcResponse<BlocklistUpdate>> = client.blocklist_update().await;
|
||||||
/// match response {
|
/// match response {
|
||||||
/// Ok(_) => println!("Yay!"),
|
/// Ok(_) => println!("Yay!"),
|
||||||
@ -220,7 +218,7 @@ impl TransClient {
|
|||||||
/// Ok(())
|
/// Ok(())
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub async fn blocklist_update(&self) -> Result<RpcResponse<BlocklistUpdate>> {
|
pub async fn blocklist_update(&mut self) -> Result<RpcResponse<BlocklistUpdate>> {
|
||||||
self.call(RpcRequest::blocklist_update()).await
|
self.call(RpcRequest::blocklist_update()).await
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -247,7 +245,7 @@ impl TransClient {
|
|||||||
/// let url= env::var("TURL")?;
|
/// let url= env::var("TURL")?;
|
||||||
/// let dir = env::var("TDIR")?;
|
/// let dir = env::var("TDIR")?;
|
||||||
/// let basic_auth = BasicAuth{user: env::var("TUSER")?, password: env::var("TPWD")?};
|
/// let basic_auth = BasicAuth{user: env::var("TUSER")?, password: env::var("TPWD")?};
|
||||||
/// let client = TransClient::with_auth(&url, basic_auth);
|
/// let mut client = TransClient::with_auth(&url, basic_auth);
|
||||||
/// let response: Result<RpcResponse<FreeSpace>> = client.free_space(dir).await;
|
/// let response: Result<RpcResponse<FreeSpace>> = client.free_space(dir).await;
|
||||||
/// match response {
|
/// match response {
|
||||||
/// Ok(_) => println!("Yay!"),
|
/// Ok(_) => println!("Yay!"),
|
||||||
@ -257,7 +255,7 @@ impl TransClient {
|
|||||||
/// Ok(())
|
/// Ok(())
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub async fn free_space(&self, path: String) -> Result<RpcResponse<FreeSpace>> {
|
pub async fn free_space(&mut self, path: String) -> Result<RpcResponse<FreeSpace>> {
|
||||||
self.call(RpcRequest::free_space(path)).await
|
self.call(RpcRequest::free_space(path)).await
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -283,7 +281,7 @@ impl TransClient {
|
|||||||
/// env_logger::init();
|
/// env_logger::init();
|
||||||
/// let url= env::var("TURL")?;
|
/// let url= env::var("TURL")?;
|
||||||
/// let basic_auth = BasicAuth{user: env::var("TUSER")?, password: env::var("TPWD")?};
|
/// let basic_auth = BasicAuth{user: env::var("TUSER")?, password: env::var("TPWD")?};
|
||||||
/// let client = TransClient::with_auth(&url, basic_auth);
|
/// let mut client = TransClient::with_auth(&url, basic_auth);
|
||||||
/// let response: Result<RpcResponse<PortTest>> = client.port_test().await;
|
/// let response: Result<RpcResponse<PortTest>> = client.port_test().await;
|
||||||
/// match response {
|
/// match response {
|
||||||
/// Ok(_) => println!("Yay!"),
|
/// Ok(_) => println!("Yay!"),
|
||||||
@ -293,7 +291,7 @@ impl TransClient {
|
|||||||
/// Ok(())
|
/// Ok(())
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub async fn port_test(&self) -> Result<RpcResponse<PortTest>> {
|
pub async fn port_test(&mut self) -> Result<RpcResponse<PortTest>> {
|
||||||
self.call(RpcRequest::port_test()).await
|
self.call(RpcRequest::port_test()).await
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -322,7 +320,7 @@ impl TransClient {
|
|||||||
/// env_logger::init();
|
/// env_logger::init();
|
||||||
/// let url= env::var("TURL")?;
|
/// let url= env::var("TURL")?;
|
||||||
/// let basic_auth = BasicAuth{user: env::var("TUSER")?, password: env::var("TPWD")?};
|
/// let basic_auth = BasicAuth{user: env::var("TUSER")?, password: env::var("TPWD")?};
|
||||||
/// let client = TransClient::with_auth(&url, basic_auth);
|
/// let mut client = TransClient::with_auth(&url, basic_auth);
|
||||||
///
|
///
|
||||||
/// let res: RpcResponse<Torrents<Torrent>> = client.torrent_get(None, None).await?;
|
/// let res: RpcResponse<Torrents<Torrent>> = client.torrent_get(None, None).await?;
|
||||||
/// let names: Vec<&String> = res.arguments.torrents.iter().map(|it| it.name.as_ref().unwrap()).collect();
|
/// let names: Vec<&String> = res.arguments.torrents.iter().map(|it| it.name.as_ref().unwrap()).collect();
|
||||||
@ -348,7 +346,7 @@ impl TransClient {
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub async fn torrent_get(
|
pub async fn torrent_get(
|
||||||
&self,
|
&mut self,
|
||||||
fields: Option<Vec<TorrentGetField>>,
|
fields: Option<Vec<TorrentGetField>>,
|
||||||
ids: Option<Vec<Id>>,
|
ids: Option<Vec<Id>>,
|
||||||
) -> Result<RpcResponse<Torrents<Torrent>>> {
|
) -> Result<RpcResponse<Torrents<Torrent>>> {
|
||||||
@ -378,7 +376,7 @@ impl TransClient {
|
|||||||
/// env_logger::init();
|
/// env_logger::init();
|
||||||
/// let url= env::var("TURL")?;
|
/// let url= env::var("TURL")?;
|
||||||
/// let basic_auth = BasicAuth{user: env::var("TUSER")?, password: env::var("TPWD")?};
|
/// let basic_auth = BasicAuth{user: env::var("TUSER")?, password: env::var("TPWD")?};
|
||||||
/// let client = TransClient::with_auth(&url, basic_auth);
|
/// let mut client = TransClient::with_auth(&url, basic_auth);
|
||||||
/// let res1: RpcResponse<Nothing> = client.torrent_action(TorrentAction::Start, vec![Id::Id(1)]).await?;
|
/// let res1: RpcResponse<Nothing> = client.torrent_action(TorrentAction::Start, vec![Id::Id(1)]).await?;
|
||||||
/// println!("Start result: {:?}", &res1.is_ok());
|
/// println!("Start result: {:?}", &res1.is_ok());
|
||||||
/// let res2: RpcResponse<Nothing> = client.torrent_action(TorrentAction::Stop, vec![Id::Id(1)]).await?;
|
/// let res2: RpcResponse<Nothing> = client.torrent_action(TorrentAction::Stop, vec![Id::Id(1)]).await?;
|
||||||
@ -388,7 +386,7 @@ impl TransClient {
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub async fn torrent_action(
|
pub async fn torrent_action(
|
||||||
&self,
|
&mut self,
|
||||||
action: TorrentAction,
|
action: TorrentAction,
|
||||||
ids: Vec<Id>,
|
ids: Vec<Id>,
|
||||||
) -> Result<RpcResponse<Nothing>> {
|
) -> Result<RpcResponse<Nothing>> {
|
||||||
@ -418,7 +416,7 @@ impl TransClient {
|
|||||||
/// env_logger::init();
|
/// env_logger::init();
|
||||||
/// let url= env::var("TURL")?;
|
/// let url= env::var("TURL")?;
|
||||||
/// let basic_auth = BasicAuth{user: env::var("TUSER")?, password: env::var("TPWD")?};
|
/// let basic_auth = BasicAuth{user: env::var("TUSER")?, password: env::var("TPWD")?};
|
||||||
/// let client = TransClient::with_auth(&url, basic_auth);
|
/// let mut client = TransClient::with_auth(&url, basic_auth);
|
||||||
/// let res: RpcResponse<Nothing> = client.torrent_remove(vec![Id::Id(1)], false).await?;
|
/// let res: RpcResponse<Nothing> = client.torrent_remove(vec![Id::Id(1)], false).await?;
|
||||||
/// println!("Remove result: {:?}", &res.is_ok());
|
/// println!("Remove result: {:?}", &res.is_ok());
|
||||||
///
|
///
|
||||||
@ -426,7 +424,7 @@ impl TransClient {
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub async fn torrent_remove(
|
pub async fn torrent_remove(
|
||||||
&self,
|
&mut self,
|
||||||
ids: Vec<Id>,
|
ids: Vec<Id>,
|
||||||
delete_local_data: bool,
|
delete_local_data: bool,
|
||||||
) -> Result<RpcResponse<Nothing>> {
|
) -> Result<RpcResponse<Nothing>> {
|
||||||
@ -457,7 +455,7 @@ impl TransClient {
|
|||||||
/// env_logger::init();
|
/// env_logger::init();
|
||||||
/// let url= env::var("TURL")?;
|
/// let url= env::var("TURL")?;
|
||||||
/// let basic_auth = BasicAuth{user: env::var("TUSER")?, password: env::var("TPWD")?};
|
/// let basic_auth = BasicAuth{user: env::var("TUSER")?, password: env::var("TPWD")?};
|
||||||
/// let client = TransClient::with_auth(&url, basic_auth);
|
/// let mut client = TransClient::with_auth(&url, basic_auth);
|
||||||
/// let res: RpcResponse<Nothing> = client.torrent_set_location(vec![Id::Id(1)], String::from("/new/location"), Option::from(false)).await?;
|
/// let res: RpcResponse<Nothing> = client.torrent_set_location(vec![Id::Id(1)], String::from("/new/location"), Option::from(false)).await?;
|
||||||
/// println!("Set-location result: {:?}", &res.is_ok());
|
/// println!("Set-location result: {:?}", &res.is_ok());
|
||||||
///
|
///
|
||||||
@ -465,7 +463,7 @@ impl TransClient {
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub async fn torrent_set_location(
|
pub async fn torrent_set_location(
|
||||||
&self,
|
&mut self,
|
||||||
ids: Vec<Id>,
|
ids: Vec<Id>,
|
||||||
location: String,
|
location: String,
|
||||||
move_from: Option<bool>,
|
move_from: Option<bool>,
|
||||||
@ -497,7 +495,7 @@ impl TransClient {
|
|||||||
/// env_logger::init();
|
/// env_logger::init();
|
||||||
/// let url= env::var("TURL")?;
|
/// let url= env::var("TURL")?;
|
||||||
/// let basic_auth = BasicAuth{user: env::var("TUSER")?, password: env::var("TPWD")?};
|
/// let basic_auth = BasicAuth{user: env::var("TUSER")?, password: env::var("TPWD")?};
|
||||||
/// let client = TransClient::with_auth(&url, basic_auth);
|
/// let mut client = TransClient::with_auth(&url, basic_auth);
|
||||||
/// let res: RpcResponse<TorrentRenamePath> = client.torrent_rename_path(vec![Id::Id(1)], String::from("Folder/OldFile.jpg"), String::from("NewFile.jpg")).await?;
|
/// let res: RpcResponse<TorrentRenamePath> = client.torrent_rename_path(vec![Id::Id(1)], String::from("Folder/OldFile.jpg"), String::from("NewFile.jpg")).await?;
|
||||||
/// println!("rename-path result: {:#?}", res);
|
/// println!("rename-path result: {:#?}", res);
|
||||||
///
|
///
|
||||||
@ -505,7 +503,7 @@ impl TransClient {
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub async fn torrent_rename_path(
|
pub async fn torrent_rename_path(
|
||||||
&self,
|
&mut self,
|
||||||
ids: Vec<Id>,
|
ids: Vec<Id>,
|
||||||
path: String,
|
path: String,
|
||||||
name: String,
|
name: String,
|
||||||
@ -537,7 +535,7 @@ impl TransClient {
|
|||||||
/// env_logger::init();
|
/// env_logger::init();
|
||||||
/// let url= env::var("TURL")?;
|
/// let url= env::var("TURL")?;
|
||||||
/// let basic_auth = BasicAuth{user: env::var("TUSER")?, password: env::var("TPWD")?};
|
/// let basic_auth = BasicAuth{user: env::var("TUSER")?, password: env::var("TPWD")?};
|
||||||
/// let client = TransClient::with_auth(&url, basic_auth);
|
/// let mut client = TransClient::with_auth(&url, basic_auth);
|
||||||
/// let add: TorrentAddArgs = TorrentAddArgs {
|
/// let add: TorrentAddArgs = TorrentAddArgs {
|
||||||
/// filename: Some("https://releases.ubuntu.com/20.04/ubuntu-20.04-desktop-amd64.iso.torrent".to_string()),
|
/// filename: Some("https://releases.ubuntu.com/20.04/ubuntu-20.04-desktop-amd64.iso.torrent".to_string()),
|
||||||
/// ..TorrentAddArgs::default()
|
/// ..TorrentAddArgs::default()
|
||||||
@ -549,7 +547,7 @@ impl TransClient {
|
|||||||
/// Ok(())
|
/// Ok(())
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub async fn torrent_add(&self, add: TorrentAddArgs) -> Result<RpcResponse<TorrentAdded>> {
|
pub async fn torrent_add(&mut self, add: TorrentAddArgs) -> Result<RpcResponse<TorrentAdded>> {
|
||||||
if add.metainfo == None && add.filename == None {
|
if add.metainfo == None && add.filename == None {
|
||||||
panic!("Metainfo or Filename should be provided")
|
panic!("Metainfo or Filename should be provided")
|
||||||
}
|
}
|
||||||
@ -561,25 +559,52 @@ impl TransClient {
|
|||||||
/// # Errors
|
/// # Errors
|
||||||
///
|
///
|
||||||
/// Any IO Error or Deserialization error
|
/// Any IO Error or Deserialization error
|
||||||
async fn call<RS>(&self, request: RpcRequest) -> Result<RpcResponse<RS>>
|
async fn call<RS>(&mut self, request: RpcRequest) -> Result<RpcResponse<RS>>
|
||||||
where
|
where
|
||||||
RS: RpcResponseArgument + DeserializeOwned + std::fmt::Debug,
|
RS: RpcResponseArgument + DeserializeOwned + std::fmt::Debug,
|
||||||
{
|
{
|
||||||
info!("Loaded auth: {:?}", &self.auth);
|
let mut remaining_retries = MAX_RETRIES;
|
||||||
let rq: reqwest::RequestBuilder = self
|
loop {
|
||||||
.rpc_request()
|
if remaining_retries <= 0 {
|
||||||
.header("X-Transmission-Session-Id", self.get_session_id().await)
|
return Err(From::from(TransError::MaxRetriesReached));
|
||||||
.json(&request);
|
}
|
||||||
info!(
|
remaining_retries -= 1;
|
||||||
"Request body: {:?}",
|
|
||||||
rq.try_clone()
|
info!("Loaded auth: {:?}", &self.auth);
|
||||||
.expect("Unable to get the request body")
|
let rq = match &self.session_id {
|
||||||
.body_string()?
|
None => self.rpc_request(),
|
||||||
);
|
Some(id) => {
|
||||||
let resp: reqwest::Response = rq.send().await?;
|
self.rpc_request().header("X-Transmission-Session-Id", id)
|
||||||
let rpc_response: RpcResponse<RS> = resp.json().await?;
|
}
|
||||||
info!("Response body: {:#?}", rpc_response);
|
}.json(&request);
|
||||||
Ok(rpc_response)
|
|
||||||
|
info!(
|
||||||
|
"Request body: {:?}",
|
||||||
|
rq.try_clone()
|
||||||
|
.expect("Unable to get the request body")
|
||||||
|
.body_string()?
|
||||||
|
);
|
||||||
|
|
||||||
|
let rsp: reqwest::Response = rq.send().await?;
|
||||||
|
match rsp.status() {
|
||||||
|
StatusCode::CONFLICT => {
|
||||||
|
let session_id = rsp.headers()
|
||||||
|
.get("X-Transmission-Session-Id")
|
||||||
|
.ok_or(TransError::NoSessionIdReceived)?
|
||||||
|
.to_str()?;
|
||||||
|
self.session_id = Some(String::from(session_id));
|
||||||
|
|
||||||
|
info!("Got new session_id: {}. Retrying request.", session_id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
let rpc_response: RpcResponse<RS> = rsp.json().await?;
|
||||||
|
info!("Response body: {:#?}", rpc_response);
|
||||||
|
|
||||||
|
return Ok(rpc_response)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -606,7 +631,7 @@ mod tests {
|
|||||||
dotenv().ok();
|
dotenv().ok();
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
let url = env::var("TURL")?;
|
let url = env::var("TURL")?;
|
||||||
let client;
|
let mut client;
|
||||||
if let (Ok(user), Ok(password)) = (env::var("TUSER"), env::var("TPWD")) {
|
if let (Ok(user), Ok(password)) = (env::var("TUSER"), env::var("TPWD")) {
|
||||||
client = TransClient::with_auth(&url, BasicAuth {user, password});
|
client = TransClient::with_auth(&url, BasicAuth {user, password});
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user