feat: cache media proxy data in redis for 30 mins
This commit is contained in:
parent
59a314b2bd
commit
2c8d138cbd
@ -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",
|
||||||
|
@ -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
11
src/utils/redis.ts
Normal 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
|
Loading…
x
Reference in New Issue
Block a user