mirror of
https://github.com/PreMiD/PreMiD.git
synced 2026-04-05 20:31:58 +02:00
fix: return image directly
This commit is contained in:
@@ -98,4 +98,31 @@ describe("getFullLink", async () => {
|
||||
expect(result.headers.get("content-type")).toBe("image/png");
|
||||
expect(Buffer.from(await result.arrayBuffer())).toStrictEqual(imageBuffer);
|
||||
});
|
||||
|
||||
it("should fetch and return PNG image instead of redirecting for URLs with .png extension", async () => {
|
||||
const testUrl = `https://cdn.rcd.gg/PreMiD/resources/reading.png?v=${"a".repeat(250)}`;
|
||||
|
||||
const { body } = await server.inject({
|
||||
url: `/create/${testUrl}`,
|
||||
});
|
||||
|
||||
expect(body).toStrictEqual(expect.any(String));
|
||||
|
||||
vi.spyOn(isInCIDRRange, "default").mockReturnValueOnce(true);
|
||||
|
||||
const result = await fetch(`${url}${body}`, {
|
||||
headers: {
|
||||
"cf-connecting-ip": "",
|
||||
},
|
||||
});
|
||||
|
||||
expect(result.status).toBe(200);
|
||||
expect(result.headers.get("content-type")).toMatch(/^image\//);
|
||||
//* Should return image data, not redirect
|
||||
expect(result.headers.get("location")).toBeNull();
|
||||
|
||||
//* Verify we got actual image data
|
||||
const imageBuffer = await result.arrayBuffer();
|
||||
expect(imageBuffer.byteLength).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -34,18 +34,49 @@ const handler: RouteHandlerMethod = async (request, reply) => {
|
||||
await Promise.all([keyv.set(hash, id, 30 * 60 * 1000), keyv.set(id, url, 30 * 60 * 1000)]);
|
||||
void reply.header("Cache-control", "public, max-age=1800");
|
||||
|
||||
//* If it is not a base64 string, redirect to it
|
||||
if (!url.startsWith("data:image"))
|
||||
return reply.redirect(url);
|
||||
//* If it is a base64 string, decode and return the image
|
||||
if (url.startsWith("data:image")) {
|
||||
const image = Buffer.from(
|
||||
url.replace(/^data:image\/\w+;base64,/, ""),
|
||||
"base64",
|
||||
);
|
||||
|
||||
const image = Buffer.from(
|
||||
url.replace(/^data:image\/\w+;base64,/, ""),
|
||||
"base64",
|
||||
);
|
||||
const mime = url.split(";")[0]!.split(":")[1]!;
|
||||
|
||||
const mime = url.split(";")[0]!.split(":")[1]!;
|
||||
return reply.type(mime).send(image);
|
||||
}
|
||||
|
||||
return reply.type(mime).send(image);
|
||||
//* Check if URL has a valid image extension
|
||||
const urlObject = new URL(url);
|
||||
const pathname = urlObject.pathname;
|
||||
const extensionMatch = pathname.match(/\.([^./]+)$/);
|
||||
const extension = extensionMatch?.[1]?.toLowerCase() ?? null;
|
||||
|
||||
const allowedExtensions = ["png", "jpeg", "jpg", "gif", "webp"];
|
||||
const hasValidImageExtension = extension && allowedExtensions.includes(extension);
|
||||
|
||||
//* If URL has valid image extension, fetch and return the image
|
||||
if (hasValidImageExtension) {
|
||||
try {
|
||||
const response = await fetch(url);
|
||||
|
||||
if (!response.ok) {
|
||||
return reply.code(404).send("Image not found");
|
||||
}
|
||||
|
||||
const contentType = response.headers.get("content-type") || `image/${extension}`;
|
||||
const imageBuffer = Buffer.from(await response.arrayBuffer());
|
||||
|
||||
return reply.type(contentType).send(imageBuffer);
|
||||
}
|
||||
catch {
|
||||
//* If fetch fails, fall back to redirect
|
||||
return reply.redirect(url);
|
||||
}
|
||||
}
|
||||
|
||||
//* For all other URLs, redirect to them
|
||||
return reply.redirect(url);
|
||||
};
|
||||
|
||||
export default handler;
|
||||
|
||||
Reference in New Issue
Block a user