138 lines
3.4 KiB
Rust
138 lines
3.4 KiB
Rust
use std::borrow::Cow;
|
|
|
|
use reqwest::{Method, Response};
|
|
use secrecy::{ExposeSecret, SecretString};
|
|
use url::UrlQuery;
|
|
|
|
macro_rules! const_from_env {
|
|
($const:ident, $env:literal) => {
|
|
const $const: Option<&'static str> = option_env!($env);
|
|
};
|
|
($const:ident, $env:literal, $default:expr) => {
|
|
const $const: &'static str = match option_env!($env) {
|
|
Some(s) => s,
|
|
None => $default,
|
|
};
|
|
};
|
|
}
|
|
|
|
const_from_env!(USER_AGENT_APP, "FROXY_UA_APP_NAME", "Froxy");
|
|
const_from_env!(USER_AGENT_VERSION, "FROXY_UA_APP_VERSION", {
|
|
const_from_env!(CARGO_PKG_VERSION, "CARGO_PKG_VERSION", "0.1-alpha");
|
|
CARGO_PKG_VERSION
|
|
});
|
|
const_from_env!(
|
|
USER_AGENT_DESC,
|
|
"FROXY_UA_DESC",
|
|
"(by maiboyer; for maiboyer)"
|
|
);
|
|
|
|
pub const DEFAULT_USER_AGENT: &str =
|
|
constcat::concat!(USER_AGENT_APP, "/", USER_AGENT_VERSION, USER_AGENT_DESC);
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct State {
|
|
client: reqwest::Client,
|
|
base_url: url::Url,
|
|
secret_cookie: secrecy::SecretString,
|
|
user_agent: std::borrow::Cow<'static, str>,
|
|
}
|
|
|
|
impl State {
|
|
pub fn new(secret_cookie: impl AsRef<str>) -> Self {
|
|
let user_agent = DEFAULT_USER_AGENT;
|
|
let base_url = "https://friends.42paris.fr";
|
|
|
|
Self::with_info(
|
|
secret_cookie,
|
|
user_agent.into(),
|
|
url::Url::parse(base_url).expect("default base url not valid"),
|
|
)
|
|
}
|
|
|
|
pub fn with_info(
|
|
secret_cookie: impl AsRef<str>,
|
|
user_agent: std::borrow::Cow<'static, str>,
|
|
base_url: url::Url,
|
|
) -> Self {
|
|
let client = reqwest::Client::builder()
|
|
.user_agent(&*user_agent)
|
|
.build()
|
|
.unwrap();
|
|
|
|
Self {
|
|
client,
|
|
base_url,
|
|
secret_cookie: secret_cookie.as_ref().into(),
|
|
user_agent,
|
|
}
|
|
}
|
|
|
|
pub fn client(&self) -> &reqwest::Client {
|
|
&self.client
|
|
}
|
|
|
|
pub fn base_url(&self) -> &url::Url {
|
|
&self.base_url
|
|
}
|
|
|
|
pub fn cookie(&self) -> &SecretString {
|
|
&self.secret_cookie
|
|
}
|
|
|
|
pub fn user_agent(&self) -> &str {
|
|
&self.user_agent
|
|
}
|
|
}
|
|
|
|
impl State {
|
|
pub async fn request(
|
|
&self,
|
|
method: Method,
|
|
url: impl AsRef<str>,
|
|
qs: Option<&str>,
|
|
body: Option<Vec<u8>>,
|
|
) -> Result<Response, reqwest::Error> {
|
|
let mut u = self.base_url.clone();
|
|
u.set_path(url.as_ref());
|
|
u.set_query(qs);
|
|
let builder = self
|
|
.client
|
|
.request(method, u)
|
|
.header("Cookie", self.secret_cookie.expose_secret());
|
|
|
|
let builder = if let Some(body) = body {
|
|
builder.body(body)
|
|
} else {
|
|
builder
|
|
};
|
|
|
|
builder.send().await
|
|
}
|
|
|
|
pub async fn get(
|
|
&self,
|
|
url: impl AsRef<str>,
|
|
qs: Option<&str>,
|
|
) -> Result<Response, reqwest::Error> {
|
|
self.request(Method::GET, url.as_ref(), qs, None).await
|
|
}
|
|
|
|
pub async fn post(
|
|
&self,
|
|
url: impl AsRef<str>,
|
|
qs: Option<&str>,
|
|
) -> Result<Response, reqwest::Error> {
|
|
self.request(Method::POST, url.as_ref(), qs, None).await
|
|
}
|
|
|
|
pub async fn post_with_body(
|
|
&self,
|
|
url: impl AsRef<str>,
|
|
qs: Option<&str>,
|
|
body: Vec<u8>,
|
|
) -> Result<Response, reqwest::Error> {
|
|
self.request(Method::POST, url.as_ref(), qs, Some(body))
|
|
.await
|
|
}
|
|
}
|