2010-07-07 15 views
5

Estoy tratando de proporcionar un análisis en vivo de una carga de archivo en CGI y mostrar los datos en la pantalla mientras se cargan.Apache2 y CGI: ¿cómo evitar que Apache guarde en búfer los datos POST?

Sin embargo, Apache2 parece querer esperar a que se complete la POST completa antes de enviar nada a la aplicación CGI.

¿Cómo puedo forzar a Apache2 a detener el almacenamiento en búfer de la POST en mi aplicación CGI?

EDITAR

Parece ser que en realidad es la salida del CGI que está siendo amortiguada. Empecé a transmitir los datos a un archivo temporal para ver su progreso. Eso, y tengo otro problema.

1) La salida se está almacenando en el búfer. He intentado SetEnvIf (y simplemente SetEnv) para "! Nogzip", "nogzip" y "! Gzip" sin éxito (dentro de la definición del Directorio CGI).

2) Apache2 parece no estar leyendo la salida del CGI hasta que finalice el proceso CGI? Observé que mi aplicación CGI (enrojecida o no) colgaba permanentemente en una línea "fwrite (..., stdout)" alrededor de los 80K.

EDITAR

bien, Firefox está jugando conmigo. Si envío un archivo de 150K, entonces no hay un bloqueo CGI alrededor de 80K. Si el archivo es 2G, entonces hay un bloqueo. Entonces, Firefox no está leyendo el resultado del servidor mientras está tratando de enviar el archivo ... ¿hay algún encabezado o tipo de contenido alternativo para cambiar ese comportamiento?

EDITAR

Está bien, supongo que el bloqueo de la producción CGI en archivos de gran tamaño no es importante en realidad. ¡No necesito repetir el archivo! Estoy depurando un problema causado por las herramientas de depuración. :)

Supongo que esto funciona bastante bien entonces. ¡Gracias!

NOTA FINAL

Así como una nota ... la razón por la que pensé fue Apache 2 buffering de entrada fue que siempre me dieron una variable de entorno "Content-Length". Creo que FireFox es lo suficientemente inteligente como para precalcular la duración del contenido de una carga de formulario multiparte y Apache2 estaba pasando eso. Pensé que Apache2 estaba almacenando en búfer la entrada e informando la longitud misma.

Respuesta

3

¿Estás seguro de que el problema es la entrada que se está almacenando en el búfer? Los problemas de almacenamiento en búfer de salida son mucho más comunes y pueden no ser distinguibles del búfer de entrada, si su método de depuración es algo así como print en la respuesta.

(buffering de salida es comúnmente causada ya sea por no volcados stdout en la secuencia de comandos o mediante filtros. El culpable habitual es el filtro DEFLATE, que a menudo se utiliza para comprimir todos los text/ respuestas, ya sea que provengan de un archivo estático o un guión. En general, es una buena idea comprimir el resultado de las secuencias de comandos, pero un efecto secundario que hará que la respuesta esté totalmente almacenada en el búfer. Si necesita una respuesta inmediata, deberá desactivarla para esa secuencia de comandos o para todas las secuencias. scripts, mediante la limitación de la aplicación de AddOutputFilterByType a particulares <Directory> s, o el uso de mod_setenvif para establecer la nota !nogzip.)

de manera similar, una entrada f ilter (incluyendo, de nuevo DEFLATE) puede hacer que la entrada CGI se guarde en el búfer, si está utilizando alguna. Pero son menos utilizados.

Editar: por ahora, solo comente cualquier httpd conf que tenga habilitado el filtro desinflar. Puede volver a colocarlo de manera selectiva una vez que esté satisfecho de que su IO no esté en búfer sin él.

Noté que mi aplicación CGI (enrojecida o no) cuelga permanentemente en una línea "fwrite (..., stdout)" alrededor de 80K.

Sí ... si no ha leído todas sus entradas, puede atascar cuando intente escribir salida, si escribe demasiado. Puede bloquear en una llamada de salida, esperando que los búferes de red se desactiven para que pueda enviar los nuevos datos que tiene, pero nunca lo harán porque el navegador está tratando de enviar todos sus datos antes de que comience a leer la salida.

¿Qué estás trabajando aquí? En general, no tiene sentido escribir salida de información de progreso en respuesta a un formulario directo POST, porque los navegadores normalmente no lo mostrarán. Si desea proporcionar retroalimentación de progreso de carga en un envío de formulario HTML sencillo, esto generalmente se hace con intrusiones como tener una comprobación de conexión AJAX para ver cómo va la carga (es decir, la información de progreso debe compartirse, por ejemplo, en una base de datos), o utilizando un componente de carga Flash.

+0

Estoy probando la línea! Nogzip sin mucho éxito. También ahora tengo un problema de salida stdout, como se detalla anteriormente. – darron

+0

Dado que era un problema de salida después de todo, y la información de DEFLATE es bastante útil, estoy marcando esta como respuesta. – darron

+0

Sí, la salida no era necesaria. Lo habilité para la depuración, y me hizo tropezar un poco. El plan fue todo el tiempo para comentarios de AJAX. En realidad, voy a tratar de analizar y mostrar el archivo tal como aparece ... debería verse muy bien. Menor, pero ordenado. – darron

0

Desde un (versión antigua) de los manuales del Servidor Apache HTTP:

Cada vez que su script hace un a los datos de salida "al ras", que los datos se retransmiten en el cliente. Algunos lenguajes de scripting , por ejemplo Perl, tienen su propio búfer para la salida; este se puede deshabilitar configurando $ | variable especial a 1. Por supuesto, este aumenta la cantidad total de paquetes que se transmiten, lo que puede dar lugar a una sensación de lentitud para el usuario final .

¿Ha intentado lavar STDOUT o comprobar si el idioma que está utilizando tiene memoria intermedia que puede deshabilitar?

+0

Sí, estoy descargando STDOUT a intervalos de 8K ... sin efecto aparente. – darron

0

Ésta es una guía útil para el control de amortiguación cuando se utiliza Perl en el lado del servidor:

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

muchas de las ideas y conceptos se aplican a otros idiomas también, como el uso de buffer y la salida sin búfer, el sistema de primas llamadas para leer y escribir datos en comparación con las bibliotecas de E/S que hacen su propio almacenamiento en búfer.

Cuestiones relacionadas