feat: media proxy for anonymous loads
This commit is contained in:
parent
261a37576b
commit
59a314b2bd
@ -16,6 +16,7 @@
|
|||||||
"axios": "^0.27.2",
|
"axios": "^0.27.2",
|
||||||
"cheerio": "1.0.0-rc.12",
|
"cheerio": "1.0.0-rc.12",
|
||||||
"next": "12.2.5",
|
"next": "12.2.5",
|
||||||
|
"node-fetch": "^3.2.10",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "18.2.0",
|
||||||
"sharp": "^0.31.0"
|
"sharp": "^0.31.0"
|
||||||
|
83
src/pages/api/media_proxy.ts
Normal file
83
src/pages/api/media_proxy.ts
Normal 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))
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user