feat: add avatar fetch for cdn with origin limit.

This commit is contained in:
Yufan Sheng 2024-06-25 21:08:44 +08:00
parent 8ace254a0f
commit 7be74bb174
Signed by: syhily
GPG Key ID: DEB186763C308C31

View File

@ -1,7 +1,7 @@
import { queryEmail } from '@/helpers/db/query'; import { queryEmail } from '@/helpers/db/query';
import { encodedEmail, urlJoin } from '@/helpers/tools'; import { encodedEmail, urlJoin } from '@/helpers/tools';
import options from '@/options'; import options from '@/options';
import type { APIRoute } from 'astro'; import type { APIRoute, ValidRedirectStatus } from 'astro';
const defaultAvatar = (): string => { const defaultAvatar = (): string => {
return urlJoin(options.assetsPrefix(), '/images/default-avatar.png'); return urlJoin(options.assetsPrefix(), '/images/default-avatar.png');
@ -11,12 +11,22 @@ function isNumeric(str: string) {
return !Number.isNaN(str) && !Number.isNaN(Number.parseFloat(str)); return !Number.isNaN(str) && !Number.isNaN(Number.parseFloat(str));
} }
const avatarImage = async (hash: string): Promise<Response> => { const avatarImage = async (
hash: string,
redirect: (path: string, status?: ValidRedirectStatus) => Response,
): Promise<Response> => {
const defaultAvatarLink = defaultAvatar();
const link = urlJoin( const link = urlJoin(
options.settings.comments.avatar.mirror, options.settings.comments.avatar.mirror,
`${hash}.png?s=${options.settings.comments.avatar.size}&d=${defaultAvatar()}`, `${hash}.png?s=${options.settings.comments.avatar.size}&d=${defaultAvatarLink}`,
); );
return new Response(Buffer.from(await (await fetch(link)).arrayBuffer()), {
const resp = await fetch(link, { redirect: 'manual', headers: { Referer: options.website } });
if (resp.headers.get('location') === defaultAvatarLink) {
return redirect(defaultAvatarLink, 302);
}
return new Response(Buffer.from(await resp.arrayBuffer()), {
headers: { 'Content-Type': 'image/png' }, headers: { 'Content-Type': 'image/png' },
}); });
}; };
@ -33,8 +43,8 @@ export const GET: APIRoute = async ({ params, redirect }) => {
if (email === null) { if (email === null) {
return redirect(defaultAvatar()); return redirect(defaultAvatar());
} }
return avatarImage(encodedEmail(email)); return avatarImage(encodedEmail(email), redirect);
} }
return avatarImage(hash); return avatarImage(hash, redirect);
}; };