From b5ec33e3204eb3df7025d036225213b96e08a893 Mon Sep 17 00:00:00 2001 From: Thomas Lai Date: Fri, 30 Aug 2024 12:56:46 -0400 Subject: [PATCH] fix uploading magazines size limit by using streams --- .../src/pages/api/content/magazine/upload.ts | 46 +++++++++++++++---- 1 file changed, 38 insertions(+), 8 deletions(-) diff --git a/lantern-club/src/pages/api/content/magazine/upload.ts b/lantern-club/src/pages/api/content/magazine/upload.ts index 62766dc..39d02ef 100644 --- a/lantern-club/src/pages/api/content/magazine/upload.ts +++ b/lantern-club/src/pages/api/content/magazine/upload.ts @@ -1,10 +1,20 @@ import type { NextApiRequest, NextApiResponse } from 'next'; -import { IncomingForm, File as FormidableFile } from 'formidable'; // Correct import for FormidableFile -import { uploadFileToS3 } from '../../../../utils/uploadFileToS3'; +import { IncomingForm, File as FormidableFile } from 'formidable'; +import AWS from 'aws-sdk'; +import fs from 'fs'; +import { v4 as uuidv4 } from 'uuid'; + +AWS.config.update({ + accessKeyId: process.env.AWS_ACCESS_KEY_ID, + secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, + region: process.env.AWS_REGION, +}); + +const s3 = new AWS.S3(); export const config = { api: { - bodyParser: false, + bodyParser: false, // Disable body parsing to allow Formidable to handle the request }, }; @@ -14,7 +24,8 @@ export default function handler(req: NextApiRequest, res: NextApiResponse) { return; } - const form = new IncomingForm(); + const form = new IncomingForm(); // Correctly initializing IncomingForm + form.parse(req, async (err, fields, files) => { if (err) { res.status(500).json({ error: err.message }); @@ -22,20 +33,39 @@ export default function handler(req: NextApiRequest, res: NextApiResponse) { } // Assuming the file input field is named 'file' - const file = files['file'] && files['file'][0]; + const file = Array.isArray(files['file']) ? files['file'][0] : files['file']; if (!file) { res.status(400).json({ error: 'No file uploaded' }); return; } try { - const fileUrl = await uploadFileToS3(file as FormidableFile, "uploads"); + // Upload the file stream to S3 + const fileUrl = await uploadStreamToS3(file as FormidableFile, "uploads"); res.status(200).json({ url: fileUrl }); - return } catch (error) { console.error('Failed to upload file to S3', error); res.status(500).json({ error: 'Failed to upload file to S3' }); - return } }); } + +async function uploadStreamToS3(file: FormidableFile, folder: string): Promise { + const key = `${folder}/${uuidv4()}_${file.originalFilename}`; + + const uploadParams = { + Bucket: process.env.AWS_BUCKET_NAME as string, + Key: key, + Body: fs.createReadStream(file.filepath), // Stream the file content + ContentType: file.mimetype || 'application/octet-stream', + }; + + return new Promise((resolve, reject) => { + s3.upload(uploadParams, (err: any, data: { Location: string | PromiseLike; }) => { + if (err) { + return reject(err); + } + resolve(data.Location); + }); + }); +}