feat: cache media proxy data in redis for 30 mins

This commit is contained in:
httpjamesm 2022-10-31 17:28:18 -04:00
parent 59a314b2bd
commit 2c8d138cbd
3 changed files with 34 additions and 13 deletions

View File

@ -15,6 +15,7 @@
"dependencies": { "dependencies": {
"axios": "^0.27.2", "axios": "^0.27.2",
"cheerio": "1.0.0-rc.12", "cheerio": "1.0.0-rc.12",
"ioredis": "^5.2.3",
"next": "12.2.5", "next": "12.2.5",
"node-fetch": "^3.2.10", "node-fetch": "^3.2.10",
"react": "18.2.0", "react": "18.2.0",

View File

@ -1,5 +1,7 @@
import { NextApiRequest, NextApiResponse } from 'next' import { NextApiRequest, NextApiResponse } from 'next'
import fetch from 'node-fetch' import fetch from 'node-fetch'
import redis from '../../utils/redis'
import crypto from 'crypto'
const acceptableExtensions = ['.jpg', '.png', '.gif', '.webp'] const acceptableExtensions = ['.jpg', '.png', '.gif', '.webp']
@ -56,6 +58,22 @@ export default async function handler(
return 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 // download media
const mediaRes = await fetch(mediaUrl) const mediaRes = await fetch(mediaUrl)
@ -64,20 +82,11 @@ export default async function handler(
return return
} }
// get media type const mediaBuffer = Buffer.from(await mediaRes.arrayBuffer())
const mediaType = mediaRes.headers.get('content-type')
if (!mediaType) { // save in redis for 30 minutes
res.status(500) await redis.setex(cacheKey, 60 * 30, mediaBuffer)
res.send(null)
return
}
// set media type
res.setHeader('content-type', mediaType)
const mediaBuffer = await mediaRes.arrayBuffer()
// send media // send media
res.send(Buffer.from(mediaBuffer)) res.send(mediaBuffer)
} }

11
src/utils/redis.ts Normal file
View File

@ -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