2010-08-23 4 views
5

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

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

Описание: example, который демонстрирует проблему.

Я хочу видеть цифры от 1 до 5, пока они печатаются.

+1

Возможно, вам понадобится Google для «несовпадающих заголовков» –

+0

@glenn: Я сделал это также, но [этот старый FAQ] (http://httpd.apache.org/docs/1.3/misc/FAQ- F.html # nph-scripts) указывает, что «[a] s скриптов Apache 1.3, CGI по существу не буферизованы. Каждый раз, когда ваш скрипт выполняет «флеш» для вывода данных, эти данные передаются клиенту. Некоторые языки сценариев, например Perl, имеют собственную буферизацию для вывода - это можно отключить, установив специальную переменную '$ |' в '1'.» –

+0

Я указал на http://mywiki.wooledge.org/BashFAQ/009 Буферизация оболочки WRT. до сих пор не понял. – hendry

ответ

6

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

я не нашел другой способ для моего CGI, чтобы отключить автоматическую кодировку Gzip.

+1

О, ничего себе, я отключил 'sudo a2dismod deflate', и теперь он работает !!! !! !!! ! – hendry

+0

Вы также можете отключить gzip для определенных типов файлов. В моих сценариях CGI есть.sh, поэтому я отключу gzip только для сценариев bash: [см. также] (http://stackoverflow.com/questions/1922934/how-to-disable-mod-deflate-in-apache2) – jtv4k

3

Здесь есть несколько факторов. Чтобы устранить несколько проблем, 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 он начинает отображаться немедленно.

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

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

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

+0

Я могу получить только 'curl -vv http: // test.dabase.com/foo.cgi'. Firefox 3.6.8, w3m, Chrome ничего не показывают. :( 0: Можете ли вы рассказать мне, как вы запускаете netcat за один шаг? У меня возникают проблемы с его запуском с установкой моего Apache2 VHOST. Я могу получить только этот завиток из самого хоста. Когда я удален, он перестает работать. :(Я предполагаю, что прокси-сервер испортил это? – hendry

+0

@hendry Для запуска netcat вы вызываете его как «nc localhost 80», а затем вводите HTTP-запрос и заголовки вручную ('GET/cgi- bin/... 'вверх через пустую строку). В этот момент вы должны увидеть ответ, возвращающийся с сервера. Это довольно низкотехнологичный способ отладки HTTP, но может быть полезно посмотреть, что именно происходит Если что-то работает локально, но не удаленно, то я бы ожидал, что прокси-сервер или какой-то аспект вашей конфигурации Apache запутают вас. Я не уверен, как помочь там, не зная больше о вашей настройке. –

+0

Я думал, что вы можете эхо и pipe to nc для более быстрого отладки. – hendry

Смежные вопросы