mirror of
https://example.com
synced 2024-11-25 01:06:38 +09:00
feat (backend): permit redirects for AP object lookups
8d7d95fd23
Co-authored-by: naskya <m@naskya.net>
This commit is contained in:
parent
757f5f0e67
commit
519288317c
2 changed files with 32 additions and 4 deletions
|
@ -2,7 +2,7 @@ import * as http from "node:http";
|
|||
import * as https from "node:https";
|
||||
import type { URL } from "node:url";
|
||||
import CacheableLookup from "cacheable-lookup";
|
||||
import fetch from "node-fetch";
|
||||
import fetch, { RequestRedirect } from "node-fetch";
|
||||
import { HttpProxyAgent, HttpsProxyAgent } from "hpagent";
|
||||
import config from "@/config/index.js";
|
||||
import { isValidUrl } from "./is-valid-url.js";
|
||||
|
@ -58,6 +58,7 @@ export async function getResponse(args: {
|
|||
headers: Record<string, string>;
|
||||
timeout?: number;
|
||||
size?: number;
|
||||
redirect?: RequestRedirect;
|
||||
}) {
|
||||
if (!isValidUrl(args.url)) {
|
||||
throw new StatusError("Invalid URL", 400);
|
||||
|
@ -78,8 +79,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}`,
|
||||
|
|
|
@ -6,6 +6,7 @@ import { createSignedPost, createSignedGet } from "./ap-request.js";
|
|||
import type { Response } from "node-fetch";
|
||||
import type { IObject } from "./type.js";
|
||||
import { isValidUrl } from "@/misc/is-valid-url.js";
|
||||
import { apLogger } from "@/remote/activitypub/logger.js";
|
||||
|
||||
export default async (user: { id: User["id"] }, url: string, object: any) => {
|
||||
const body = JSON.stringify(object);
|
||||
|
@ -34,10 +35,15 @@ export default async (user: { id: User["id"] }, url: string, object: any) => {
|
|||
|
||||
/**
|
||||
* Get ActivityPub object
|
||||
* @param user http-signature user
|
||||
* @param url URL to fetch
|
||||
* @param user http-signature user
|
||||
* @param redirects whether or not to accept redirects
|
||||
*/
|
||||
export async function apGet(url: string, user?: ILocalUser): Promise<IObject> {
|
||||
export async function apGet(
|
||||
url: string,
|
||||
user?: ILocalUser,
|
||||
redirects: boolean = true
|
||||
): Promise<IObject> {
|
||||
if (!isValidUrl(url)) {
|
||||
throw new StatusError("Invalid URL", 400);
|
||||
}
|
||||
|
@ -61,7 +67,15 @@ export async function apGet(url: string, user?: ILocalUser): Promise<IObject> {
|
|||
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 == null) throw new Error("apGet got redirect but no target location");
|
||||
apLogger.debug(`apGet is redirecting to ${newUrl}`);
|
||||
return apGet(newUrl, user, false);
|
||||
}
|
||||
} else {
|
||||
res = await getResponse({
|
||||
url,
|
||||
|
@ -71,12 +85,20 @@ export async function apGet(url: string, user?: ILocalUser): Promise<IObject> {
|
|||
'application/activity+json, application/ld+json; profile="https://www.w3.org/ns/activitystreams"',
|
||||
"User-Agent": config.userAgent,
|
||||
},
|
||||
redirect: redirects ? "manual" : "error",
|
||||
});
|
||||
|
||||
if (redirects && [301, 302, 307, 308].includes(res.status)) {
|
||||
const newUrl = res.headers.get("location");
|
||||
if (newUrl == null) throw new Error("apGet got redirect but no target location");
|
||||
apLogger.debug(`apGet is redirecting to ${newUrl}`);
|
||||
return apGet(newUrl, undefined, false);
|
||||
}
|
||||
}
|
||||
|
||||
const contentType = res.headers.get("content-type");
|
||||
if (contentType == null || !validateContentType(contentType)) {
|
||||
throw new Error("Invalid Content Type");
|
||||
throw new Error(`apGet response had unexpected content-type: ${contentType}`);
|
||||
}
|
||||
|
||||
if (res.body == null) throw new Error("body is null");
|
||||
|
|
Loading…
Reference in a new issue