fix(upload): Groessengrenzen realistisch setzen, PDFs eigener Wert
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
Der Upload lief gegen einen einzigen globalen Wert von 5 MB, der fuer alle
Dateitypen galt. Eine Getraenkekarte liegt aber schnell bei 15-20 MB, das
Hochladen scheiterte deshalb zuverlaessig.
- MAX_FILE_SIZE (Bilder) von 5 auf 20 MB. Bilder werden ohnehin auf 1600px
heruntergerechnet, die Grenze muss nur ein unbearbeitetes Handyfoto
durchlassen - 5 MB reichten dafuer schon nicht.
- MAX_PDF_SIZE neu, 40 MB. PDFs werden unveraendert abgelegt.
- Beides ueber Umgebungsvariablen uebersteuerbar.
Die Registrierung von multipart nimmt den groesseren der beiden Werte als
Obergrenze, die Routen setzen ihn per request.file({ limits }) auf ihren
eigenen herunter. Die Fehlermeldung im PDF-Zweig nannte bisher die
Bildgrenze.
Geprueft am laufenden Container, auch mit --memory=512m wie auf Fly: 18-MB-
PDF und 18-MB-Foto gehen durch, 45 MB bzw. 25 MB werden mit 413 und
passender Meldung abgelehnt, kein OOM.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
@@ -28,7 +28,12 @@ export const env = {
|
||||
FRONTEND_URL: process.env.FRONTEND_URL || 'http://localhost:5173',
|
||||
|
||||
// Upload
|
||||
MAX_FILE_SIZE: parseInt(process.env.MAX_FILE_SIZE || '5242880', 10),
|
||||
// Bilder werden ohnehin auf 1600px heruntergerechnet, die Grenze muss nur
|
||||
// gross genug fuer ein unbearbeitetes Handyfoto sein.
|
||||
MAX_FILE_SIZE: parseInt(process.env.MAX_FILE_SIZE || String(20 * 1024 * 1024), 10),
|
||||
// PDFs werden unveraendert abgelegt. Eine Getraenkekarte mit Bildern liegt
|
||||
// schnell bei 15-20 MB, deshalb ein eigener, groesserer Wert.
|
||||
MAX_PDF_SIZE: parseInt(process.env.MAX_PDF_SIZE || String(40 * 1024 * 1024), 10),
|
||||
};
|
||||
|
||||
// Validate required environment variables
|
||||
|
||||
@@ -73,9 +73,11 @@ fastify.register(jwt, {
|
||||
},
|
||||
});
|
||||
|
||||
// Der globale Wert ist die Obergrenze fuer alles. Die Routen setzen ihn per
|
||||
// request.file({ limits }) auf ihren eigenen, engeren Wert herunter.
|
||||
fastify.register(multipart, {
|
||||
limits: {
|
||||
fileSize: env.MAX_FILE_SIZE,
|
||||
fileSize: Math.max(env.MAX_FILE_SIZE, env.MAX_PDF_SIZE),
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import { contentSections } from '../db/schema.js';
|
||||
import { eq } from 'drizzle-orm';
|
||||
import { saveUploadedImage } from '../services/upload.service.js';
|
||||
import { dropImageIfUnused, extractImageUrls } from '../services/image-refs.service.js';
|
||||
import { env } from '../config/env.js';
|
||||
|
||||
// Fastify JSON schema for content section body
|
||||
const contentBodyJsonSchema = {
|
||||
@@ -106,7 +107,7 @@ const contentRoute: FastifyPluginAsync = async (fastify) => {
|
||||
preHandler: [fastify.authenticate],
|
||||
}, async (request, reply) => {
|
||||
try {
|
||||
const file = await (request as any).file();
|
||||
const file = await (request as any).file({ limits: { fileSize: env.MAX_FILE_SIZE } });
|
||||
if (!file) {
|
||||
return reply.code(400).send({ error: 'No file uploaded' });
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import { events } from '../db/schema.js';
|
||||
import { eq } from 'drizzle-orm';
|
||||
import { dropImageIfUnused } from '../services/image-refs.service.js';
|
||||
import { saveUploadedImage } from '../services/upload.service.js';
|
||||
import { env } from '../config/env.js';
|
||||
|
||||
/** Raeumt eine Bilddatei weg, ohne dass ein Fehler die Antwort kippt. */
|
||||
async function dropUnusedImage(fastify: any, url: string | null | undefined, reason: string) {
|
||||
@@ -102,7 +103,7 @@ const eventsRoute: FastifyPluginAsync = async (fastify) => {
|
||||
}, async (request, reply) => {
|
||||
try {
|
||||
// Expect a single file field named "file"
|
||||
const file = await (request as any).file();
|
||||
const file = await (request as any).file({ limits: { fileSize: env.MAX_FILE_SIZE } });
|
||||
if (!file) {
|
||||
return reply.code(400).send({ error: 'No file uploaded' });
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import { galleryImages } from '../db/schema.js';
|
||||
import { eq } from 'drizzle-orm';
|
||||
import { dropImageIfUnused } from '../services/image-refs.service.js';
|
||||
import { saveUploadedImage } from '../services/upload.service.js';
|
||||
import { env } from '../config/env.js';
|
||||
|
||||
/** Raeumt eine Bilddatei weg, ohne dass ein Fehler die Antwort kippt. */
|
||||
async function dropUnusedImage(fastify: any, url: string | null | undefined, reason: string) {
|
||||
@@ -81,7 +82,7 @@ const galleryRoute: FastifyPluginAsync = async (fastify) => {
|
||||
}, async (request, reply) => {
|
||||
try {
|
||||
// Expect a single file field named "file"
|
||||
const file = await (request as any).file();
|
||||
const file = await (request as any).file({ limits: { fileSize: env.MAX_FILE_SIZE } });
|
||||
if (!file) {
|
||||
return reply.code(400).send({ error: 'No file uploaded' });
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ const pdfRoute: FastifyPluginAsync = async (fastify) => {
|
||||
}
|
||||
|
||||
try {
|
||||
const file = await (request as any).file();
|
||||
const file = await (request as any).file({ limits: { fileSize: env.MAX_PDF_SIZE } });
|
||||
if (!file) {
|
||||
return reply.code(400).send({ error: 'No file uploaded' });
|
||||
}
|
||||
@@ -63,7 +63,7 @@ const pdfRoute: FastifyPluginAsync = async (fastify) => {
|
||||
const buffer = Buffer.concat(chunks);
|
||||
|
||||
if ((file.file as any)?.truncated) {
|
||||
const limit = Math.round(env.MAX_FILE_SIZE / 1024 / 1024);
|
||||
const limit = Math.round(env.MAX_PDF_SIZE / 1024 / 1024);
|
||||
return reply.code(413).send({ error: `PDF too large. Maximum is ${limit} MB` });
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@ const pdfRoute: FastifyPluginAsync = async (fastify) => {
|
||||
|
||||
} catch (err: any) {
|
||||
if (err?.code === 'FST_REQ_FILE_TOO_LARGE') {
|
||||
const limit = Math.round(env.MAX_FILE_SIZE / 1024 / 1024);
|
||||
const limit = Math.round(env.MAX_PDF_SIZE / 1024 / 1024);
|
||||
return reply.code(413).send({ error: `PDF too large. Maximum is ${limit} MB` });
|
||||
}
|
||||
fastify.log.error({ err }, 'PDF upload failed');
|
||||
|
||||
Reference in New Issue
Block a user