Показаны длительный процесс оболочки с Apache - PullRequest
5 голосов
/ 23 августа 2010

У меня есть скрипт CGI , выполнение которого занимает около 1 минуты. В настоящее время Apache возвращает результаты в браузер только после завершения процесса.

Как мне сделать так, чтобы вывод выводился так, как будто он был запущен на терминале?

Вот пример , который демонстрирует проблему.

Я хочу, чтобы числа от 1 до 5 появлялись по мере их печати. ​​

Ответы [ 2 ]

6 голосов
/ 26 января 2012

Мне пришлось отключить mod_deflate, чтобы режим чанка работал с apache

Я не нашел другого способа для моего cgi отключить автоматическое кодирование в gzip.

3 голосов
/ 25 августа 2010

Здесь есть несколько факторов.Чтобы устранить несколько проблем, Apache и bash не буферизируют какой-либо вывод.Вы можете проверить с помощью этого сценария:

#!/bin/sh

cat <<END
Content-Type: text/plain

END

for i in $(seq 1 10)
do
    echo $i
    sleep 1
done

Вставьте это куда-нибудь, что Apache настроен на выполнение сценариев CGI, и протестируйте с помощью 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

Когда я это делаю, я вижу вnetcat каждый номер появляется один раз в секунду, как и предполагалось.

Обратите внимание, что моя версия Apache, по крайней мере, автоматически применяет кодирование передачи по частям, предположительно, потому что я не включил Content-Length;если вы возвращаете заголовок Transfer-Encoding: chunked самостоятельно, то вам необходимо закодировать вывод вашего скрипта в кодировку передачи по частям.Это довольно просто, даже в сценарии оболочки:

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.

Однако, отправьте это в браузер, и вы получите различные результаты в зависимости от браузера.В моей системе Mac OS X 10.5.8 я вижу разные варианты поведения в моих браузерах.В бета-версиях Safari, Chrome и Firefox 4 я не начинаю видеть вывод, пока не отправлю где-нибудь около 1000 символов (я бы предположил 1024, включая заголовки или что-то в этом роде, но я не сузил их доточное поведение).В Firefox 3.6 он начинает отображаться немедленно.

Я думаю, что эта задержка связана с анализом типа содержимого или анализом кодировки символов , которые находятся в процессе.быть стандартизированным.Я пытался выяснить, смогу ли я обойти задержку, указав надлежащие типы контента и кодировки символов, но без удачи.Возможно, вам придется отправить некоторые данные заполнения (что было бы довольно легко сделать незаметно, если вы используете HTML вместо обычного текста), чтобы выйти за пределы этого начального буфера.

Как только вы начнете потоковую передачу HTML вместо простого текста,структура вашего HTML тоже имеет значение.Некоторый контент может отображаться постепенно, а другой нет.Например, поток <div> s в тело без стилизации работает нормально и может отображаться постепенно по мере поступления.Если вы попытаетесь открыть тег <pre> и просто направить в него содержимое, браузеры на основе Webkit будут ждать, пока не увидят закрывающий тег, чтобы попытаться его разложить, в то время как Firefox с удовольствием покажет его постепенно.Я не знаю всех угловых случаев;вам придется поэкспериментировать, чтобы увидеть, что работает для вас.

В любом случае, я надеюсь, это поможет вам начать работу.Дайте мне знать, если у вас есть еще вопросы!

...