Fastify (#9106)
* wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * fix * Update SignupApiService.ts * wip * wip * Update ClientServerService.ts * wip * wip * wip * Update WellKnownServerService.ts * wip * wip * update des * wip * Update ApiServerService.ts * wip * update deps * Update WellKnownServerService.ts * wip * update deps * Update ApiCallService.ts * Update ApiCallService.ts * Update ApiServerService.ts
This commit is contained in:
parent
2db9f6efe7
commit
3a7182bfb5
40 changed files with 1651 additions and 1977 deletions
|
@ -2,10 +2,8 @@ import * as fs from 'node:fs';
|
|||
import { fileURLToPath } from 'node:url';
|
||||
import { dirname } from 'node:path';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import Koa from 'koa';
|
||||
import cors from '@koa/cors';
|
||||
import Router from '@koa/router';
|
||||
import send from 'koa-send';
|
||||
import { FastifyInstance, FastifyRequest, FastifyReply, FastifyPluginOptions } from 'fastify';
|
||||
import fastifyStatic from '@fastify/static';
|
||||
import rename from 'rename';
|
||||
import type { Config } from '@/config.js';
|
||||
import type { DriveFilesRepository } from '@/models/index.js';
|
||||
|
@ -46,45 +44,44 @@ export class FileServerService {
|
|||
private loggerService: LoggerService,
|
||||
) {
|
||||
this.logger = this.loggerService.getLogger('server', 'gray', false);
|
||||
|
||||
this.createServer = this.createServer.bind(this);
|
||||
}
|
||||
|
||||
public commonReadableHandlerGenerator(ctx: Koa.Context) {
|
||||
return (e: Error): void => {
|
||||
this.logger.error(e);
|
||||
ctx.status = 500;
|
||||
ctx.set('Cache-Control', 'max-age=300');
|
||||
public commonReadableHandlerGenerator(reply: FastifyReply) {
|
||||
return (err: Error): void => {
|
||||
this.logger.error(err);
|
||||
reply.code(500);
|
||||
reply.header('Cache-Control', 'max-age=300');
|
||||
};
|
||||
}
|
||||
|
||||
public createServer() {
|
||||
const app = new Koa();
|
||||
app.use(cors());
|
||||
app.use(async (ctx, next) => {
|
||||
ctx.set('Content-Security-Policy', 'default-src \'none\'; img-src \'self\'; media-src \'self\'; style-src \'unsafe-inline\'');
|
||||
await next();
|
||||
public createServer(fastify: FastifyInstance, options: FastifyPluginOptions, done: (err?: Error) => void) {
|
||||
fastify.addHook('onRequest', (request, reply, done) => {
|
||||
reply.header('Content-Security-Policy', 'default-src \'none\'; img-src \'self\'; media-src \'self\'; style-src \'unsafe-inline\'');
|
||||
done();
|
||||
});
|
||||
|
||||
// Init router
|
||||
const router = new Router();
|
||||
fastify.register(fastifyStatic, {
|
||||
root: _dirname,
|
||||
serve: false,
|
||||
});
|
||||
|
||||
router.get('/app-default.jpg', ctx => {
|
||||
fastify.get('/app-default.jpg', (request, reply) => {
|
||||
const file = fs.createReadStream(`${_dirname}/assets/dummy.png`);
|
||||
ctx.body = file;
|
||||
ctx.set('Content-Type', 'image/jpeg');
|
||||
ctx.set('Cache-Control', 'max-age=31536000, immutable');
|
||||
reply.header('Content-Type', 'image/jpeg');
|
||||
reply.header('Cache-Control', 'max-age=31536000, immutable');
|
||||
return reply.send(file);
|
||||
});
|
||||
|
||||
router.get('/:key', ctx => this.sendDriveFile(ctx));
|
||||
router.get('/:key/(.*)', ctx => this.sendDriveFile(ctx));
|
||||
fastify.get<{ Params: { key: string; } }>('/:key', async (request, reply) => await this.sendDriveFile(request, reply));
|
||||
fastify.get<{ Params: { key: string; } }>('/:key/*', async (request, reply) => await this.sendDriveFile(request, reply));
|
||||
|
||||
// Register router
|
||||
app.use(router.routes());
|
||||
|
||||
return app;
|
||||
done();
|
||||
}
|
||||
|
||||
private async sendDriveFile(ctx: Koa.Context) {
|
||||
const key = ctx.params.key;
|
||||
private async sendDriveFile(request: FastifyRequest<{ Params: { key: string; } }>, reply: FastifyReply) {
|
||||
const key = request.params.key;
|
||||
|
||||
// Fetch drive file
|
||||
const file = await this.driveFilesRepository.createQueryBuilder('file')
|
||||
|
@ -94,10 +91,9 @@ export class FileServerService {
|
|||
.getOne();
|
||||
|
||||
if (file == null) {
|
||||
ctx.status = 404;
|
||||
ctx.set('Cache-Control', 'max-age=86400');
|
||||
await send(ctx as any, '/dummy.png', { root: assets });
|
||||
return;
|
||||
reply.code(404);
|
||||
reply.header('Cache-Control', 'max-age=86400');
|
||||
return reply.sendFile('/dummy.png', assets);
|
||||
}
|
||||
|
||||
const isThumbnail = file.thumbnailAccessKey === key;
|
||||
|
@ -135,18 +131,18 @@ export class FileServerService {
|
|||
};
|
||||
|
||||
const image = await convertFile();
|
||||
ctx.body = image.data;
|
||||
ctx.set('Content-Type', FILE_TYPE_BROWSERSAFE.includes(image.type) ? image.type : 'application/octet-stream');
|
||||
ctx.set('Cache-Control', 'max-age=31536000, immutable');
|
||||
reply.header('Content-Type', FILE_TYPE_BROWSERSAFE.includes(image.type) ? image.type : 'application/octet-stream');
|
||||
reply.header('Cache-Control', 'max-age=31536000, immutable');
|
||||
return image.data;
|
||||
} catch (err) {
|
||||
this.logger.error(`${err}`);
|
||||
|
||||
if (err instanceof StatusError && err.isClientError) {
|
||||
ctx.status = err.statusCode;
|
||||
ctx.set('Cache-Control', 'max-age=86400');
|
||||
reply.code(err.statusCode);
|
||||
reply.header('Cache-Control', 'max-age=86400');
|
||||
} else {
|
||||
ctx.status = 500;
|
||||
ctx.set('Cache-Control', 'max-age=300');
|
||||
reply.code(500);
|
||||
reply.header('Cache-Control', 'max-age=300');
|
||||
}
|
||||
} finally {
|
||||
cleanup();
|
||||
|
@ -154,8 +150,8 @@ export class FileServerService {
|
|||
return;
|
||||
}
|
||||
|
||||
ctx.status = 204;
|
||||
ctx.set('Cache-Control', 'max-age=86400');
|
||||
reply.code(204);
|
||||
reply.header('Cache-Control', 'max-age=86400');
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -166,18 +162,17 @@ export class FileServerService {
|
|||
extname: ext ? `.${ext}` : undefined,
|
||||
}).toString();
|
||||
|
||||
ctx.body = this.internalStorageService.read(key);
|
||||
ctx.set('Content-Type', FILE_TYPE_BROWSERSAFE.includes(mime) ? mime : 'application/octet-stream');
|
||||
ctx.set('Cache-Control', 'max-age=31536000, immutable');
|
||||
ctx.set('Content-Disposition', contentDisposition('inline', filename));
|
||||
reply.header('Content-Type', FILE_TYPE_BROWSERSAFE.includes(mime) ? mime : 'application/octet-stream');
|
||||
reply.header('Cache-Control', 'max-age=31536000, immutable');
|
||||
reply.header('Content-Disposition', contentDisposition('inline', filename));
|
||||
return this.internalStorageService.read(key);
|
||||
} else {
|
||||
const readable = this.internalStorageService.read(file.accessKey!);
|
||||
readable.on('error', this.commonReadableHandlerGenerator(ctx));
|
||||
ctx.body = readable;
|
||||
ctx.set('Content-Type', FILE_TYPE_BROWSERSAFE.includes(file.type) ? file.type : 'application/octet-stream');
|
||||
ctx.set('Cache-Control', 'max-age=31536000, immutable');
|
||||
ctx.set('Content-Disposition', contentDisposition('inline', file.name));
|
||||
readable.on('error', this.commonReadableHandlerGenerator(reply));
|
||||
reply.header('Content-Type', FILE_TYPE_BROWSERSAFE.includes(file.type) ? file.type : 'application/octet-stream');
|
||||
reply.header('Cache-Control', 'max-age=31536000, immutable');
|
||||
reply.header('Content-Disposition', contentDisposition('inline', file.name));
|
||||
return readable;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue