mirror of
https://github.com/bewcloud/bewcloud.git
synced 2026-03-11 08:54:49 +00:00
Stream zip archive in download-directory API
Refactored the zip archive creation to stream output directly from the zip process, improving memory efficiency and response time. This fixes out-of-memory crashes on low-end devices.
This commit is contained in:
parent
8d78e1f25c
commit
c3609984b5
1 changed files with 42 additions and 12 deletions
|
|
@ -39,25 +39,55 @@ export const handler: Handlers<Data, FreshContextState> = {
|
|||
const userRootPath = join(filesRootPath, context.state.user.id);
|
||||
const fullDirectoryPath = join(userRootPath, directoryPath);
|
||||
|
||||
// Use the zip command to create the archive
|
||||
// Use the zip command to create the archive with streaming
|
||||
const zipProcess = new Deno.Command('zip', {
|
||||
args: ['-r', '-', '.'],
|
||||
cwd: fullDirectoryPath,
|
||||
stdout: 'piped',
|
||||
stderr: 'piped',
|
||||
}).spawn();
|
||||
|
||||
// Get the zip stream from the process stdout
|
||||
const zipStream = zipProcess.stdout;
|
||||
|
||||
// Monitor process errors and log them (stream will end on error)
|
||||
zipProcess.status.then(async (status) => {
|
||||
if (status.code !== 0) {
|
||||
console.error('Zip command failed with code:', status.code);
|
||||
// Read and log stderr for error details
|
||||
try {
|
||||
const stderrReader = zipProcess.stderr.getReader();
|
||||
try {
|
||||
const chunks: Uint8Array[] = [];
|
||||
while (true) {
|
||||
const { done, value } = await stderrReader.read();
|
||||
if (done) break;
|
||||
if (value) chunks.push(value);
|
||||
}
|
||||
if (chunks.length > 0) {
|
||||
// Concatenate chunks
|
||||
const totalLength = chunks.reduce((acc, chunk) => acc + chunk.length, 0);
|
||||
const combined = new Uint8Array(totalLength);
|
||||
let offset = 0;
|
||||
for (const chunk of chunks) {
|
||||
combined.set(chunk, offset);
|
||||
offset += chunk.length;
|
||||
}
|
||||
const errorText = new TextDecoder().decode(combined);
|
||||
console.error('Zip stderr:', errorText);
|
||||
}
|
||||
} finally {
|
||||
stderrReader.releaseLock();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error reading stderr:', error);
|
||||
}
|
||||
}
|
||||
}).catch((error) => {
|
||||
console.error('Zip process error:', error);
|
||||
});
|
||||
|
||||
const { code, stdout, stderr } = await zipProcess.output();
|
||||
|
||||
if (code !== 0) {
|
||||
const errorText = new TextDecoder().decode(stderr);
|
||||
|
||||
console.error('Zip command failed:', errorText);
|
||||
|
||||
return new Response('Error creating zip archive', { status: 500 });
|
||||
}
|
||||
|
||||
return new Response(stdout, {
|
||||
return new Response(zipStream, {
|
||||
status: 200,
|
||||
headers: {
|
||||
'content-type': 'application/zip',
|
||||
|
|
|
|||
Loading…
Reference in a new issue