mirror of
https://github.com/astro/buzzrelay.git
synced 2024-11-22 04:00:59 +00:00
fetch: add authorized_fetch()
This commit is contained in:
parent
c0601f8eef
commit
e8b2b807b2
4 changed files with 63 additions and 15 deletions
20
src/digest.rs
Normal file
20
src/digest.rs
Normal file
|
@ -0,0 +1,20 @@
|
|||
use http_digest_headers::{DigestHeader, DigestMethod};
|
||||
|
||||
pub fn generate_header(body: &[u8]) -> Result<String, ()> {
|
||||
let mut digest_header = DigestHeader::new()
|
||||
.with_method(DigestMethod::SHA256, body)
|
||||
.map(|h| format!("{}", h))
|
||||
.map_err(|_| ())?;
|
||||
|
||||
// mastodon expects uppercase algo name
|
||||
if digest_header.starts_with("sha-") {
|
||||
digest_header.replace_range(..4, "SHA-");
|
||||
}
|
||||
// mastodon uses base64::alphabet::STANDARD, not base64::alphabet::URL_SAFE
|
||||
digest_header.replace_range(
|
||||
7..,
|
||||
&digest_header[7..].replace('-', "+").replace('_', "/")
|
||||
);
|
||||
|
||||
Ok(digest_header)
|
||||
}
|
39
src/fetch.rs
39
src/fetch.rs
|
@ -1,4 +1,8 @@
|
|||
use http::StatusCode;
|
||||
use serde::de::DeserializeOwned;
|
||||
use sigh::{PrivateKey, SigningConfig, alg::RsaSha256};
|
||||
use crate::digest;
|
||||
use crate::send::SendError;
|
||||
|
||||
pub async fn fetch<T>(client: &reqwest::Client, url: &str) -> Result<T, reqwest::Error>
|
||||
where
|
||||
|
@ -11,3 +15,38 @@ where
|
|||
.json()
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn authorized_fetch<T>(
|
||||
client: &reqwest::Client,
|
||||
uri: &str,
|
||||
key_id: &str,
|
||||
private_key: &PrivateKey,
|
||||
) -> Result<T, SendError>
|
||||
where
|
||||
T: DeserializeOwned,
|
||||
{
|
||||
let url = reqwest::Url::parse(uri)
|
||||
.map_err(|_| SendError::InvalidUri)?;
|
||||
let host = format!("{}", url.host().ok_or(SendError::InvalidUri)?);
|
||||
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")
|
||||
.header("date", chrono::Utc::now().to_rfc2822()
|
||||
.replace("+0000", "GMT"))
|
||||
.header("accept", "application/activity+json")
|
||||
.header("digest", digest_header)
|
||||
.body(vec![])?;
|
||||
SigningConfig::new(RsaSha256, private_key, key_id)
|
||||
.sign(&mut req)?;
|
||||
let req: reqwest::Request = req.try_into()?;
|
||||
let res = client.execute(req)
|
||||
.await?;
|
||||
if res.status() >= StatusCode::OK && res.status() < StatusCode::MULTIPLE_CHOICES {
|
||||
Ok(res.json().await?)
|
||||
} else {
|
||||
Err(SendError::Response(format!("{}", res.text().await?)))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,8 +17,8 @@ use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
|||
mod config;
|
||||
mod actor;
|
||||
mod db;
|
||||
mod digest;
|
||||
mod fetch;
|
||||
pub use fetch::fetch;
|
||||
mod send;
|
||||
mod stream;
|
||||
mod relay;
|
||||
|
|
17
src/send.rs
17
src/send.rs
|
@ -47,22 +47,11 @@ pub async fn send_raw(
|
|||
private_key: &PrivateKey,
|
||||
body: Arc<Vec<u8>>,
|
||||
) -> Result<(), SendError> {
|
||||
let mut digest_header = DigestHeader::new()
|
||||
.with_method(DigestMethod::SHA256, &body)
|
||||
.map(|h| format!("{}", h))
|
||||
.map_err(|_| SendError::Digest)?;
|
||||
if digest_header.starts_with("sha-") {
|
||||
digest_header.replace_range(..4, "SHA-");
|
||||
}
|
||||
// mastodon uses base64::alphabet::STANDARD, not base64::alphabet::URL_SAFE
|
||||
digest_header.replace_range(
|
||||
7..,
|
||||
&digest_header[7..].replace('-', "+").replace('_', "/")
|
||||
);
|
||||
|
||||
let url = reqwest::Url::parse(uri)
|
||||
.map_err(|_| SendError::InvalidUri)?;
|
||||
.map_err(|_| Error::InvalidUri)?;
|
||||
let host = format!("{}", url.host().ok_or(SendError::InvalidUri)?);
|
||||
let digest_header = digest::generate_header(&body)
|
||||
.map_err(|()| SendError::Digest)?;
|
||||
let mut req = http::Request::builder()
|
||||
.method("POST")
|
||||
.uri(uri)
|
||||
|
|
Loading…
Reference in a new issue