From a2ac97db98c82b9bdfddcec73fcc84451ffea8aa Mon Sep 17 00:00:00 2001 From: Nutomic Date: Tue, 9 Apr 2024 11:28:22 +0200 Subject: [PATCH] Allow fetching from local domain in case it redirects to remote (#104) * Allow fetching from local domain in case it redirects to remote * clippy * fix lemmy tests --- examples/local_federation/instance.rs | 1 + src/fetch/mod.rs | 11 ++++++++--- src/fetch/object_id.rs | 12 +++--------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/examples/local_federation/instance.rs b/examples/local_federation/instance.rs index f377f31..ad1fd12 100644 --- a/examples/local_federation/instance.rs +++ b/examples/local_federation/instance.rs @@ -28,6 +28,7 @@ pub async fn new_instance( .domain(hostname) .signed_fetch_actor(&system_user) .app_data(database) + .url_verifier(Box::new(MyUrlVerifier())) .debug(true) .build() .await?; diff --git a/src/fetch/mod.rs b/src/fetch/mod.rs index 13ea16c..4d563b6 100644 --- a/src/fetch/mod.rs +++ b/src/fetch/mod.rs @@ -69,10 +69,17 @@ 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)); } + + // 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(&res.url) { + return Err(Error::NotFound); + } + Ok(res) } @@ -84,8 +91,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()); diff --git a/src/fetch/object_id.rs b/src/fetch/object_id.rs index 061a9f5..50e75bc 100644 --- a/src/fetch/object_id.rs +++ b/src/fetch/object_id.rs @@ -88,19 +88,13 @@ 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 { - // object is old and should be refetched if let Some(last_refreshed_at) = object.last_refreshed_at() { - if should_refetch_object(last_refreshed_at) { + let is_local = data.config.is_local_url(&self.0); + if !is_local && should_refetch_object(last_refreshed_at) { + // object is outdated and should be refetched return self.dereference_from_http(data, Some(object)).await; } }