2023-10-07 01:25:43 +00:00
|
|
|
use std::time::SystemTime;
|
2023-05-14 20:44:26 +00:00
|
|
|
use http::StatusCode;
|
2022-12-11 00:07:39 +00:00
|
|
|
use serde::de::DeserializeOwned;
|
2023-05-14 20:44:26 +00:00
|
|
|
use sigh::{PrivateKey, SigningConfig, alg::RsaSha256};
|
2024-06-07 00:18:11 +00:00
|
|
|
use tokio::task::spawn_blocking;
|
2023-05-14 20:58:00 +00:00
|
|
|
use crate::{digest, error::Error};
|
2022-12-11 00:07:39 +00:00
|
|
|
|
2023-05-14 20:44:26 +00:00
|
|
|
pub async fn authorized_fetch<T>(
|
|
|
|
client: &reqwest::Client,
|
|
|
|
uri: &str,
|
|
|
|
key_id: &str,
|
|
|
|
private_key: &PrivateKey,
|
2023-05-14 20:58:00 +00:00
|
|
|
) -> Result<T, Error>
|
2023-05-14 20:44:26 +00:00
|
|
|
where
|
|
|
|
T: DeserializeOwned,
|
|
|
|
{
|
|
|
|
let url = reqwest::Url::parse(uri)
|
2023-05-14 20:58:00 +00:00
|
|
|
.map_err(|_| Error::InvalidUri)?;
|
|
|
|
let host = format!("{}", url.host().ok_or(Error::InvalidUri)?);
|
2023-05-14 20:44:26 +00:00
|
|
|
let digest_header = digest::generate_header(&[])
|
|
|
|
.expect("digest::generate_header");
|
|
|
|
let mut req = http::Request::builder()
|
|
|
|
.uri(uri)
|
|
|
|
.header("host", &host)
|
|
|
|
.header("content-type", "application/activity+json")
|
2023-10-07 01:25:43 +00:00
|
|
|
.header("date", httpdate::fmt_http_date(SystemTime::now()))
|
2023-05-14 20:44:26 +00:00
|
|
|
.header("accept", "application/activity+json")
|
|
|
|
.header("digest", digest_header)
|
|
|
|
.body(vec![])?;
|
2024-06-07 00:18:11 +00:00
|
|
|
let private_key = private_key.clone();
|
|
|
|
let key_id = key_id.to_string();
|
|
|
|
let req = spawn_blocking(move || {
|
|
|
|
SigningConfig::new(RsaSha256, &private_key, &key_id).sign(&mut req)?;
|
|
|
|
Ok(req)
|
|
|
|
})
|
|
|
|
.await
|
|
|
|
.map_err(|e| Error::Response(format!("{e}")))?
|
|
|
|
.map_err(|e: sigh::Error| Error::Response(format!("{e}")))?;
|
2023-05-14 20:44:26 +00:00
|
|
|
let req: reqwest::Request = req.try_into()?;
|
2024-06-07 00:18:11 +00:00
|
|
|
let res = client.execute(req).await?;
|
2023-05-14 20:44:26 +00:00
|
|
|
if res.status() >= StatusCode::OK && res.status() < StatusCode::MULTIPLE_CHOICES {
|
|
|
|
Ok(res.json().await?)
|
|
|
|
} else {
|
2023-05-14 21:29:36 +00:00
|
|
|
Err(Error::Response(res.text().await?))
|
2023-05-14 20:44:26 +00:00
|
|
|
}
|
|
|
|
}
|