Как я могу обслуживать небуферизованный контент CGI из Apache 2?

Я хотел бы иметь возможность разрешить пользователю просматривать выходные данные долго работающего сценария GCI по мере его создания, а не после завершения сценария. Однако даже когда я явно сбрасываю STDOUT, сервер, кажется, ждет завершения скрипта перед отправкой ответа клиенту. Это на сервере Linux под управлением Apache 2.2.9.

Пример Python CGI:

#!/usr/bin/python

import time
import sys


print "Content-type: text/plain"
print
for i in range(1, 10):
        print i
        sys.stdout.flush()
        time.sleep(1)

print "Done."

Аналогичный пример на perl:

#!/usr/bin/perl

print "Content-type: text/plain\n\n";

for ($i = 1; $i <= 10 ; $i++) {
        print "$i\n";
        sleep(1);
}

print "Done.";

В этой ссылке говорится, что начиная с Apache 1.3 вывод CGI должен быть небуферизованным (но это может относиться только к Apache 1.x): http://httpd.apache.org/docs/1.3/misc/FAQ-F.html#nph-scripts

Любые идеи?


person Dave Forgac    schedule 25.07.2009    source источник
comment
Вы также можете столкнуться с проблемами буферизации на стороне клиента (браузера).   -  person Miles    schedule 25.07.2009


Ответы (4)


Статья Рэндала Шварца Наблюдение за длинными процессами через CGI объясняет другое (и IMHO, лучше ) способ наблюдения за длительным процессом.

person Sinan Ünür    schedule 25.07.2009
comment
В итоге я использовал аналогичный метод для своего приложения, но мне все еще любопытно, почему исходный метод не работает в моей настройке. Ну что ж. - person Dave Forgac; 22.09.2009

Вы должны поместить свой push-скрипт в специальный каталог, который содержит специальный .htaccess со следующими спецификациями среды:

Options +ExecCGI
AddHandler cgi-script .cgi .sh .pl .py
SetEnvIfNoCase Content-Type \
"^multipart/form-data;" "MODSEC_NOPOSTBUFFERING=Do not buffer file uploads"
SetEnv no-gzip dont-vary
person F. Hauri    schedule 14.11.2010

Промывка STDOUT может помочь. Например, следующая программа Perl должна работать должным образом:

#!/usr/bin/perl

use strict;
use warnings;

local $| = 1;

print "Content-type: text/plain\n\n";

for ( my $i = 1 ; $i <= 10 ; $i++ ) {
    print "$i\n";
    sleep(1);
}

print "Done.";
person Alan Haggai Alavi    schedule 25.07.2009

Согласно CGI :: Push,

Веб-сервер Apache, начиная с версии 1.3b2, не требует установки сценариев push-уведомлений на сервер как сценариев NPH: для параметра -nph для do_push () может быть установлено значение false, чтобы отключить дополнительные заголовки, необходимые для сценария NPH.

Вам просто нужно найти эквивалент do_push в python.

Изменить. Взгляните на CherryPy: потоковая передача тела ответа.

Когда вы устанавливаете для записи конфигурации response.stream значение True (и используете yield) CherryPy управляет диалогом между HTTP-сервером и вашим кодом следующим образом:

alt text
(источник: cherrypy.org)

person Eugene Yokota    schedule 25.07.2009