我在我的服务器上运行一个nph-script.cgi。
服务器不断添加
HTTP / 1.1 200 OKdate:星期四,2009年11月05日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 Content-Length:0 Keep-Alive:timeout = 15,max = 100 Connection:Keep-Alive Content-Type:text / plain X-Pad:避免浏览器bug
在通过.cgi脚本加载的每个页面的底部。 这是为什么呢? 我如何删除附加到所有页面的烦人的消息?
我们看到一个类似nph文件的问题,它充当了IntersystemsCaché(一个数据库和Web应用程序服务器)的网关。 只要我们不使用URL重写,就可以正常工作。 任何通过URL重写处理的请求都会产生上述虚假标题(在响应内容的底部或附近)。
我们试图用一个小的Perl脚本来隔离这个bug,并且遇到了同样的问题。 在不同的服务器上进行testing:Ubuntu 9.04上的Apache / 2.2.11,Debian 5.0上的Apache / 2.2.9以及Red Hat EL 4上的Apache / 2.0.52。
在常规的cgi-bin目录下脚本nph-test.cgi :
#!/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作为testing脚本,但并不能解决我们的问题,因为我们显然不能更改IntersystemsCaché附带的nph-cgi可执行文件。
正如你所说,这可能应该提交给Apache,但在httpd.apache.org/bug_report.html规定的规则是相当艰巨的。 (我对Apache的知识有限。)
你确定服务器安装正确吗? 考虑到这个消息宣称内容types是text / plain而不是text / html或者别的什么,我在想如何设置CGI或者你的.cgi脚本是错误的。
这是我偶尔在我们自己的WAMP服务器以及LAMP托pipe环境中看到的问题。 Apache 1.3和2.0以后的版本似乎限制了这个问题,但是它经常是2.2的问题。
这个问题主要在NPH脚本与重写结合时发音。 如果你处理你自己的gzip压缩,这个问题会更加复杂,这在使用NPH scrips时是非常必要的。 如果你不使用URL重写,这个问题几乎消失。
这是没有logging在任何地方,我不得不自己确定可能的原因和解决scheme。 我已经能够(大多数)以下面的方式解决这个问题:添加一个Content-Length头。 如果您在发送到客户端之前累积页面输出,这将只会工作,以便您可以计算标题的字节大小。
例如,当你build立你的页面时,如果你使用Perl,你可以把它们堆积成一个variables,例如$ HTML,然后当你处理了所有的页面处理时,你可以把它发送到一个处理最终输出的子程序。 我所做的也是在最终输出之前,根据需要将头文件分别存储到一个variables中,这有效地节省了我多次处理输出的麻烦,这对debugging有很大的帮助。
这是一个没有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';
$ STATUS || = 200;
$ TYPE || ='text / html';
if($ STATUS =〜m / ^ 30 [123] $ /){
$ HEADER。=“Content-Length:0 \ n”;
打印“$ HTTP_PROTOCOL $ STATUS \ n”;
打印$ HEADER;
打印“内容types:$ TYPE \ n”;
打印“位置:$ HTML \ n \ n”;
出口;
}
打印“$ HTTP_PROTOCOL $ STATUS \ n”if($ ISNPH);
打印$ HEADER;
打印“内容types:$ TYPE \ n”;
打印“Content-Length:”。 长度($ HTML)。 “\ n”if($ ISNPH);
打印“\ n”;
打印$ HTML;
出口;
}
它会被这样调用:
完成('200',$ HEADER,'text / html',$ HTML,1);
如果你在支持NPH之前testing你的脚本,只需要传递一个0作为最后一个参数。 在这个函数调用之前,根本不要打印给客户端,并将你的头文件build立成$ HEADER和HTML到$ HTML。
如果您正在进行redirect,请将要redirect到的URL传递到$ HTML参数中。 redirect场景中不需要实际的HTML输出。
为了进一步解决问题,如果你仍然看到它们,testing你的脚本输出缓冲打开和closures。
仍然有些情况下,这可能无法解决问题,我还没有find一个解决scheme,它应该提出来的Apache集团。 我只知道CGI编程,所以我没有能力研究Apache源代码或提交补丁,但希望有人把这个补丁。
〜周杰伦