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 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>
|
pub async fn fetch<T>(client: &reqwest::Client, url: &str) -> Result<T, reqwest::Error>
|
||||||
where
|
where
|
||||||
|
@ -11,3 +15,38 @@ where
|
||||||
.json()
|
.json()
|
||||||
.await
|
.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 config;
|
||||||
mod actor;
|
mod actor;
|
||||||
mod db;
|
mod db;
|
||||||
|
mod digest;
|
||||||
mod fetch;
|
mod fetch;
|
||||||
pub use fetch::fetch;
|
|
||||||
mod send;
|
mod send;
|
||||||
mod stream;
|
mod stream;
|
||||||
mod relay;
|
mod relay;
|
||||||
|
|
17
src/send.rs
17
src/send.rs
|
@ -47,22 +47,11 @@ pub async fn send_raw(
|
||||||
private_key: &PrivateKey,
|
private_key: &PrivateKey,
|
||||||
body: Arc<Vec<u8>>,
|
body: Arc<Vec<u8>>,
|
||||||
) -> Result<(), SendError> {
|
) -> 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)
|
let url = reqwest::Url::parse(uri)
|
||||||
.map_err(|_| SendError::InvalidUri)?;
|
.map_err(|_| Error::InvalidUri)?;
|
||||||
let host = format!("{}", url.host().ok_or(SendError::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()
|
let mut req = http::Request::builder()
|
||||||
.method("POST")
|
.method("POST")
|
||||||
.uri(uri)
|
.uri(uri)
|
||||||
|
|
Loading…
Reference in a new issue