From b467df07d29c2f2cb992981cea59dcda26c7bc3a Mon Sep 17 00:00:00 2001 From: Yufan Sheng Date: Tue, 25 Jun 2024 21:08:44 +0800 Subject: [PATCH] feat: add avatar fetch for cdn with origin limit. --- src/pages/avatar/[hash].png.ts | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/pages/avatar/[hash].png.ts b/src/pages/avatar/[hash].png.ts index 45d3138..ad8ccf1 100644 --- a/src/pages/avatar/[hash].png.ts +++ b/src/pages/avatar/[hash].png.ts @@ -1,7 +1,7 @@ import { queryEmail } from '@/helpers/db/query'; import { encodedEmail, urlJoin } from '@/helpers/tools'; import options from '@/options'; -import type { APIRoute } from 'astro'; +import type { APIRoute, ValidRedirectStatus } from 'astro'; const defaultAvatar = (): string => { 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)); } -const avatarImage = async (hash: string): Promise => { +const avatarImage = async ( + hash: string, + redirect: (path: string, status?: ValidRedirectStatus) => Response, +): Promise => { + const defaultAvatarLink = defaultAvatar(); const link = urlJoin( 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' }, }); }; @@ -33,8 +43,8 @@ export const GET: APIRoute = async ({ params, redirect }) => { if (email === null) { return redirect(defaultAvatar()); } - return avatarImage(encodedEmail(email)); + return avatarImage(encodedEmail(email), redirect); } - return avatarImage(hash); + return avatarImage(hash, redirect); };