summaryrefslogtreecommitdiff
path: root/src/server/file
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/file')
-rw-r--r--src/server/file/send-drive-file.ts67
1 files changed, 64 insertions, 3 deletions
diff --git a/src/server/file/send-drive-file.ts b/src/server/file/send-drive-file.ts
index a05477488b..e0aea5b42f 100644
--- a/src/server/file/send-drive-file.ts
+++ b/src/server/file/send-drive-file.ts
@@ -1,10 +1,16 @@
import * as Koa from 'koa';
import * as send from 'koa-send';
import * as rename from 'rename';
+import * as tmp from 'tmp';
+import * as fs from 'fs';
import { serverLogger } from '..';
import { contentDisposition } from '../../misc/content-disposition';
import { DriveFiles } from '../../models';
import { InternalStorage } from '../../services/drive/internal-storage';
+import { downloadUrl } from '../../misc/donwload-url';
+import { detectMine } from '../../misc/detect-mine';
+import { convertToJpeg, convertToPng, convertToGif, convertToApng } from '../../services/drive/image-processor';
+import { GenerateVideoThumbnail } from '../../services/drive/generate-video-thumbnail';
const assets = `${__dirname}/../../server/file/assets/`;
@@ -31,15 +37,70 @@ export default async function(ctx: Koa.Context) {
return;
}
+ const isThumbnail = file.thumbnailAccessKey === key;
+ const isWebpublic = file.webpublicAccessKey === key;
+
if (!file.storedInternal) {
+ if (file.isLink && file.uri) { // 期限切れリモートファイル
+ const [path, cleanup] = await new Promise<[string, any]>((res, rej) => {
+ tmp.file((e, path, fd, cleanup) => {
+ if (e) return rej(e);
+ res([path, cleanup]);
+ });
+ });
+
+ try {
+ await downloadUrl(file.uri, path);
+
+ const [type, ext] = await detectMine(path);
+
+ const convertFile = async () => {
+ if (isThumbnail) {
+ if (['image/jpeg', 'image/webp'].includes(type)) {
+ return await convertToJpeg(path, 498, 280);
+ } else if (['image/png'].includes(type)) {
+ return await convertToPng(path, 498, 280);
+ } else if (['image/gif'].includes(type)) {
+ return await convertToGif(path);
+ } else if (['image/apng', 'image/vnd.mozilla.apng'].includes(type)) {
+ return await convertToApng(path);
+ } else if (type.startsWith('video/')) {
+ return await GenerateVideoThumbnail(path);
+ }
+ }
+
+ return {
+ data: fs.readFileSync(path),
+ ext,
+ type,
+ };
+ };
+
+ const image = await convertFile();
+ ctx.body = image.data;
+ ctx.set('Content-Type', file.type);
+ ctx.set('Cache-Control', 'max-age=31536000, immutable');
+ } catch (e) {
+ serverLogger.error(e);
+
+ if (typeof e == 'number' && e >= 400 && e < 500) {
+ ctx.status = e;
+ ctx.set('Cache-Control', 'max-age=86400');
+ } else {
+ ctx.status = 500;
+ ctx.set('Cache-Control', 'max-age=300');
+ }
+ } finally {
+ cleanup();
+ }
+ return;
+ }
+
ctx.status = 204;
ctx.set('Cache-Control', 'max-age=86400');
return;
}
- const isThumbnail = file.thumbnailAccessKey === key;
- const isWebpublic = file.webpublicAccessKey === key;
-
if (isThumbnail) {
ctx.body = InternalStorage.read(key);
ctx.set('Content-Type', 'image/jpeg');