looood / src /api /media /route.ts
looda3131's picture
Clean push without any binary history
cc276cc
import { NextRequest, NextResponse } from 'next/server';
import { S3Client, PutObjectCommand, GetObjectCommand } from '@aws-sdk/client-s3';
// Hardcoded credentials for stability in this environment
const R2_ACCOUNT_ID = "057488dfeda40a86a3a5d10340c38db3";
const R2_ACCESS_KEY_ID = "60bf8645223f8566982671ee43911238";
const R2_SECRET_ACCESS_KEY = "2f57e4371382dbb8c6128f2d5edd7f24c31ee1c2d4bbcdb0dbdc2d2fe112dd70";
const R2_BUCKET_NAME = "myapp";
// Initialize S3 client directly
const s3 = new S3Client({
region: 'auto',
endpoint: `https://${R2_ACCOUNT_ID}.r2.cloudflarestorage.com`,
credentials: {
accessKeyId: R2_ACCESS_KEY_ID,
secretAccessKey: R2_SECRET_ACCESS_KEY,
},
});
// GET handler now fetches the object and returns it directly
export async function GET(req: NextRequest) {
try {
const url = new URL(req.url);
const fileKey = url.searchParams.get('fileKey');
if (!fileKey) {
return NextResponse.json({ error: 'File key is required' }, { status: 400 });
}
const command = new GetObjectCommand({
Bucket: R2_BUCKET_NAME,
Key: fileKey,
});
const { Body, ContentType } = await s3.send(command);
if (!Body) {
return NextResponse.json({ error: 'File not found or body is empty' }, { status: 404 });
}
// Return the file content directly as a readable stream
return new NextResponse(Body as any, {
headers: {
'Content-Type': ContentType || 'application/octet-stream',
},
});
} catch (error: any) {
console.error('Error fetching file from R2:', error.message);
// Ensure a JSON error response for client-side error handling
if (error.name === 'NoSuchKey') {
return NextResponse.json({ error: 'File not found' }, { status: 404 });
}
return NextResponse.json({ error: 'Failed to get file from storage', details: error.message }, { status: 500 });
}
}
// POST handler for receiving file from client and uploading to R2
export async function POST(req: NextRequest) {
try {
const formData = await req.formData();
const file = formData.get('file') as File | null;
if (!file) {
return NextResponse.json({ error: 'File is required' }, { status: 400 });
}
const buffer = Buffer.from(await file.arrayBuffer());
const sanitizedFilename = file.name.replace(/[^a-zA-Z0-9._-]/g, '');
const fileKey = `uploads/user-content/${Date.now()}-${sanitizedFilename}`;
const command = new PutObjectCommand({
Bucket: R2_BUCKET_NAME,
Key: fileKey,
Body: buffer,
ContentType: file.type,
});
await s3.send(command);
return NextResponse.json({ fileKey });
} catch (error: any) {
console.error('Error uploading file:', error.message);
return NextResponse.json({ error: 'Failed to upload file', details: error.message }, { status: 500 });
}
}