fix: File Manager large uploads had no server-processing feedback and short nginx timeouts

Reaching 100% in the upload progress bar only means the browser finished SENDING the bytes to nginx - it does not mean the server has finished receiving/saving the file. For multi-GB files this gap was invisible, making a genuinely-still-working upload look frozen at 100 percent, leading to a premature reload (confirmed via nginx access log: status 499, client closed request).

nginx-panel.conf: added fastcgi_request_buffering off on the admin panels /api/ location so nginx streams the body straight to PHP-FPM instead of fully buffering it to a temp file first and reading it back (a full extra disk I/O pass for large files); also added client_body_timeout/fastcgi_send_timeout/send_timeout at 1800s alongside the existing fastcgi_read_timeout, since those are separate timeout phases that previously still defaulted to 60s.

admin.js: added an xhr.upload load-complete handler that switches the dialog to a clear "Finishing up on the server..." state once the send phase hits 100%, so large uploads no longer look stuck during the save phase.
This commit is contained in:
NovaCPX Admin
2026-07-15 14:49:53 -05:00
parent 8adedb9759
commit 3d2c7c25c2
2 changed files with 19 additions and 0 deletions
+7
View File
@@ -47,6 +47,13 @@ http {
fastcgi_param SCRIPT_FILENAME /srv/novacpx/public/api/index.php;
fastcgi_param SERVER_PORT 8882;
fastcgi_read_timeout 1800;
fastcgi_send_timeout 1800;
client_body_timeout 1800;
send_timeout 1800;
# Stream the request body straight to PHP-FPM instead of nginx buffering
# the whole thing to a temp file first and then reading it back — cuts a
# full extra disk read+write pass for large uploads (ISOs, installers).
fastcgi_request_buffering off;
fastcgi_param PHP_VALUE "upload_max_filesize=20G
post_max_size=20G
max_execution_time=1800
+12
View File
@@ -4861,6 +4861,18 @@ window.fmSubmitUpload = () => {
if (pctEl) pctEl.textContent = pct + '%';
if (bytesEl) bytesEl.textContent = fmFormatBytes(e.loaded) + ' / ' + fmFormatBytes(e.total);
});
// Reaching 100% here only means the browser finished SENDING the bytes — the
// server (nginx + PHP) still has to receive/move the file, which for large
// files can take a genuine extra stretch with no further upload events. Make
// that explicit so it doesn't look frozen.
xhr.upload.addEventListener('load', () => {
const pctEl = document.getElementById('fm-upload-pct');
const bytesEl = document.getElementById('fm-upload-bytes');
const bar = document.getElementById('fm-upload-bar');
if (bar) bar.style.background = '#f59e0b';
if (pctEl) pctEl.textContent = 'Finishing up…';
if (bytesEl) bytesEl.textContent = 'Upload sent — waiting for the server to finish saving the file. Large files can take a few extra minutes here. Do not close or reload this page.';
});
xhr.onload = () => {
let res = null;