Un envoi qui échoue à une frontière de taille est une limite — voir 413 Requête trop volumineuse. Un envoi qui échoue en cours de route, à aucune taille constante, la connexion tombant simplement, est un délai d'attente quelque part sur le trajet.
Les délais à relever, tous
# nginx
client_body_timeout 300s;
client_max_body_size 512M;
send_timeout 300s;
fastcgi_read_timeout 300s;
proxy_read_timeout 300s;
; php
max_execution_time = 300
max_input_time = 300 ; the one that is forgotten - it covers the UPLOAD itself
max_input_time limite le temps que PHP passera à recevoir la requête. Il est distinct de max_execution_time, sa valeur par défaut est basse, et c'est lui qui tue un envoi lent depuis un téléphone.
Disque et espace temporaire
df -h /tmp /var/lib/php/tmp
grep upload_tmp_dir /etc/php/8.3/fpm/php.ini
Un envoi est d'abord écrit dans un fichier temporaire. Si ce système de fichiers se remplit, l'écriture échoue en plein transfert et la connexion tombe sans message nulle part.
Cherchez ce qui a été consigné
sudo tail -50 /var/log/nginx/error.log
sudo journalctl -u php8.3-fpm -n 50 --no-pager
client intended to send too large body, c'est la limite de taille. timed out et upstream prematurely closed, ce sont les délais ci-dessus. Rien du tout signifie en général que le navigateur ou un proxy a renoncé avant le serveur.
La vraie solution pour les gros fichiers
L'envoi par morceaux ou reprenable découpe un gros fichier en de nombreuses petites requêtes : aucune requête n'est longue, et une connexion tombée reprend au lieu de repartir de zéro. Au-delà de quelques centaines de mégaoctets, c'est la seule réponse fiable.