From 1983f6b1fb0380642c6488a0347a7073eea20338 Mon Sep 17 00:00:00 2001 From: httpjamesm Date: Mon, 31 Oct 2022 17:45:14 -0400 Subject: [PATCH] feat: proxy videos and add more descriptive error messages --- src/components/title/Media.tsx | 2 +- src/pages/api/media_proxy.ts | 40 ++++++++++++++++++++++++++-------- 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/src/components/title/Media.tsx b/src/components/title/Media.tsx index 5ef8ade..117ed39 100644 --- a/src/components/title/Media.tsx +++ b/src/components/title/Media.tsx @@ -37,7 +37,7 @@ const Media = ({ className, media, router }: Props) => { ))} diff --git a/src/pages/api/media_proxy.ts b/src/pages/api/media_proxy.ts index 1ec226f..6e2cb2b 100644 --- a/src/pages/api/media_proxy.ts +++ b/src/pages/api/media_proxy.ts @@ -3,7 +3,7 @@ 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', '.mp4'] export default async function handler( req: NextApiRequest, @@ -14,7 +14,10 @@ export default async function handler( if (!mediaUrl) { res.status(400) - res.end() + res.json({ + success: false, + message: 'Missing query', + }) return } @@ -24,22 +27,34 @@ export default async function handler( mediaUrlParsed = new URL(mediaUrl) } catch { res.status(400) - res.end() + res.json({ + success: false, + message: 'Invalid URL', + }) return } // get media domain const mediaDomain = mediaUrlParsed.hostname - if (!mediaDomain.endsWith('media-amazon.com')) { + if ( + !mediaDomain.endsWith('media-amazon.com') && + mediaDomain !== 'imdb-video.media-imdb.com' + ) { res.status(400) - res.end() + res.json({ + success: false, + message: 'Unauthorized domain', + }) return } if (mediaUrlParsed.protocol !== 'https:') { res.status(400) - res.end() + res.json({ + success: false, + message: 'Unauthorized protocol', + }) return } @@ -54,12 +69,15 @@ export default async function handler( if (!validExtension) { res.status(400) - res.end() + res.json({ + success: false, + message: 'Unauthorized extension', + }) return } // hash mediaUrl with blake3 - const mediaUrlHash = await crypto + const mediaUrlHash = crypto .createHash('sha256') .update(mediaUrl) .digest('base64') @@ -70,6 +88,7 @@ export default async function handler( const cachedMedia = await redis.get(cacheKey) if (cachedMedia) { + res.status(302) res.send(cachedMedia) return } @@ -79,7 +98,10 @@ export default async function handler( if (!mediaRes.ok) { res.status(mediaRes.status) - res.end() + res.json({ + success: false, + message: 'Error from Amazon', + }) return }