如何在Apache 2中提供无缓冲的CGI内容?

11

我想允许用户在长时间运行的GCI脚本生成输出时就能查看它,而不是等到脚本完成后再查看。但是,即使我显式地刷新了STDOUT,服务器似乎仍然会等待脚本完成后才将响应发送给客户端。这是在运行Apache 2.2.9的Linux服务器上发生的。

示例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

有什么想法吗?


1
您可能还会遇到客户端(浏览器)缓冲问题。 - Miles
4个回答

4

我最终在我的应用程序中使用了类似的方法,但我仍然很好奇为什么原始方法在我的设置中无法工作。哎,算了。 - Dave Forgac

2

清空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.";

2
你必须把你的推送脚本放到一个特殊的目录中,该目录包含一个特殊的.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

这与文件上传有什么关系? - Rualark

1
根据 CGI::Push

从版本1.3b2开始的Apache Web服务器不需要安装服务器推送脚本作为NPH脚本:do_push()的-nph参数可以设置为false值,以禁用NPH脚本所需的额外标头。

你只需要在Python中找到do_push的等效物。 编辑:看一下CherryPy:流式传输响应正文

当您将配置条目“response.stream”设置为True(并使用“yield”)时,CherryPy会像这样管理HTTP服务器和代码之间的对话:

alt text
(来源: cherrypy.org)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接