feat: media proxy for anonymous loads

This commit is contained in:
httpjamesm 2022-10-31 17:04:26 -04:00
parent 261a37576b
commit 59a314b2bd
2 changed files with 85 additions and 1 deletions

View File

@ -16,6 +16,7 @@
"axios": "^0.27.2",
"cheerio": "1.0.0-rc.12",
"next": "12.2.5",
"node-fetch": "^3.2.10",
"react": "18.2.0",
"react-dom": "18.2.0",
"sharp": "^0.31.0"
@ -33,4 +34,4 @@
"node": ">=16.5.0",
"pnpm": ">=7.0.0"
}
}
}

View File

@ -0,0 +1,83 @@
import { NextApiRequest, NextApiResponse } from 'next'
import fetch from 'node-fetch'
const acceptableExtensions = ['.jpg', '.png', '.gif', '.webp']
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
// get query param
const mediaUrl = (req.query as { url: string }).url
if (!mediaUrl) {
res.status(400)
res.send(null)
return
}
let mediaUrlParsed: URL
try {
mediaUrlParsed = new URL(mediaUrl)
} catch {
res.status(400)
res.send(null)
return
}
// get media domain
const mediaDomain = mediaUrlParsed.hostname
if (!mediaDomain.endsWith('media-amazon.com')) {
res.status(400)
res.send(null)
return
}
if (mediaUrlParsed.protocol !== 'https:') {
res.status(400)
res.send(null)
return
}
let validExtension = false
for (const acceptableExtension of acceptableExtensions) {
if (mediaUrlParsed.pathname.endsWith(acceptableExtension)) {
validExtension = true
break
}
}
if (!validExtension) {
res.status(400)
res.send(null)
return
}
// download media
const mediaRes = await fetch(mediaUrl)
if (!mediaRes.ok) {
res.status(mediaRes.status)
return
}
// get media type
const mediaType = mediaRes.headers.get('content-type')
if (!mediaType) {
res.status(500)
res.send(null)
return
}
// set media type
res.setHeader('content-type', mediaType)
const mediaBuffer = await mediaRes.arrayBuffer()
// send media
res.send(Buffer.from(mediaBuffer))
}