Apache2 et CGI – comment empêcher Apache de mettre en mémoire tampon les données POST?

J’essaie de fournir une parsing en direct d’un téléchargement de fichier dans CGI et d’afficher les données à l’écran au fur et à mesure de leur téléchargement.

Cependant, Apache2 semble vouloir attendre la fin du test POST avant d’envoyer l’application CGI.

Comment puis-je forcer Apache2 à arrêter la mise en mémoire tampon du POST dans mon application CGI?

MODIFIER

Il semble que ce soit en fait la sortie du CGI qui est en mémoire tampon. J’ai commencé à diffuser les données dans un fichier temporaire pour voir ses progrès. Cela et j’ai un autre problème.

1) La sortie est en tampon. J’ai essayé SetEnvIf (et simplement SetEnv) pour “! Nogzip”, “nogzip” et “! Gzip” sans succès (dans la définition du répertoire CGI).

2) Apache2 semble ne pas lire la sortie du CGI tant que le processus CGI n’est pas terminé? Je remarque que mon application CGI (rinçage ou non) raccroche en permanence sur une ligne “fwrite (…, stdout)” à environ 80K.

MODIFIER

Ok, Firefox joue avec moi. Si j’envoie un fichier 150K, il n’y a pas de locking CGI autour de 80K. Si le fichier est 2G, il y a un blocage. Ainsi, Firefox ne lit pas la sortie du serveur pendant qu’il essaie d’envoyer le fichier … existe-t-il un en-tête ou un autre type de contenu pour modifier ce comportement?

MODIFIER

Ok, je suppose que le blocage de sortie CGI sur les gros fichiers n’est pas important en fait. Je n’ai pas besoin de faire écho au fichier! Je débogue un problème causé par les aides au débogage. 🙂

Je suppose que cela fonctionne assez bien alors. Merci!

NOTE FINALE

Juste comme une note … la raison pour laquelle je pensais qu’Apache2 mettait en mémoire tampon l’entrée était que j’avais toujours une variable d’environnement “Content-Length”. Je suppose que FireFox est suffisamment intelligent pour calculer la longueur du contenu d’un téléchargement de formulaire en plusieurs parties et qu’Apache2 le transmet. Je pensais qu’Apache2 mettait en mémoire tampon l’entrée et signalait la longueur elle-même.

Etes-vous sûr que le problème est lié à l’entrée mise en mémoire tampon? Les problèmes de mise en mémoire tampon des sorties sont beaucoup plus fréquents et peuvent ne pas être distingués de la mise en mémoire tampon en entrée, si votre méthode de débogage consiste simplement à print la réponse.

(La mise en mémoire tampon de sortie est généralement causée par une sortie stdout non purgée dans le script ou par des filtres. Le filtre DEFLATE est souvent utilisé pour compresser tous les text/ réponses, qu’ils proviennent d’un fichier statique ou d’un script. une bonne idée pour compresser la sortie des scripts, mais cela risque d’entraîner une mise en mémoire tampon complète de la réponse.Si vous avez besoin d’une réponse immédiate, vous devrez la désactiver pour ce script ou tous les scripts, en limiter l’application de AddOutputFilterByType à un particulier, ou utiliser mod_setenvif pour définir la note !nogzip .)

De même, un filtre d’entrée (y compris, encore une fois DEFLATE ) peut entraîner la mise en mémoire tampon de l’entrée CGI, si vous en utilisez. Mais ils sont moins largement utilisés.

Edit: pour l’instant, il suffit de commenter n’importe quelle httpd conf vous permettant d’activer le filtre de dégonflage. Vous pouvez le remettre de manière sélective une fois que vous êtes heureux que votre IO soit sans tampon.

Je remarque que mon application CGI (rinçage ou non) raccroche en permanence sur une ligne “fwrite (…, stdout)” à environ 80K.

Ouais … si vous n’avez pas lu toutes vos entrées, vous pouvez vous bloquer en essayant d’écrire des sorties, si vous écrivez trop. Vous pouvez bloquer un appel en sortie, en attendant que les tampons du réseau soient débloqués pour que vous puissiez envoyer les nouvelles données que vous avez, mais ils ne le feront jamais car le navigateur essaie d’envoyer toutes ses données avant de commencer à lire la sortie.

Sur quoi travaillez-vous ici? En général, il n’est pas logique d’écrire une sortie d’informations de progression en réponse à une requête POST directe, car les navigateurs ne l’afficheront généralement pas. Si vous souhaitez fournir des commentaires sur la progression du téléchargement sur un envoi HTML simple, cela se fait généralement avec des hacks, comme la vérification de la connexion AJAX pour voir comment le téléchargement se déroule (les informations de progression doivent être partagées, par exemple dans une firebase database). ), ou en utilisant un composant de téléchargement Flash.

A partir d’une (ancienne version) des manuels Apache HTTP Server:

Chaque fois que votre script effectue un “vidage” pour générer des données, celles-ci sont transmises au client. Certains langages de script, par exemple Perl, ont leur propre mise en mémoire tampon pour la sortie – cela peut être désactivé en définissant le $ | variable spéciale à 1. Bien sûr, cela augmente le nombre total de paquets en cours de transmission, ce qui peut entraîner une impression de lenteur pour l’utilisateur final.

Avez-vous essayé de vider STDOUT ou de vérifier si la langue que vous utilisez possède une mise en mémoire tampon que vous pouvez désactiver?

Voici un guide utile pour contrôler la mise en mémoire tampon lors de l’utilisation de perl côté serveur:

http://perl.plover.com/FAQs/Buffering.html

Beaucoup d’idées et de concepts s’appliquent également à d’autres langages, comme l’utilisation de sorties tamponnées et non tamponnées, d’appels système bruts pour lire et écrire des données par rapport aux bibliothèques d’E / S qui effectuent leur propre mise en mémoire tampon.