web-dev-qa-db-fra.com

nginx upload problème client_max_body_size

J'exécute nginx/Ruby-on-Rails et j'ai un simple formulaire en plusieurs parties pour télécharger des fichiers. Tout fonctionne bien jusqu'à ce que je décide de limiter la taille maximale des fichiers que je veux télécharger. Pour ce faire, je règle nginx client_max_body_size sur 1m (1MB) et attend un statut HTTP 413 (demande d'entité trop grande) en réponse lorsque cette règle est rompue.

Le problème, c'est que lorsque je télécharge un fichier de 1,2 Mo, au lieu d'afficher la page d'erreur HTTP 413, le navigateur se bloque un peu, puis meurt avec le message "La connexion a été réinitialisée pendant le chargement de la page".

J'ai essayé à peu près toutes les options proposées par nginx, rien ne semble fonctionner. Est-ce que quelqu'un a des idées à ce sujet?

Voici mon nginx.conf:

_worker_processes  1;
timer_resolution  1000ms;
events {
    worker_connections  1024;
}

http {
    passenger_root /the_passenger_root;
    passenger_Ruby /the_Ruby;

    include       mime.types;
    default_type  application/octet-stream;

    sendfile           on;
    keepalive_timeout  65;

    server {
      listen 80;
      server_name www.x.com;
      client_max_body_size 1M;
      passenger_use_global_queue on;
      root /the_root;
      passenger_enabled on;

      error_page 404 /404.html;
      error_page 413 /413.html;    
    }    
}
_

Merci.


**Edit**

Environnement/UA: Windows XP/Firefox 3.6.13

113
krukid

nginx "échoue rapidement" lorsque le client l'informe qu'il va envoyer un corps plus grand que le client_max_body_size en envoyant une réponse 413 et en fermant la connexion.

La plupart des clients ne lisent pas les réponses avant l'envoi complet du corps de la demande. Comme nginx ferme la connexion, le client envoie des données au socket fermé, provoquant un TCP RST.

Si votre client HTTP le prend en charge, la meilleure solution consiste à envoyer un en-tête Expect: 100-Continue. Nginx prend correctement en charge cette fonctionnalité à partir de la version 1.2.7 et répondra avec une réponse 413 Request Entity Too Large plutôt que 100 Continue si Content-Length dépasse la taille maximale du corps.

123
Joe Shaw

Est-ce que votre téléchargement meurt à la toute fin? 99% avant de s'écraser? Le corps du client et les tampons sont essentiels car nginx doit mettre en tampon les données entrantes. Le corps configs (données du corps de la requête) spécifie comment nginx gère le flux de données en bloc binaires provenant de clients multi-parties dans la logique de votre application.

Le paramètre clean libère de la mémoire et des limites de consommation en demandant à nginx de stocker la mémoire tampon entrante dans un fichier, puis de nettoyer ce fichier ultérieurement du disque en le supprimant.

Réglez body_in_file_only sur clean et ajustez les tampons pour le client_max_body_size. La configuration de la question initiale avait déjà envoyé le fichier, augmenter les délais d'attente aussi. J'utilise les paramètres ci-dessous pour résoudre ce problème, qui convient à votre contexte local de configuration, de serveur et http.

client_body_in_file_only clean;
client_body_buffer_size 32K;

client_max_body_size 300M;

sendfile on;
send_timeout 300s;
48
Bent Cardan

De la documentation :

Il faut garder à l'esprit que les navigateurs ne savent pas comment afficher correctement cette erreur.

Je suppose que c'est ce qui se passe, si vous inspectez le protocole HTTP à l'aide d'outils tels que Firebug ou en-têtes HTTP en direct (les deux extensions Firefox), vous pourrez pour voir ce qui se passe réellement.

7
ZoFreX