diff --git a/src/fetch/mod.rs b/src/fetch/mod.rs index 3bb9e18..424a115 100644 --- a/src/fetch/mod.rs +++ b/src/fetch/mod.rs @@ -59,7 +59,7 @@ pub async fn fetch_object_http( r#"application/ld+json; profile="https://www.w3.org/ns/activitystreams""#, // activitypub standard r#"application/activity+json; charset=utf-8"#, // mastodon ]; - let res = fetch_object_http_with_accept(url, data, &FETCH_CONTENT_TYPE).await?; + let res = fetch_object_http_with_accept(url, data, &FETCH_CONTENT_TYPE, false).await?; // Ensure correct content-type to prevent vulnerabilities, with case insensitive comparison. let content_type = res @@ -100,6 +100,7 @@ async fn fetch_object_http_with_accept( url: &Url, data: &Data, content_type: &HeaderValue, + recursive: bool, ) -> Result, Error> { let config = &data.config; config.verify_url_valid(url).await?; @@ -132,10 +133,17 @@ async fn fetch_object_http_with_accept( req.send().await? }; + // Allow a single redirect using recursion. Further redirects are ignored. let location = res.headers().get(LOCATION).and_then(|l| l.to_str().ok()); - if let Some(location) = location { + if let (Some(location), false) = (location, recursive) { let location = location.parse()?; - return Box::pin(fetch_object_http_with_accept(&location, data, content_type)).await; + return Box::pin(fetch_object_http_with_accept( + &location, + data, + content_type, + true, + )) + .await; } if res.status() == StatusCode::GONE { diff --git a/src/fetch/webfinger.rs b/src/fetch/webfinger.rs index 5f3b456..8d53078 100644 --- a/src/fetch/webfinger.rs +++ b/src/fetch/webfinger.rs @@ -69,6 +69,7 @@ where &Url::parse(&fetch_url).map_err(Error::UrlParse)?, data, &WEBFINGER_CONTENT_TYPE, + false, ) .await?; if res.url.as_str() != fetch_url {