Aquí hay varios factores en juego. Para eliminar algunos problemas, Apache y bash no almacenan en búfer ninguno de los resultados. Puede comprobar con este script:
#!/bin/sh
cat <<END
Content-Type: text/plain
END
for i in $(seq 1 10)
do
echo $i
sleep 1
done
Pegue esto en alguna parte que Apache está configurado para ejecutar scripts CGI, y probar con netcat:
$ nc localhost 80
GET /cgi-bin/chunkit.cgi HTTP/1.1
Host: localhost
HTTP/1.1 200 OK
Date: Tue, 24 Aug 2010 23:26:24 GMT
Server: Apache/2.2.14 (Unix) mod_ssl/2.2.14 OpenSSL/0.9.7l DAV/2
Transfer-Encoding: chunked
Content-Type: text/plain
2
1
2
2
2
3
2
4
2
5
2
6
2
7
2
8
2
9
3
10
0
Cuando hago esto, veo en netcat cada número que aparece una vez por segundo, según lo previsto.
Tenga en cuenta que mi versión de Apache, al menos, aplica la codificación de transferencia fragmentada automáticamente, presumiblemente porque no incluí un Content-Length
; si devuelve el encabezado Transfer-Encoding: chunked
usted mismo, entonces necesita codificar el resultado de su secuencia de comandos en la codificación de transferencia fragmentada. Eso es bastante fácil, incluso en un script de shell:
chunk() {
printf '%x\r\n' "${#1}" # Length of the chunk in hex, CRLF
printf '%s\r\n' "$1" # Chunk itself, CRLF
}
chunk $'1\n' # This is a Bash-ism, since it's pretty hard to get a newline
chunk $'2\n' # character portably.
Sin embargo, sirven a un navegador, y obtendrá resultados variables dependiendo del navegador. En mi sistema, Mac OS X 10.5.8, veo diferentes comportamientos entre mis navegadores. En Safari, Chrome y Firefox 4 beta, no empiezo a ver la salida hasta que he enviado alrededor de 1000 caracteres (supongo que 1024 incluye los encabezados, o algo así, pero no lo he reducido al comportamiento exacto). En Firefox 3.6, comienza a mostrarse de inmediato.
Supongo que este retraso se debe a content type sniffing, o character encoding sniffing, que están en proceso de estandarización. Intenté ver si podía superar el retraso especificando los tipos de contenido y las codificaciones de caracteres adecuados, pero sin suerte. Puede que tenga que enviar algunos datos de relleno (lo que sería bastante fácil de hacer de forma invisible si utiliza HTML en lugar de texto sin formato), para ir más allá de ese búfer inicial.
Una vez que comience a transmitir HTML en lugar de texto sin formato, también importa la estructura de su HTML. Algunos contenidos pueden mostrarse progresivamente, mientras que otros no. Por ejemplo, la transmisión hacia abajo <div>
s en el cuerpo, sin ningún estilo, funciona bien, y puede mostrarse progresivamente a medida que llega. Si intentas abrir una etiqueta <pre>
y simplemente transmitir contenido a eso, los navegadores basados en Webkit esperarán hasta que vean la etiqueta de cierre para tratar de establecer eso, mientras que Firefox se complace en mostrarla progresivamente. No conozco todos los casos de esquina; Tendrás que experimentar para ver qué funciona para ti.
De todos modos, espero que esto lo ayude a comenzar. ¡Avíseme si tiene más preguntas!
Es posible que desee buscar en Google "encabezados no analizados" –
@glenn: también lo hice, pero [esta antigua pregunta frecuente] (http://httpd.apache.org/docs/1.3/misc/FAQ- F.html # nph-scripts) establece que "[a] s de Apache 1.3, los scripts CGI esencialmente no están almacenados en búfer. Cada vez que la secuencia de comandos realiza un "lavado" de los datos de salida, los datos se transmiten al cliente. Algunos lenguajes de scripting, por ejemplo Perl, tienen su propio buffer para la salida, esto se puede deshabilitar estableciendo la variable especial '$ |' en '1'." –
me han señalado http://mywiki.wooledge.org/BashFAQ/009 WRT shell buffering. todavía no lo he descubierto. – hendry