add configurable limits to the buffer sizes

This commit is contained in:
daniel31x13 2024-06-28 12:12:16 -04:00
parent 06234e42df
commit 576d50f467
7 changed files with 100 additions and 42 deletions

View File

@ -24,10 +24,11 @@ IGNORE_URL_SIZE_LIMIT=
ADMINISTRATOR= ADMINISTRATOR=
NEXT_PUBLIC_MAX_FILE_BUFFER= NEXT_PUBLIC_MAX_FILE_BUFFER=
MONOLITH_MAX_BUFFER= MONOLITH_MAX_BUFFER=
MONOLITH_OPTIONS= MONOLITH_CUSTOM_OPTIONS=
PDF_MAX_BUFFER= PDF_MAX_BUFFER=
SCREENSHOT_MAX_BUFFER= SCREENSHOT_MAX_BUFFER=
READABILITY_MAX_BUFFER= READABILITY_MAX_BUFFER=
PREVIEW_MAX_BUFFER=
# AWS S3 Settings # AWS S3 Settings
SPACES_KEY= SPACES_KEY=

View File

@ -14,17 +14,23 @@ const generatePreview = async (
image?.resize(1280, Jimp.AUTO).quality(20); image?.resize(1280, Jimp.AUTO).quality(20);
const processedBuffer = await image?.getBufferAsync(Jimp.MIME_JPEG); const processedBuffer = await image?.getBufferAsync(Jimp.MIME_JPEG);
createFile({ if (
Buffer.byteLength(processedBuffer) >
1024 * 1024 * Number(process.env.PREVIEW_MAX_BUFFER || 0.1)
)
return console.log("Error generating preview: Buffer size exceeded");
await createFile({
data: processedBuffer, data: processedBuffer,
filePath: `archives/preview/${collectionId}/${linkId}.jpeg`, filePath: `archives/preview/${collectionId}/${linkId}.jpeg`,
}).then(() => { });
return prisma.link.update({
await prisma.link.update({
where: { id: linkId }, where: { id: linkId },
data: { data: {
preview: `archives/preview/${collectionId}/${linkId}.jpeg`, preview: `archives/preview/${collectionId}/${linkId}.jpeg`,
}, },
}); });
});
} }
}).catch((err) => { }).catch((err) => {
console.error("Error processing the image:", err); console.error("Error processing the image:", err);

View File

@ -36,14 +36,19 @@ const handleArchivePreview = async (
console.log("No og:image found"); console.log("No og:image found");
await page await page
.screenshot({ type: "jpeg", quality: 20 }) .screenshot({ type: "jpeg", quality: 20 })
.then((screenshot) => { .then(async (screenshot) => {
return createFile({ if (
Buffer.byteLength(screenshot) >
1024 * 1024 * Number(process.env.PREVIEW_MAX_BUFFER || 0.1)
)
return console.log("Error generating preview: Buffer size exceeded");
await createFile({
data: screenshot, data: screenshot,
filePath: `archives/preview/${link.collectionId}/${link.id}.jpeg`, filePath: `archives/preview/${link.collectionId}/${link.id}.jpeg`,
}); });
})
.then(() => { await prisma.link.update({
return prisma.link.update({
where: { id: link.id }, where: { id: link.id },
data: { data: {
preview: `archives/preview/${link.collectionId}/${link.id}.jpeg`, preview: `archives/preview/${link.collectionId}/${link.id}.jpeg`,

View File

@ -9,7 +9,7 @@ const handleMonolith = async (link: Link, content: string) => {
try { try {
let html = execSync( let html = execSync(
`monolith - -I -b ${link.url} ${ `monolith - -I -b ${link.url} ${
process.env.MONOLITH_OPTIONS || "-j -F -s" process.env.MONOLITH_CUSTOM_OPTIONS || "-j -F -s"
} -o -`, } -o -`,
{ {
timeout: 120000, timeout: 120000,
@ -18,10 +18,14 @@ const handleMonolith = async (link: Link, content: string) => {
} }
); );
if (!html?.length) { if (!html?.length)
console.error("Error running MONOLITH: Empty buffer"); return console.error("Error archiving as Monolith: Empty buffer");
return;
} if (
Buffer.byteLength(html) >
1024 * 1024 * Number(process.env.MONOLITH_MAX_BUFFER || 6)
)
return console.error("Error archiving as Monolith: Buffer size exceeded");
await createFile({ await createFile({
data: html, data: html,
@ -35,7 +39,7 @@ const handleMonolith = async (link: Link, content: string) => {
}); });
}); });
} catch (err) { } catch (err) {
console.error("Error running MONOLITH:", err); console.log("Error running MONOLITH:", err);
} }
}; };

View File

@ -23,8 +23,18 @@ const handleReadablility = async (content: string, link: Link) => {
}) })
)?.collectionId; )?.collectionId;
const data = JSON.stringify(article);
if (
Buffer.byteLength(data, "utf8") >
1024 * 1024 * Number(process.env.READABILITY_MAX_BUFFER || 1)
)
return console.error(
"Error archiving as Readability: Buffer size exceeded"
);
await createFile({ await createFile({
data: JSON.stringify(article), data,
filePath: `archives/${collectionId}/${link.id}_readability.json`, filePath: `archives/${collectionId}/${link.id}_readability.json`,
}); });

View File

@ -24,11 +24,29 @@ const handleScreenshotAndPdf = async (
if (user.archiveAsScreenshot && !link.image?.startsWith("archive")) { if (user.archiveAsScreenshot && !link.image?.startsWith("archive")) {
processingPromises.push( processingPromises.push(
page.screenshot({ fullPage: true, type: "jpeg" }).then((screenshot) => { page
return createFile({ .screenshot({ fullPage: true, type: "jpeg" })
.then(async (screenshot) => {
if (
Buffer.byteLength(screenshot) >
1024 * 1024 * Number(process.env.SCREENSHOT_MAX_BUFFER || 2)
)
return console.log(
"Error archiving as Screenshot: Buffer size exceeded"
);
await createFile({
data: screenshot, data: screenshot,
filePath: `archives/${linkExists.collectionId}/${link.id}.jpeg`, filePath: `archives/${linkExists.collectionId}/${link.id}.jpeg`,
}); });
await prisma.link.update({
where: { id: link.id },
data: {
image: user.archiveAsScreenshot
? `archives/${linkExists.collectionId}/${link.id}.jpeg`
: undefined,
},
});
}) })
); );
} }
@ -47,26 +65,32 @@ const handleScreenshotAndPdf = async (
printBackground: true, printBackground: true,
margin: margins, margin: margins,
}) })
.then((pdf) => { .then(async (pdf) => {
return createFile({ if (
Buffer.byteLength(pdf) >
1024 * 1024 * Number(process.env.PDF_MAX_BUFFER || 2)
)
return console.log(
"Error archiving as PDF: Buffer size exceeded"
);
await createFile({
data: pdf, data: pdf,
filePath: `archives/${linkExists.collectionId}/${link.id}.pdf`, filePath: `archives/${linkExists.collectionId}/${link.id}.pdf`,
}); });
})
);
}
await Promise.allSettled(processingPromises);
await prisma.link.update({ await prisma.link.update({
where: { id: link.id }, where: { id: link.id },
data: { data: {
image: user.archiveAsScreenshot
? `archives/${linkExists.collectionId}/${link.id}.jpeg`
: undefined,
pdf: user.archiveAsPDF pdf: user.archiveAsPDF
? `archives/${linkExists.collectionId}/${link.id}.pdf` ? `archives/${linkExists.collectionId}/${link.id}.pdf`
: undefined, : undefined,
}, },
}); });
})
);
}
await Promise.allSettled(processingPromises);
} }
}; };

View File

@ -120,7 +120,7 @@ export default async function Index(req: NextApiRequest, res: NextApiResponse) {
const form = formidable({ const form = formidable({
maxFields: 1, maxFields: 1,
maxFiles: 1, maxFiles: 1,
maxFileSize: NEXT_PUBLIC_MAX_FILE_BUFFER * 1048576, maxFileSize: NEXT_PUBLIC_MAX_FILE_BUFFER * 1024 * 1024,
}); });
form.parse(req, async (err, fields, files) => { form.parse(req, async (err, fields, files) => {
@ -138,12 +138,20 @@ export default async function Index(req: NextApiRequest, res: NextApiResponse) {
!allowedMIMETypes.includes(files.file[0].mimetype || "") !allowedMIMETypes.includes(files.file[0].mimetype || "")
) { ) {
// Handle parsing error // Handle parsing error
return res.status(500).json({ return res.status(400).json({
response: `Sorry, we couldn't process your file. Please ensure it's a PDF, PNG, or JPG format and doesn't exceed ${NEXT_PUBLIC_MAX_FILE_BUFFER}MB.`, response: `Sorry, we couldn't process your file. Please ensure it's a PDF, PNG, or JPG format and doesn't exceed ${NEXT_PUBLIC_MAX_FILE_BUFFER}MB.`,
}); });
} else { } else {
const fileBuffer = fs.readFileSync(files.file[0].filepath); const fileBuffer = fs.readFileSync(files.file[0].filepath);
if (
Buffer.byteLength(fileBuffer) >
1024 * 1024 * Number(NEXT_PUBLIC_MAX_FILE_BUFFER)
)
return res.status(400).json({
response: `Sorry, we couldn't process your file. Please ensure it's a PDF, PNG, or JPG format and doesn't exceed ${NEXT_PUBLIC_MAX_FILE_BUFFER}MB.`,
});
const linkStillExists = await prisma.link.findUnique({ const linkStillExists = await prisma.link.findUnique({
where: { id: linkId }, where: { id: linkId },
}); });