fix: don't http sign proxy cloaks

This commit is contained in:
əlemi 2024-07-17 21:32:59 +02:00
parent d9d7acbe98
commit 018a399ee3
Signed by: alemi
GPG key ID: A4895B84D311642C
2 changed files with 19 additions and 15 deletions

View file

@ -99,6 +99,13 @@ pub trait Fetcher {
async fn fetch_thread(&self, id: &str, tx: &impl ConnectionTrait) -> Result<(), RequestError>; async fn fetch_thread(&self, id: &str, tx: &impl ConnectionTrait) -> Result<(), RequestError>;
fn client(domain: &str) -> reqwest::Client {
reqwest::Client::builder()
.user_agent(format!("upub+{} ({domain})", crate::VERSION))
.build()
.expect("failed building http client, check system tls or resolver")
}
async fn request( async fn request(
method: reqwest::Method, method: reqwest::Method,
url: &str, url: &str,
@ -130,11 +137,10 @@ pub trait Fetcher {
.build_manually(&method.to_string().to_lowercase(), &path, headers_map) .build_manually(&method.to_string().to_lowercase(), &path, headers_map)
.sign(key)?; .sign(key)?;
let response = reqwest::Client::new() let response = Self::client(domain)
.request(method.clone(), url) .request(method, url)
.header(ACCEPT, "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"") .header(ACCEPT, "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"")
.header(CONTENT_TYPE, "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"") .header(CONTENT_TYPE, "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"")
.header(USER_AGENT, format!("upub+{} ({domain})", crate::VERSION))
.header("Host", host.clone()) .header("Host", host.clone())
.header("Date", date.clone()) .header("Date", date.clone())
.header("Digest", digest) .header("Digest", digest)

View file

@ -3,7 +3,7 @@ use axum::{extract::{Path, Query, State}, http::HeaderMap, response::{IntoRespon
use reqwest::Method; use reqwest::Method;
use upub::{traits::{Cloaker, Fetcher}, Context}; use upub::{traits::{Cloaker, Fetcher}, Context};
use crate::{builders::JsonLD, ApiError, ApiResult, AuthIdentity, Identity}; use crate::{builders::JsonLD, ApiError, AuthIdentity};
pub async fn view( pub async fn view(
@ -76,20 +76,18 @@ pub async fn cloak_proxy(
let uri = ctx.uncloak(&hmac, &uri) let uri = ctx.uncloak(&hmac, &uri)
.ok_or_else(ApiError::unauthorized)?; .ok_or_else(ApiError::unauthorized)?;
let resp = Context::request( let resp = Context::client(ctx.domain())
Method::GET, .get(uri)
&uri, .send()
None, .await?
ctx.base(), .error_for_status()?;
ctx.pkey(),
&format!("{}+proxy", ctx.domain()),
)
.await?
.error_for_status()?;
let headers = resp.headers().clone(); let headers = resp.headers().clone();
// TODO can we stream the response body as it comes?
let body = resp.bytes().await?.to_vec(); let body = resp.bytes().await?.to_vec();
// TODO not so great to just try parsing json, but this should be a cheap check as most things we
// proxy are not json (as in, dont start with '{')
if serde_json::from_slice::<serde_json::Value>(&body).is_ok() { if serde_json::from_slice::<serde_json::Value>(&body).is_ok() {
return Err(ApiError::forbidden()); return Err(ApiError::forbidden());
} }