From 2cd31014b34ca7b0c27c7a921669af0e5511059b Mon Sep 17 00:00:00 2001 From: Felix Ableitner Date: Mon, 8 Apr 2024 14:49:01 +0200 Subject: [PATCH] Allow fetching from local domain in case it redirects to remote --- src/activity_sending.rs | 2 -- src/fetch/mod.rs | 11 ++++++++--- src/fetch/object_id.rs | 7 ------- src/traits.rs | 2 +- 4 files changed, 9 insertions(+), 13 deletions(-) diff --git a/src/activity_sending.rs b/src/activity_sending.rs index f16ef37..31eca80 100644 --- a/src/activity_sending.rs +++ b/src/activity_sending.rs @@ -19,7 +19,6 @@ use reqwest::header::{HeaderMap, HeaderName, HeaderValue}; use reqwest_middleware::ClientWithMiddleware; use serde::Serialize; use std::{ - self, fmt::{Debug, Display}, time::{Duration, SystemTime}, }; @@ -214,7 +213,6 @@ pub(crate) fn generate_request_headers(inbox_url: &Url) -> HeaderMap { mod tests { use super::*; use crate::{config::FederationConfig, http_signatures::generate_actor_keypair}; - use bytes::Bytes; use http::StatusCode; use std::{ sync::{atomic::AtomicUsize, Arc}, diff --git a/src/fetch/mod.rs b/src/fetch/mod.rs index 13ea16c..66af2fa 100644 --- a/src/fetch/mod.rs +++ b/src/fetch/mod.rs @@ -69,10 +69,11 @@ pub async fn fetch_object_http( return Err(Error::FetchInvalidContentType(res.url)); } - // Ensure id field matches final url + // Ensure id field matches final url after redirect if res.object_id.as_ref() != Some(&res.url) { return Err(Error::FetchWrongId(res.url)); } + Ok(res) } @@ -84,8 +85,6 @@ async fn fetch_object_http_with_accept( content_type: &HeaderValue, ) -> Result, Error> { let config = &data.config; - // dont fetch local objects this way - debug_assert!(url.domain() != Some(&config.domain)); config.verify_url_valid(url).await?; info!("Fetching remote object {}", url.to_string()); @@ -125,6 +124,12 @@ async fn fetch_object_http_with_accept( let text = res.bytes_limited().await?; let object_id = extract_id(&text).ok(); + // Dont allow fetching local object. Only check this after the request as a local url + // may redirect to a remote object. + if data.config.is_local_url(&url) { + return Err(Error::NotFound.into()); + } + match serde_json::from_slice(&text) { Ok(object) => Ok(FetchObjectResponse { object, diff --git a/src/fetch/object_id.rs b/src/fetch/object_id.rs index f3fa560..c64ff8b 100644 --- a/src/fetch/object_id.rs +++ b/src/fetch/object_id.rs @@ -88,13 +88,6 @@ where ::Error: From, { let db_object = self.dereference_from_db(data).await?; - // if its a local object, only fetch it from the database and not over http - if data.config.is_local_url(&self.0) { - return match db_object { - None => Err(Error::NotFound.into()), - Some(o) => Ok(o), - }; - } // object found in database if let Some(object) = db_object { diff --git a/src/traits.rs b/src/traits.rs index 9fdec27..720f731 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -343,7 +343,7 @@ pub mod tests { error::Error, fetch::object_id::ObjectId, http_signatures::{generate_actor_keypair, Keypair}, - protocol::{public_key::PublicKey, verification::verify_domains_match}, + protocol::verification::verify_domains_match, }; use activitystreams_kinds::{activity::FollowType, actor::PersonType}; use once_cell::sync::Lazy;