From d37f485e3010f8571c0b3a464950c9bc3fd495cb Mon Sep 17 00:00:00 2001 From: undefined Date: Wed, 18 Aug 2021 23:20:40 +0800 Subject: [PATCH] core: add file fallback --- packages/hydrooj/package.json | 2 +- packages/hydrooj/src/handler/contest.ts | 7 ++++++- packages/hydrooj/src/handler/homework.ts | 7 ++++++- packages/hydrooj/src/handler/misc.ts | 7 ++++++- packages/hydrooj/src/handler/problem.ts | 7 ++++++- packages/hydrooj/src/model/storage.ts | 4 ++-- 6 files changed, 27 insertions(+), 7 deletions(-) diff --git a/packages/hydrooj/package.json b/packages/hydrooj/package.json index 303477a39..6916e7da5 100644 --- a/packages/hydrooj/package.json +++ b/packages/hydrooj/package.json @@ -1,6 +1,6 @@ { "name": "hydrooj", - "version": "2.32.27", + "version": "2.32.28", "bin": "bin/hydrooj.js", "main": "src/loader", "module": "src/loader", diff --git a/packages/hydrooj/src/handler/contest.ts b/packages/hydrooj/src/handler/contest.ts index 1193d4e90..6988d2ebd 100644 --- a/packages/hydrooj/src/handler/contest.ts +++ b/packages/hydrooj/src/handler/contest.ts @@ -320,7 +320,12 @@ export class ContestProblemFileDownloadHandler extends ContestProblemHandler { if (typeof this.pdoc.docId === 'string') this.pdoc.docId = this.pdoc.docId.split(':')[1]; const target = `problem/${this.pdoc.domainId}/${this.pdoc.docId}/additional_file/${filename}`; const file = await storage.getMeta(target); - if (!file) throw new NotFoundError(filename); + if (!file) { + this.response.redirect = await storage.signDownloadLink( + target, noDisposition ? undefined : filename, false, 'user', + ); + return; + } this.response.etag = file.etag; const type = lookup(filename).toString(); const shouldProxy = ['image', 'video', 'audio', 'pdf', 'vnd'].filter((i) => type.includes(i)).length; diff --git a/packages/hydrooj/src/handler/homework.ts b/packages/hydrooj/src/handler/homework.ts index ce43a4337..3a8819f42 100644 --- a/packages/hydrooj/src/handler/homework.ts +++ b/packages/hydrooj/src/handler/homework.ts @@ -184,7 +184,12 @@ export class HomeworkProblemFileDownloadHandler extends HomeworkDetailProblemHan if (typeof this.pdoc.docId === 'string') this.pdoc.docId = this.pdoc.docId.split(':')[1]; const target = `problem/${this.pdoc.domainId}/${this.pdoc.docId}/additional_file/${filename}`; const file = await storage.getMeta(target); - if (!file) throw new NotFoundError(filename); + if (!file) { + this.response.redirect = await storage.signDownloadLink( + target, noDisposition ? undefined : filename, false, 'user', + ); + return; + } this.response.etag = file.etag; const type = lookup(filename).toString(); const shouldProxy = ['image', 'video', 'audio', 'pdf', 'vnd'].filter((i) => type.includes(i)).length; diff --git a/packages/hydrooj/src/handler/misc.ts b/packages/hydrooj/src/handler/misc.ts index 128804536..45343fea4 100644 --- a/packages/hydrooj/src/handler/misc.ts +++ b/packages/hydrooj/src/handler/misc.ts @@ -111,7 +111,12 @@ export class FSDownloadHandler extends Handler { this.response.addHeader('Cache-Control', 'public'); const target = `user/${uid}/${filename}`; const file = await storage.getMeta(target); - if (!file) throw new NotFoundError(filename); + if (!file) { + this.response.redirect = await storage.signDownloadLink( + target, noDisposition ? undefined : filename, false, 'user', + ); + return; + } this.response.etag = file.etag; const type = lookup(filename).toString(); const shouldProxy = ['image', 'video', 'audio', 'pdf', 'vnd'].filter((i) => type.includes(i)).length; diff --git a/packages/hydrooj/src/handler/problem.ts b/packages/hydrooj/src/handler/problem.ts index eea0d7b3e..bfead48bc 100644 --- a/packages/hydrooj/src/handler/problem.ts +++ b/packages/hydrooj/src/handler/problem.ts @@ -417,7 +417,12 @@ export class ProblemFileDownloadHandler extends ProblemDetailHandler { } const target = `problem/${domainId}/${this.pdoc.docId}/${type}/${filename}`; const file = await storage.getMeta(target); - if (!file) throw new NotFoundError(filename); + if (!file) { + this.response.redirect = await storage.signDownloadLink( + target, noDisposition ? undefined : filename, false, 'user', + ); + return; + } this.response.etag = file.etag; const fileType = lookup(filename).toString(); const shouldProxy = ['image', 'video', 'audio', 'pdf', 'vnd'].filter((i) => fileType.includes(i)).length; diff --git a/packages/hydrooj/src/model/storage.ts b/packages/hydrooj/src/model/storage.ts index dee740540..18610e973 100644 --- a/packages/hydrooj/src/model/storage.ts +++ b/packages/hydrooj/src/model/storage.ts @@ -18,7 +18,7 @@ export class StorageModel { meta['Content-Type'] = (path.endsWith('.ans') || path.endsWith('.out')) ? 'text/plain' : lookup(path) || 'application/octet-stream'; - const _id = nanoid() + extname(path); + const _id = `${nanoid(3)}/${nanoid()}${extname(path)}`; await storage.put(_id, file, meta); const { metaData, size, etag } = await storage.getMeta(_id); await StorageModel.coll.insertOne({ @@ -88,7 +88,7 @@ export class StorageModel { { path: target, autoDelete: { $exists: false } }, { $set: { lastUsage: new Date() } }, ); - if (!res.value) return ''; + if (!res.value) return await storage.signDownloadLink(target, filename, noExpire, useAlternativeEndpointFor); return await storage.signDownloadLink(res.value._id, filename, noExpire, useAlternativeEndpointFor); } }