cc-core-cli
Version:
Command Line Interface tool for generating project templates for the (Your Platform's Name) platform.
80 lines (67 loc) • 2.21 kB
text/typescript
import type { NextApiRequest, NextApiResponse } from 'next';
import Cookies from 'cookies';
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method !== 'GET') {
return res.status(405).json({ message: 'Method not allowed' });
}
const { id } = req.query;
if (!id || typeof id !== 'string') {
return res.status(400).json({ message: 'Missing or invalid file ID' });
}
const cookies = new Cookies(req)
const token = cookies.get('token');
const userAgent = req.headers['user-agent'] || '';
const clientIp =
(req.headers['x-forwarded-for'] as string)?.split(',')[0] ||
req.socket.remoteAddress ||
'';
try {
const apiUrl = `${process.env.API_GATEWAY}/attachment/stream/${encodeURIComponent(id)}`;
const response = await fetch(apiUrl, {
headers: {
Authorization: `Bearer ${token}`,
'X-Client-IP': clientIp === '::1' ? '127.0.0.1' : clientIp,
'User-Agent': userAgent,
},
});
if (!response.ok || !response.body) {
return res.status(response.status).json({ message: 'Error fetching file' });
}
// Forward headers
res.setHeader(
'Content-Disposition',
response.headers.get('content-disposition') || `attachment; filename="${id}"`
);
res.setHeader(
'Content-Type',
response.headers.get('content-type') || 'application/octet-stream'
);
// Pipe fetch response to Next.js response
const reader = response.body.getReader();
const stream = new ReadableStream({
async pull(controller) {
const { done, value } = await reader.read();
if (done) {
controller.close();
} else {
controller.enqueue(value);
}
},
});
const streamResponse = new Response(stream);
const body = streamResponse.body;
if (body) {
body.pipeTo(new WritableStream({
write(chunk) {
res.write(Buffer.from(chunk));
},
close() {
res.end();
},
}));
}
} catch (err: any) {
console.error('Download error:', err?.message || err);
res.status(500).json({ message: 'Error downloading file' });
}
}