This commit is contained in:
tamaina 2023-02-28 16:06:23 +00:00
parent 30c8088b8e
commit d5f5f4023c
4 changed files with 14 additions and 10 deletions

View File

@ -26,7 +26,7 @@ Acceptヘッダーは無視される。
Cache-Controlは、正常なレスポンスの場合`max-age=31536000, immutable`、エラーレスポンスの場合`max-age=300`である。 Cache-Controlは、正常なレスポンスの場合`max-age=31536000, immutable`、エラーレスポンスの場合`max-age=300`である。
Content-Typeは、ファイルの内容について適切なものが挿入される。 Content-Typeは、ファイルの内容について適切なものが挿入される。
Content-Security-Policyは、`default-src 'none'; img-src 'self'; media-src 'self'; style-src 'unsafe-inline'`となっている。 Content-Security-Policyは、`default-src 'none'; img-src 'self'; media-src 'self'; style-src 'unsafe-inline'`となっている。
Content-Dispositionは、filenameは元画像のContent-Disposition.filenameもしくはファイル名に基づいて挿入される。inlineが指定される。 Content-Dispositionは、filenameは元画像のContent-Disposition.filenameもしくはファイル名に基づいて挿入される。拡張子は適宜変更され、octet-streamの場合は拡張子として.unknownが付加される。inlineが指定される。
### クエリの一覧 ### クエリの一覧
#### url (必須) #### url (必須)
@ -52,6 +52,9 @@ https://www.google.com/images/errors/robot.png をプロキシする場合:
変換形式が指定されていなかった場合は、画像ファイルもしくは許可されたファイルFILE_TYPE_BROWSERSAFEである場合のみプロキシファイルの再配信が行われる。 変換形式が指定されていなかった場合は、画像ファイルもしくは許可されたファイルFILE_TYPE_BROWSERSAFEである場合のみプロキシファイルの再配信が行われる。
ただし、svgは、webpに変換される最大サイズ2048x2048 ただし、svgは、webpに変換される最大サイズ2048x2048
#### 変換クエリ付加時の挙動
一方、以下の変換クエリが指定されているが、元ファイルがsharp.jsで変換できない形式の場合、404が返される。
#### emoji #### emoji
存在すると、高さ128px以下のwebpが応答される。 存在すると、高さ128px以下のwebpが応答される。
ただし、sharp.jsの都合により、元画像がapngの場合は無変換で応答される。 ただし、sharp.jsの都合により、元画像がapngの場合は無変換で応答される。

View File

@ -183,7 +183,7 @@ async function proxyHandler(request, reply) {
} }
reply.header('Content-Type', image.type); reply.header('Content-Type', image.type);
reply.header('Cache-Control', 'max-age=31536000, immutable'); reply.header('Cache-Control', 'max-age=31536000, immutable');
reply.header('Content-Disposition', contentDisposition('inline', file.filename)); reply.header('Content-Disposition', contentDisposition('inline', correctFilename(file.filename, image.ext)));
return reply.send(image.data); return reply.send(image.data);
} }
catch (e) { catch (e) {
@ -210,9 +210,7 @@ async function downloadAndDetectTypeFromUrl(url) {
} }
} }
function correctFilename(filename, ext) { function correctFilename(filename, ext) {
if (!ext) const dotExt = ext ? `.${ext}` : '.unknown';
return filename;
const dotExt = `.${ext}`;
if (filename.endsWith(dotExt)) { if (filename.endsWith(dotExt)) {
return filename; return filename;
} }

View File

@ -1,6 +1,6 @@
{ {
"name": "misskey-media-proxy", "name": "misskey-media-proxy",
"version": "0.0.14", "version": "0.0.15",
"description": "The Media Proxy for Misskey", "description": "The Media Proxy for Misskey",
"main": "built/index.js", "main": "built/index.js",
"packageManager": "pnpm@7.26.0", "packageManager": "pnpm@7.26.0",

View File

@ -231,7 +231,12 @@ async function proxyHandler(request: FastifyRequest<{ Params: { url: string; };
reply.header('Content-Type', image.type); reply.header('Content-Type', image.type);
reply.header('Cache-Control', 'max-age=31536000, immutable'); reply.header('Cache-Control', 'max-age=31536000, immutable');
reply.header('Content-Disposition', contentDisposition('inline', file.filename)); reply.header('Content-Disposition',
contentDisposition(
'inline',
correctFilename(file.filename, image.ext)
)
);
return reply.send(image.data); return reply.send(image.data);
} catch (e) { } catch (e) {
if ('cleanup' in file) file.cleanup(); if ('cleanup' in file) file.cleanup();
@ -261,9 +266,7 @@ async function downloadAndDetectTypeFromUrl(url: string): Promise<
} }
function correctFilename(filename: string, ext: string | null) { function correctFilename(filename: string, ext: string | null) {
if (!ext) return filename; const dotExt = ext ? `.${ext}` : '.unknown';
const dotExt = `.${ext}`;
if (filename.endsWith(dotExt)) { if (filename.endsWith(dotExt)) {
return filename; return filename;
} }