Implement streaming file download for backup route
- Enhanced the backup server route to support streaming of large backup files using Node.js streams. - Improved error handling for file access and added appropriate HTTP responses for missing parameters and inaccessible files. - Updated response headers to include content length and type for better client handling.
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,12 @@
|
||||
import { env } from '$env/dynamic/private';
|
||||
import { createReadStream } from 'node:fs';
|
||||
import fs from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
import { Readable } from 'node:stream';
|
||||
import type { RequestHandler } from './$types';
|
||||
|
||||
// GET /backup?file=nombre.bak -> descarga el archivo físico desde BACKUP_PATH
|
||||
export const GET = async ({ url }: { url: URL }) => {
|
||||
// GET /backup?file=nombre.bak -> descarga el archivo físico desde BACKUP_PATH (streaming; soporta archivos muy grandes)
|
||||
export const GET: RequestHandler = async ({ url, request }) => {
|
||||
const fileName = url.searchParams.get('file');
|
||||
if (!fileName) {
|
||||
return new Response('Missing file parameter', { status: 400 });
|
||||
@@ -28,14 +31,20 @@ export const GET = async ({ url }: { url: URL }) => {
|
||||
console.error('Backup path is not a regular file:', filePath);
|
||||
return new Response('Backup file not found or inaccessible', { status: 404 });
|
||||
}
|
||||
console.log('Serving backup file from', filePath);
|
||||
const data = await fs.readFile(filePath);
|
||||
console.log('Serving backup file from', filePath, 'size', st.size);
|
||||
const nodeStream = createReadStream(filePath, { highWaterMark: 1024 * 1024 });
|
||||
request.signal.addEventListener('abort', () => {
|
||||
nodeStream.destroy();
|
||||
});
|
||||
const body = Readable.toWeb(nodeStream) as unknown as ReadableStream<Uint8Array>;
|
||||
const headers = new Headers();
|
||||
headers.set('Content-Type', 'application/octet-stream');
|
||||
headers.set('Content-Disposition', `attachment; filename="${fileName}"`);
|
||||
return new Response(data, { status: 200, headers });
|
||||
} catch (e: any) {
|
||||
console.error('Error serving backup file:', e?.message ?? e);
|
||||
headers.set('Content-Length', String(st.size));
|
||||
return new Response(body, { status: 200, headers });
|
||||
} catch (e: unknown) {
|
||||
const msg = e instanceof Error ? e.message : String(e);
|
||||
console.error('Error serving backup file:', msg);
|
||||
return new Response('Backup file not found or inaccessible', { status: 404 });
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user