94d3764c05
Build and Deploy Verso / deploy (push) Has been cancelled
Uploads from slow connections consistently fail with 502 after ~60-120s because an upstream proxy (Traefik or cloud load-balancer) has a "first response byte" deadline that fires before the request body arrives. Fix: add startStreamingResponse middleware (after auth, before multer) that immediately writes HTTP 200 + Transfer-Encoding: chunked + '\n'. With proxy_request_buffering off in Nginx, this reaches the proxy at T≈0, so no timeout triggers. The upload body continues streaming; multer writes to disk; the actual JSON result arrives as the final chunk. Periodic heartbeat '\n' writes every 30s keep response-idle timeouts at bay too. Client-side: override Uppy's getResponseData/validateStatus to trim leading whitespace before JSON.parse so the extra '\n' bytes are ignored. Server-side: sendUploadResponse() helper handles both streaming mode (res.headersSent → res.end(json)) and normal mode (res.status(N).json()). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
103 lines
3.0 KiB
Plaintext
103 lines
3.0 KiB
Plaintext
server {
|
|
listen 80;
|
|
server_name _; # Catch all, see http://nginx.org/en/docs/http/server_names.html
|
|
|
|
root /overleaf/services/web/public/;
|
|
|
|
# block external access to prometheus /metrics
|
|
location /metrics {
|
|
internal;
|
|
}
|
|
|
|
# File upload endpoints: extended timeouts for large files on slow connections.
|
|
# proxy_request_buffering off: forward the request body to Node.js immediately
|
|
# rather than buffering first, so Node.js can send a keepalive response byte
|
|
# before the full body arrives (preventing upstream proxy "first-byte" timeouts).
|
|
# proxy_buffering off: forward that keepalive byte to Traefik/LB without delay.
|
|
location ~ ^/project/[^/]+/upload$ {
|
|
proxy_pass http://127.0.0.1:4000;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Forwarded-Host $host;
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
proxy_request_buffering off;
|
|
proxy_buffering off;
|
|
proxy_read_timeout 15m;
|
|
proxy_send_timeout 15m;
|
|
send_timeout 15m;
|
|
client_body_timeout 15m;
|
|
client_max_body_size 550m;
|
|
}
|
|
|
|
location / {
|
|
proxy_pass http://127.0.0.1:4000;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
proxy_set_header Connection "upgrade";
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Forwarded-Host $host;
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
proxy_read_timeout 10m;
|
|
proxy_send_timeout 10m;
|
|
}
|
|
|
|
location /socket.io {
|
|
proxy_pass http://127.0.0.1:3026;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
proxy_set_header Connection "upgrade";
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Forwarded-Host $host;
|
|
proxy_set_header X-Forwarded-Proto $scheme;
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
proxy_read_timeout 10m;
|
|
proxy_send_timeout 10m;
|
|
}
|
|
|
|
location /stylesheets {
|
|
expires 1y;
|
|
}
|
|
|
|
location /minjs {
|
|
expires 1y;
|
|
}
|
|
|
|
location /img {
|
|
expires 1y;
|
|
}
|
|
|
|
# handle output files for specific users
|
|
location ~ ^/project/([0-9a-f]+)/user/([0-9a-f]+)/build/([0-9a-f-]+)/output/output\.([a-z.]+)$ {
|
|
proxy_pass http://127.0.0.1:8080; # clsi-nginx.conf
|
|
proxy_http_version 1.1;
|
|
}
|
|
# handle output files for anonymous users
|
|
location ~ ^/project/([0-9a-f]+)/build/([0-9a-f-]+)/output/output\.([a-z.]+)$ {
|
|
proxy_pass http://127.0.0.1:8080; # clsi-nginx.conf
|
|
proxy_http_version 1.1;
|
|
}
|
|
# PDF range for specific users
|
|
location ~ ^/project/([0-9a-f]+)/user/([0-9a-f]+)/content/([0-9a-f-]+/[0-9a-f]+)$ {
|
|
proxy_pass http://127.0.0.1:8080; # clsi-nginx.conf
|
|
proxy_http_version 1.1;
|
|
}
|
|
# PDF range for anonymous users
|
|
location ~ ^/project/([0-9a-f]+)/content/([0-9a-f-]+/[0-9a-f]+)$ {
|
|
proxy_pass http://127.0.0.1:8080; # clsi-nginx.conf
|
|
proxy_http_version 1.1;
|
|
}
|
|
|
|
# block external access to metrics
|
|
location ~* ^/metrics/?$ {
|
|
return 404 'Not found';
|
|
}
|
|
|
|
# block external access to all health checks /health_check, /health_check/full, etc
|
|
location ~* ^/health_check {
|
|
return 404 'Not found';
|
|
}
|
|
|
|
# Load any extra configuration for this vhost
|
|
include /etc/nginx/vhost-extras/overleaf/*.conf;
|
|
}
|