UNPKG

astro

Version:

Astro is a modern site builder with web best practices, performance, and DX front-of-mind.

52 lines (51 loc) • 2.07 kB
// @ts-expect-error import { imageConfig } from "astro:assets"; import { isRemotePath } from "@astrojs/internal-helpers/path"; import { isRemoteAllowed } from "@astrojs/internal-helpers/remote"; import * as mime from "mrmime"; import { getConfiguredImageService } from "../internal.js"; import { etag } from "../utils/etag.js"; import { loadImage } from "./loadImage.js"; /** * Endpoint used in dev and SSR to serve optimized images by the base image services */ export const GET = async ({ request, logger }) => { try { const imageService = await getConfiguredImageService(); if (!("transform" in imageService)) { throw new Error("Configured image service is not a local service"); } const url = new URL(request.url); const transform = await imageService.parseURL(url, imageConfig, logger); if (!transform?.src) { throw new Error("Incorrect transform returned by `parseURL`"); } let inputBuffer = undefined; const isRemoteImage = isRemotePath(transform.src); if (isRemoteImage && isRemoteAllowed(transform.src, imageConfig) === false) { return new Response("Forbidden", { status: 403 }); } const sourceUrl = new URL(transform.src, url.origin); // Have we been tricked into thinking this is local? if (!isRemoteImage && sourceUrl.origin !== url.origin) { return new Response("Forbidden", { status: 403 }); } inputBuffer = await loadImage(sourceUrl, isRemoteImage ? new Headers() : request.headers, imageConfig, isRemoteImage); if (!inputBuffer) { return new Response("Not Found", { status: 404 }); } const { data, format } = await imageService.transform(new Uint8Array(inputBuffer), transform, imageConfig, logger); return new Response(data, { status: 200, headers: { "Content-Type": mime.lookup(format) ?? `image/${format}`, "Cache-Control": "public, max-age=31536000", ETag: etag(data.toString()), Date: new Date().toUTCString() } }); } catch (err) { logger.error(`Could not process image request: ${err}`); return new Response("Internal Server Error", { status: 500 }); } };