util: add reqwest wrapper

This commit is contained in:
anna 2023-01-18 19:56:19 +01:00
parent da603511c4
commit 7124590ff3
Signed by: fef
GPG key ID: EC22E476DC2D3D84
2 changed files with 89 additions and 0 deletions

88
src/util/http.rs Normal file
View file

@ -0,0 +1,88 @@
use reqwest::header::{HeaderName, HeaderValue, AUTHORIZATION, USER_AGENT};
use reqwest::{header::HeaderMap, RequestBuilder, Response};
use std::collections::HashMap;
use crate::core::*;
use crate::middle::AuthData;
use crate::state::AppState;
use crate::util::bear::Bearcap;
/// Perform an HTTP GET request to the specified URL (supports bearcaps).
/// Use the [`headers!`] macro for the `headers` parameter.
///
/// ## Example
///
/// ```
/// let response = get(
/// &state,
/// "https://www.example.com",
/// headers! {
/// ACCEPT => "application/activity+json",
/// "X-Custom-Header" => "x-custom-value",
/// }
/// )
/// .await?;
///
/// // automatically injects an "Authorization: Bearer b4dc0ffee" header
/// let response = get(&state, "bear:?t=b4dc0ffee&u=https://www.example.com", headers! {}).await?;
/// ```
pub async fn get(
state: &AppState,
url: &str,
headers: &[(GenericHeaderName, String)],
) -> Result<Response> {
let client = reqwest::Client::new();
let builder = if url.starts_with("bear:") {
let bearcap = Bearcap::try_from(url)?;
client
.get(bearcap.url.as_str())
.header(AUTHORIZATION, format!("Bearer {}", bearcap.token))
} else {
client.get(url)
};
perform_request(state, builder, headers).await
}
// the state reference will be used for caching
async fn perform_request(
_state: &AppState,
mut builder: RequestBuilder,
headers: &[(GenericHeaderName, String)],
) -> Result<Response> {
builder = headers.into_iter().fold(builder, |b, (k, v)| match k {
GenericHeaderName::Standard(hdr) => b.header(hdr, v),
GenericHeaderName::Custom(hdr) => b.header(hdr, v),
});
builder = builder.header(USER_AGENT, "nyano");
Ok(builder.send().await?)
}
#[macro_export]
macro_rules! headers {
($($k:expr => $v:expr),* $(,)?) => {{
&[$((crate::util::http::GenericHeaderName::from($k), ::std::string::String::from($v)),)*]
}}
}
pub enum GenericHeaderName {
Custom(String),
Standard(HeaderName),
}
impl From<String> for GenericHeaderName {
fn from(val: String) -> GenericHeaderName {
GenericHeaderName::Custom(val)
}
}
impl From<&str> for GenericHeaderName {
fn from(val: &str) -> GenericHeaderName {
GenericHeaderName::Custom(String::from(val))
}
}
impl From<HeaderName> for GenericHeaderName {
fn from(val: HeaderName) -> GenericHeaderName {
GenericHeaderName::Standard(val)
}
}

View file

@ -1,4 +1,5 @@
pub mod bear; pub mod bear;
pub mod http;
pub mod password; pub mod password;
pub mod token; pub mod token;
pub mod validate; pub mod validate;