运行 nph-script.cgi 时,最后不断输出服务器详细信息

运行 nph-script.cgi 时,最后不断输出服务器详细信息

我正在我的服务器上运行 nph-script.cgi。

服务器不断添加

HTTP/1.1 200 OK 日期:2009 年 11 月 5 日星期四 02:28:53 GMT 服务器:Apache/2.2.8 (Ubuntu) PHP/5.2.8-1hardy~ppa1 带有 Suhosin-Patch mod_perl/2.0.3 Perl/v5.8.8 内容长度:0 保持活动:超时=15,最大=100 连接:保持活动 内容类型:纯文本 X-Pad:避免浏览器错误

在每个通过 .cgi 脚本加载的页面底部。为什么会出现这种情况?如何删除附加到所有页面的这个烦人的消息?

答案1

我们发现一个类似的问题与一个 nph 文件有关,它充当 Intersystems Caché(数据库和 Web 应用程序服务器)的网关。只要我们不使用 URL 重写,它就可以正常工作。任何通过 URL 重写处理的请求都会产生上述虚假标头(在响应内容的底部或附近)。

我们尝试使用一个小的 Perl nph 脚本来隔离该错误,但遇到了同样的问题。在不同的服务器上进行了测试:Ubuntu 9.04 上的 Apache/2.2.11、Debian 5.0 上的 Apache/2.2.9 和 Red Hat EL 4 上的 Apache/2.0.52。

脚本nph-测试.cgi在常规 cgi-bin 目录中:

#!/usr/bin/perl -wT
use strict;
print "$ENV{SERVER_PROTOCOL} 200 OK\n";
print "Server: $ENV{SERVER_SOFTWARE}\n";
print "Content-Type: text/plain\n\n";

# Tell Perl not to buffer our output
$| = 1;

print "OK.";

URL 重写

RewriteEngine On
RewriteRule ^test/([0-9]+)$ /cgi-bin/nph-test.cgi

(在 Apache .conf 文件中,在 下Directory /var/www/

回复

OK.
HTTP/1.1 200 OK
Date: Mon, 07 Dec 2009 09:44:40 GMT
Server: Apache/2.2.11 (Ubuntu) PHP/5.2.6-3ubuntu4.2 with Suhosin-Patch
Content-Length: 0
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Content-Type: text/plain

描述相同或类似问题的其他来源:

对于测试脚本来说,使用 Content-Length 是可行的,但不能解决我们的问题,因为我们显然无法更改 Intersystems Caché 附带的 nph-cgi 可执行文件。

正如您所说,这可能应该提交给 Apache,但 httpd.apache.org/bug_report.html 上列出的规则相当令人生畏。(我对 Apache 的了解有限。)

答案2

您确定服务器设置正确吗?考虑到消息声称内容类型是 text/plain 而不是 text/html 或其他内容,我认为您的 CGI 或 .cgi 脚本设置有问题。

答案3

这是我在我们自己的 WAMP 服务器以及 LAMP 托管环境中偶尔看到的一个问题。Apache 1.3 和 2.0 的后续版本似乎限制了这个问题,但它经常出现在 2.2 中。

当 NPH 脚本与重写结合使用时,这个问题尤其突出。如果您处理自己的 gzip 压缩,这个问题会进一步加剧,这在使用 NPH 脚本时几乎是必需的。如果您不使用 URL 重写,问题几乎就会消失。

任何地方都没有记录这个问题,我不得不自己确定可能的原因和解决方案。我能够(大部分)通过以下方式解决该问题:添加 Content-Length 标头。这仅在您在发送到客户端之前累积页面输出时才有效,这样您就可以计算标头的字节大小。

例如,在构建页面时,如果您使用 Perl,则可以将它们累积到一个变量中,例如,$HTML然后在处理完所有页面处理后,将其发送到处理最终输出的子程序。我还会根据需要在最终输出之前将标题单独累积到一个变量中,这有效地节省了我多次处理输出的麻烦,这对调试很有帮助。

以下是不支持 gzip 输出的代码片段:

子完成{
    我的($STATUS,$HEADER,$TYPE,$HTML,$ISNPH)= @_;
    我的 $HTTP_PROTOCOL = $ENV{'SERVER_PROTOCOL'}
        如果 ($ENV{'SERVER_PROTOCOL'}
            && $ENV{'SERVER_PROTOCOL'} =~ m/^HTTP\/\d\.\d\$/);
    $HTTP_PROTOCOL ||= 'HTTP/1.1';
    $状态||= 200;
    $TYPE ||='文本/html';
    如果 ($STATUS =~ m/^30[123]$/) {
        $HEADER .= "内容长度: 0\n";
        打印“$HTTP_PROTOCOL $STATUS\n”;
        打印$HEADER;
        打印“内容类型:$TYPE \n”;
        打印“位置:$HTML\n\n”;
        出口;
    }
    如果 ($ISNPH),则打印“$HTTP_PROTOCOL $STATUS\n”;
    打印$HEADER;
    打印“内容类型:$TYPE \n”;
    打印'Content-Length:'.length($HTML)。“\n”如果($ISNPH);
    打印“\n”;
    打印$HTML;
    出口;
}

它可以被这样调用:

&finish('200', $HEADER, 'text/html', $HTML, 1);

如果您在使脚本支持 NPH 之前对其进行测试,只需将 a0作为最后一个参数传递即可。只需在此函数调用之前完全不打印到客户端,然后将标题构建到$HEADERHTML 中即可$HTML

如果您要进行重定向,请在参数中传递要重定向到的 URL $HTML。在重定向场景中不需要实际的 HTML 输出。

如果仍然遇到问题,请进一步解决问题,并使用输出缓冲on&测试您的脚本off

在某些情况下,这可能无法解决问题,我还没有找到解决方案,应该将其提交给 Apache 组。我只懂 CGI 编程,所以我没有能力研究 Apache 源代码或提交补丁,但希望有人能解决这个问题。

〜杰伊

相关内容