diff options
| author | syuilo <Syuilotan@yahoo.co.jp> | 2021-11-12 02:02:25 +0900 |
|---|---|---|
| committer | syuilo <Syuilotan@yahoo.co.jp> | 2021-11-12 02:02:25 +0900 |
| commit | 0e4a111f81cceed275d9bec2695f6e401fb654d8 (patch) | |
| tree | 40874799472fa07416f17b50a398ac33b7771905 /packages/backend/src/server/proxy | |
| parent | update deps (diff) | |
| download | sharkey-0e4a111f81cceed275d9bec2695f6e401fb654d8.tar.gz sharkey-0e4a111f81cceed275d9bec2695f6e401fb654d8.tar.bz2 sharkey-0e4a111f81cceed275d9bec2695f6e401fb654d8.zip | |
refactoring
Resolve #7779
Diffstat (limited to 'packages/backend/src/server/proxy')
| -rw-r--r-- | packages/backend/src/server/proxy/index.ts | 26 | ||||
| -rw-r--r-- | packages/backend/src/server/proxy/proxy-media.ts | 51 |
2 files changed, 77 insertions, 0 deletions
diff --git a/packages/backend/src/server/proxy/index.ts b/packages/backend/src/server/proxy/index.ts new file mode 100644 index 0000000000..b8993f19f8 --- /dev/null +++ b/packages/backend/src/server/proxy/index.ts @@ -0,0 +1,26 @@ +/** + * Media Proxy + */ + +import * as Koa from 'koa'; +import * as cors from '@koa/cors'; +import * as Router from '@koa/router'; +import { proxyMedia } from './proxy-media'; + +// Init app +const app = new Koa(); +app.use(cors()); +app.use(async (ctx, next) => { + ctx.set('Content-Security-Policy', `default-src 'none'; style-src 'unsafe-inline'`); + await next(); +}); + +// Init router +const router = new Router(); + +router.get('/:url*', proxyMedia); + +// Register router +app.use(router.routes()); + +module.exports = app; diff --git a/packages/backend/src/server/proxy/proxy-media.ts b/packages/backend/src/server/proxy/proxy-media.ts new file mode 100644 index 0000000000..9e13c0877f --- /dev/null +++ b/packages/backend/src/server/proxy/proxy-media.ts @@ -0,0 +1,51 @@ +import * as fs from 'fs'; +import * as Koa from 'koa'; +import { serverLogger } from '../index'; +import { IImage, convertToPng, convertToJpeg } from '@/services/drive/image-processor'; +import { createTemp } from '@/misc/create-temp'; +import { downloadUrl } from '@/misc/download-url'; +import { detectType } from '@/misc/get-file-info'; +import { StatusError } from '@/misc/fetch'; + +export async function proxyMedia(ctx: Koa.Context) { + const url = 'url' in ctx.query ? ctx.query.url : 'https://' + ctx.params.url; + + // Create temp file + const [path, cleanup] = await createTemp(); + + try { + await downloadUrl(url, path); + + const { mime, ext } = await detectType(path); + + if (!mime.startsWith('image/')) throw 403; + + let image: IImage; + + if ('static' in ctx.query && ['image/png', 'image/gif', 'image/apng', 'image/vnd.mozilla.apng', 'image/webp'].includes(mime)) { + image = await convertToPng(path, 498, 280); + } else if ('preview' in ctx.query && ['image/jpeg', 'image/png', 'image/gif', 'image/apng', 'image/vnd.mozilla.apng'].includes(mime)) { + image = await convertToJpeg(path, 200, 200); + } else { + image = { + data: fs.readFileSync(path), + ext, + type: mime, + }; + } + + ctx.set('Content-Type', image.type); + ctx.set('Cache-Control', 'max-age=31536000, immutable'); + ctx.body = image.data; + } catch (e) { + serverLogger.error(`${e}`); + + if (e instanceof StatusError && e.isClientError) { + ctx.status = e.statusCode; + } else { + ctx.status = 500; + } + } finally { + cleanup(); + } +} |