This commit is contained in:
Tangel 2024-12-16 10:31:49 +00:00 committed by GitHub
parent 80f175421f
commit 40117bdfdc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 14 additions and 45 deletions

View file

@ -238,9 +238,6 @@ pub(crate) fn generate_request_headers(inbox_url: &Url) -> HeaderMap {
mod tests { mod tests {
use super::*; use super::*;
use crate::{config::FederationConfig, http_signatures::generate_actor_keypair}; use crate::{config::FederationConfig, http_signatures::generate_actor_keypair};
use axum::extract::State;
use bytes::Bytes;
use http::StatusCode;
use std::{ use std::{
sync::{atomic::AtomicUsize, Arc}, sync::{atomic::AtomicUsize, Arc},
time::Instant, time::Instant,
@ -249,11 +246,7 @@ mod tests {
use tracing::info; use tracing::info;
// This will periodically send back internal errors to test the retry // This will periodically send back internal errors to test the retry
async fn dodgy_handler( async fn dodgy_handler(headers: HeaderMap, body: Bytes) -> Result<(), StatusCode> {
State(_state): State<Arc<AtomicUsize>>,
headers: http::HeaderMap,
body: Bytes,
) -> Result<(), StatusCode> {
debug!("Headers:{:?}", headers); debug!("Headers:{:?}", headers);
debug!("Body len:{}", body.len()); debug!("Body len:{}", body.len());
Ok(()) Ok(())

View file

@ -13,7 +13,6 @@ use crate::{
}; };
use actix_web::{web::Bytes, HttpRequest}; use actix_web::{web::Bytes, HttpRequest};
use serde::Deserialize; use serde::Deserialize;
use std::str::FromStr;
/// Checks whether the request is signed by an actor of type A, and returns /// Checks whether the request is signed by an actor of type A, and returns
/// the actor in question if a valid signature is found. /// the actor in question if a valid signature is found.
@ -27,29 +26,14 @@ where
<A as Object>::Error: From<Error>, <A as Object>::Error: From<Error>,
for<'de2> <A as Object>::Kind: Deserialize<'de2>, for<'de2> <A as Object>::Kind: Deserialize<'de2>,
{ {
let header_value = request let digest_header = request
.headers() .headers()
.get("Digest") .get("Digest")
.map(|v| reqwest::header::HeaderValue::from_str(v.to_str().unwrap_or_default())) .map(http_compat::header_value);
.and_then(std::result::Result::ok); verify_body_hash(digest_header.as_ref(), &body.unwrap_or_default())?;
verify_body_hash(header_value.as_ref(), &body.unwrap_or_default())?;
let mut vec = Vec::<(_, _)>::with_capacity(request.headers().len()); let headers = http_compat::header_map(request.headers());
request.headers().iter().for_each(|(k, v)| { let method = http_compat::method(request.method());
let k = reqwest::header::HeaderName::from_str(k.as_str()).expect("Failed to parse header"); let uri = http_compat::uri(request.uri());
let v = reqwest::header::HeaderValue::from_str(v.to_str().unwrap_or_default()) http_signatures::signing_actor(&headers, &method, &uri, data).await
.expect("Failed to parse header");
vec.push((k, v));
});
let headers = vec.iter().map(|(k, v)| (k, v)).collect::<Vec<(_, _)>>();
http_signatures::signing_actor(
headers,
&reqwest::Method::from_str(request.method().as_str())
.map_err(|err| Error::Other(err.to_string()))?,
&http::Uri::from_str(&request.uri().to_string())
.map_err(|err| Error::Other(err.to_string()))?,
data,
)
.await
} }

View file

@ -114,7 +114,7 @@ async fn fetch_object_http_with_accept<T: Clone, Kind: DeserializeOwned>(
let req = config let req = config
.client .client
.get(url.as_str()) .get(url.as_str())
.header("Accept", content_type.as_bytes()) .header("Accept", content_type)
.timeout(config.request_timeout); .timeout(config.request_timeout);
let res = if let Some((actor_id, private_key_pem)) = config.signed_fetch_actor.as_deref() { let res = if let Some((actor_id, private_key_pem)) = config.signed_fetch_actor.as_deref() {
@ -131,16 +131,12 @@ async fn fetch_object_http_with_accept<T: Clone, Kind: DeserializeOwned>(
req.send().await? req.send().await?
}; };
if res.status().as_u16() == StatusCode::GONE.as_u16() { if res.status() == StatusCode::GONE {
return Err(Error::ObjectDeleted(url.clone())); return Err(Error::ObjectDeleted(url.clone()));
} }
let url = res.url().clone(); let url = res.url().clone();
let content_type = res let content_type = res.headers().get("Content-Type").cloned();
.headers()
.get("Content-Type")
.cloned()
.and_then(|v| HeaderValue::from_maybe_shared(v).ok());
let text = res.bytes_limited().await?; let text = res.bytes_limited().await?;
let object_id = extract_id(&text).ok(); let object_id = extract_id(&text).ok();

View file

@ -14,16 +14,12 @@ use crate::{
}; };
use base64::{engine::general_purpose::STANDARD as Base64, Engine}; use base64::{engine::general_purpose::STANDARD as Base64, Engine};
use bytes::Bytes; use bytes::Bytes;
use http::{uri::PathAndQuery, Uri}; use http::{header::HeaderName, uri::PathAndQuery, HeaderValue, Method, Uri};
use http_signature_normalization_reqwest::{ use http_signature_normalization_reqwest::{
prelude::{Config, SignExt}, prelude::{Config, SignExt},
DefaultSpawner, DefaultSpawner,
}; };
use reqwest::{ use reqwest::Request;
header::{HeaderName, HeaderValue},
Method,
Request,
};
use reqwest_middleware::RequestBuilder; use reqwest_middleware::RequestBuilder;
use rsa::{ use rsa::{
pkcs8::{DecodePublicKey, EncodePrivateKey, EncodePublicKey, LineEnding}, pkcs8::{DecodePublicKey, EncodePrivateKey, EncodePublicKey, LineEnding},
@ -302,7 +298,7 @@ pub mod test {
// use hardcoded date in order to test against hardcoded signature // use hardcoded date in order to test against hardcoded signature
headers.insert( headers.insert(
"date", "date",
reqwest::header::HeaderValue::from_str("Tue, 28 Mar 2023 21:03:44 GMT").unwrap(), HeaderValue::from_str("Tue, 28 Mar 2023 21:03:44 GMT").unwrap(),
); );
let request_builder = ClientWithMiddleware::from(Client::new()) let request_builder = ClientWithMiddleware::from(Client::new())