util: add reqwest wrapper
This commit is contained in:
parent
da603511c4
commit
7124590ff3
2 changed files with 89 additions and 0 deletions
88
src/util/http.rs
Normal file
88
src/util/http.rs
Normal 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)
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
pub mod bear;
|
||||
pub mod http;
|
||||
pub mod password;
|
||||
pub mod token;
|
||||
pub mod validate;
|
||||
|
|
Loading…
Reference in a new issue