diff --git a/packages/backend/src/misc/fetch.ts b/packages/backend/src/misc/fetch.ts index 0e673ba3a..ff9cf6e0c 100644 --- a/packages/backend/src/misc/fetch.ts +++ b/packages/backend/src/misc/fetch.ts @@ -57,6 +57,7 @@ export async function getResponse(args: { headers: Record; timeout?: number; size?: number; + redirect?: RequestRedirect; }) { const timeout = args.timeout || 10 * 1000; @@ -73,8 +74,13 @@ export async function getResponse(args: { size: args.size || 10 * 1024 * 1024, agent: getAgentByUrl, signal: controller.signal, + redirect: args.redirect }); + if (args.redirect === "manual" && [301,302,307,308].includes(res.status)) { + return res; + } + if (!res.ok) { throw new StatusError( `${res.status} ${res.statusText}`, diff --git a/packages/backend/src/remote/activitypub/request.ts b/packages/backend/src/remote/activitypub/request.ts index 69c97a445..ef35fd45d 100644 --- a/packages/backend/src/remote/activitypub/request.ts +++ b/packages/backend/src/remote/activitypub/request.ts @@ -34,8 +34,9 @@ export default async (user: { id: User["id"] }, url: string, object: any) => { * Get AP object with http-signature * @param user http-signature user * @param url URL to fetch + * @param redirects whether or not to accept redirects */ -export async function signedGet(url: string, user: { id: User["id"] }) { +export async function signedGet(url: string, user: { id: User["id"] }, redirects: boolean = true) { apLogger.debug(`Running signedGet on url: ${url}`); const keypair = await getUserKeypair(user.id); @@ -54,7 +55,15 @@ export async function signedGet(url: string, user: { id: User["id"] }) { url, method: req.request.method, headers: req.request.headers, + redirect: redirects ? "manual" : "error" }); + if (redirects && [301,302,307,308].includes(res.status)) { + const newUrl = res.headers.get('location'); + if (!newUrl) throw new Error('signedGet got redirect but no target location'); + apLogger.debug(`signedGet is redirecting to ${newUrl}`); + return signedGet(newUrl, user, false); + } + return await res.json(); }