From 02ab897f4fc0c72bd7af40f5139b5f122953701a Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Tue, 18 Jul 2023 22:17:21 +0200 Subject: [PATCH] Fix webfinger fetching non-compliance (#69) Allow webfinger to use "jrd+json" instead of "activity+json". Fix #68. --- src/fetch/mod.rs | 14 +++++++++++++- src/fetch/webfinger.rs | 9 +++++++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/fetch/mod.rs b/src/fetch/mod.rs index 7a9734c..28b709e 100644 --- a/src/fetch/mod.rs +++ b/src/fetch/mod.rs @@ -33,9 +33,21 @@ pub mod webfinger; /// If the value exceeds [FederationSettings.http_fetch_limit], the request is aborted with /// [Error::RequestLimit]. This prevents denial of service attacks where an attack triggers /// infinite, recursive fetching of data. +/// +/// The `Accept` header will be set to the content of [`FEDERATION_CONTENT_TYPE`]. pub async fn fetch_object_http( url: &Url, data: &Data, +) -> Result { + fetch_object_http_with_accept(url, data, FEDERATION_CONTENT_TYPE).await +} + +/// Fetch a remote object over HTTP and convert to `Kind`. This function works exactly as +/// [`fetch_object_http`] except that the `Accept` header is specified in `content_type`. +async fn fetch_object_http_with_accept( + url: &Url, + data: &Data, + content_type: &str, ) -> Result { let config = &data.config; // dont fetch local objects this way @@ -51,7 +63,7 @@ pub async fn fetch_object_http( let req = config .client .get(url.as_str()) - .header("Accept", FEDERATION_CONTENT_TYPE) + .header("Accept", content_type) .timeout(config.request_timeout); let res = if let Some((actor_id, private_key_pem)) = config.signed_fetch_actor.as_deref() { diff --git a/src/fetch/webfinger.rs b/src/fetch/webfinger.rs index 1ccf274..5a8a7ce 100644 --- a/src/fetch/webfinger.rs +++ b/src/fetch/webfinger.rs @@ -1,7 +1,7 @@ use crate::{ config::Data, error::{Error, Error::WebfingerResolveFailed}, - fetch::{fetch_object_http, object_id::ObjectId}, + fetch::{fetch_object_http_with_accept, object_id::ObjectId}, traits::{Actor, Object}, FEDERATION_CONTENT_TYPE, }; @@ -36,7 +36,9 @@ where format!("{protocol}://{domain}/.well-known/webfinger?resource=acct:{identifier}"); debug!("Fetching webfinger url: {}", &fetch_url); - let res: Webfinger = fetch_object_http(&Url::parse(&fetch_url)?, data).await?; + let res: Webfinger = + fetch_object_http_with_accept(&Url::parse(&fetch_url)?, data, "application/jrd+json") + .await?; debug_assert_eq!(res.subject, format!("acct:{identifier}")); let links: Vec = res @@ -231,5 +233,8 @@ mod tests { webfinger_resolve_actor::("LemmyDev@mastodon.social", &data) .await; assert!(res.is_ok()); + // poa.st is as of 2023-07-14 the largest Pleroma instance + let res = webfinger_resolve_actor::("graf@poa.st", &data).await; + assert!(res.is_ok()); } }