feat: correctly cache images with redis

This commit is contained in:
2023-07-30 18:27:45 +02:00
parent 1917fc7d8f
commit af8adf9ce7
17 changed files with 321 additions and 121 deletions

View File

@ -5,7 +5,7 @@ import {
MagickGeometry,
} from "https://deno.land/x/imagemagick_deno@0.0.14/mod.ts";
import { parseMediaType } from "https://deno.land/std@0.175.0/media_types/parse_media_type.ts";
import * as cache from "@lib/cache.ts";
import * as cache from "@lib/cache/image.ts";
await initializeImageMagick();
@ -56,6 +56,11 @@ function modifyImage(
}
function parseParams(reqUrl: URL) {
const image = reqUrl.searchParams.get("image")?.replace(/^\//, "");
if (image == null) {
return "Missing 'image' query parameter.";
}
const height = Number(reqUrl.searchParams.get("height")) || 0;
const width = Number(reqUrl.searchParams.get("width")) || 0;
if (height === 0 && width === 0) {
@ -69,50 +74,36 @@ function parseParams(reqUrl: URL) {
return `Width and height cannot exceed ${maxDimension}.`;
}
return {
image,
height,
width,
};
}
async function getImageResponse(
remoteImage: { buffer: Uint8Array; mediaType: string },
params: { width: number; height: number },
): Promise<Response> {
const modifiedImage = await modifyImage(remoteImage.buffer, {
...params,
mode: "resize",
});
const response = new Response(modifiedImage, {
headers: {
"Content-Type": remoteImage.mediaType,
},
});
return response;
}
export const handler = async (
_req: Request,
_ctx: HandlerContext,
): Promise<Response> => {
const imageUrl = Deno.env.get("SILVERBULLET_SERVER") + "/Recipes/images/" +
_ctx.params.image;
const url = new URL(_req.url);
const params = parseParams(url);
if (typeof params === "string") {
return new Response(params, { status: 400 });
}
const imageId = `${imageUrl}.${params.width}.${params.height}`;
const cachedResponse = await cache.get(imageId);
const imageUrl = Deno.env.get("SILVERBULLET_SERVER") + "/" + params.image;
const cachedResponse = await cache.getImage({
url: imageUrl,
width: params.width,
height: params.height,
});
if (cachedResponse) {
const _r = await cachedResponse;
console.log({ cachedResponse, _r });
return (await cachedResponse).clone();
return new Response(cachedResponse.buffer.slice(), {
headers: {
"Content-Type": cachedResponse.mediaType,
},
});
}
const remoteImage = await getRemoteImage(imageUrl);
@ -120,9 +111,21 @@ export const handler = async (
return new Response(remoteImage, { status: 400 });
}
const response = getImageResponse(remoteImage, params);
const modifiedImage = await modifyImage(remoteImage.buffer, {
...params,
mode: "resize",
});
await cache.set(imageId, response);
cache.setImage(modifiedImage, {
url: imageUrl,
width: params.width,
height: params.height,
mediaType: remoteImage.mediaType,
});
return response;
return new Response(modifiedImage, {
headers: {
"Content-Type": remoteImage.mediaType,
},
});
};