fix: implement streaming downloads for large files
- Add token-based download system with 5-minute expiry - Stream files in 8MB chunks on backend (no memory loading) - Use browser native download with tokens on frontend - Fixes hang on large files (10GB+) by avoiding memory buffering
This commit is contained in:
@@ -203,25 +203,27 @@ export async function download(path, filename) {
|
||||
if (token) headers["Authorization"] = `Bearer ${token}`;
|
||||
|
||||
try {
|
||||
const r = await fetch(`${BASE}/files/download?path=${encodeURIComponent(path)}`, {
|
||||
method: "GET",
|
||||
// Get a temporary download token
|
||||
const tokenResponse = await fetch(`${BASE}/files/download-token?path=${encodeURIComponent(path)}`, {
|
||||
method: "POST",
|
||||
headers,
|
||||
});
|
||||
|
||||
if (!r.ok) {
|
||||
const errorText = await r.text();
|
||||
console.error(`Download failed: ${r.status} - ${errorText}`);
|
||||
throw new Error(`Download failed: ${r.status}`);
|
||||
if (!tokenResponse.ok) {
|
||||
const errorText = await tokenResponse.text();
|
||||
console.error(`Download token failed: ${tokenResponse.status} - ${errorText}`);
|
||||
throw new Error(`Download failed: ${tokenResponse.status}`);
|
||||
}
|
||||
|
||||
const blob = await r.blob();
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const { token: downloadToken } = await tokenResponse.json();
|
||||
|
||||
// Use the token to trigger browser download (no memory loading)
|
||||
const downloadUrl = `${BASE}/files/download?token=${downloadToken}`;
|
||||
const a = document.createElement("a");
|
||||
a.href = url;
|
||||
a.href = downloadUrl;
|
||||
a.download = filename;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
window.URL.revokeObjectURL(url);
|
||||
document.body.removeChild(a);
|
||||
} catch (e) {
|
||||
console.error("Download error:", e);
|
||||
|
||||
Reference in New Issue
Block a user