From 2c8d138cbd7a9d040d23bbc2d209133d0e15b41b Mon Sep 17 00:00:00 2001 From: httpjamesm Date: Mon, 31 Oct 2022 17:28:18 -0400 Subject: [PATCH] feat: cache media proxy data in redis for 30 mins --- package.json | 1 + src/pages/api/media_proxy.ts | 35 ++++++++++++++++++++++------------- src/utils/redis.ts | 11 +++++++++++ 3 files changed, 34 insertions(+), 13 deletions(-) create mode 100644 src/utils/redis.ts diff --git a/package.json b/package.json index 9f880f6..f3755ba 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "dependencies": { "axios": "^0.27.2", "cheerio": "1.0.0-rc.12", + "ioredis": "^5.2.3", "next": "12.2.5", "node-fetch": "^3.2.10", "react": "18.2.0", diff --git a/src/pages/api/media_proxy.ts b/src/pages/api/media_proxy.ts index 98b9c93..78a75c1 100644 --- a/src/pages/api/media_proxy.ts +++ b/src/pages/api/media_proxy.ts @@ -1,5 +1,7 @@ import { NextApiRequest, NextApiResponse } from 'next' import fetch from 'node-fetch' +import redis from '../../utils/redis' +import crypto from 'crypto' const acceptableExtensions = ['.jpg', '.png', '.gif', '.webp'] @@ -56,6 +58,22 @@ export default async function handler( return } + // hash mediaUrl with blake3 + const mediaUrlHash = await crypto + .createHash('sha256') + .update(mediaUrl) + .digest('base64') + + // try to find mediaUrlHash in redis + const cacheKey = `media_proxy:${mediaUrlHash}` + + const cachedMedia = await redis.get(cacheKey) + + if (cachedMedia) { + res.send(cachedMedia) + return + } + // download media const mediaRes = await fetch(mediaUrl) @@ -64,20 +82,11 @@ export default async function handler( return } - // get media type - const mediaType = mediaRes.headers.get('content-type') + const mediaBuffer = Buffer.from(await mediaRes.arrayBuffer()) - if (!mediaType) { - res.status(500) - res.send(null) - return - } - - // set media type - res.setHeader('content-type', mediaType) - - const mediaBuffer = await mediaRes.arrayBuffer() + // save in redis for 30 minutes + await redis.setex(cacheKey, 60 * 30, mediaBuffer) // send media - res.send(Buffer.from(mediaBuffer)) + res.send(mediaBuffer) } diff --git a/src/utils/redis.ts b/src/utils/redis.ts new file mode 100644 index 0000000..eb87c77 --- /dev/null +++ b/src/utils/redis.ts @@ -0,0 +1,11 @@ +import Redis from 'ioredis' + +const redisUrl = process.env.REDIS_URL + +if (!redisUrl) { + throw 'Please set the REDIS_URL environment variable.' +} + +const redis = new Redis(redisUrl) + +export default redis