简体   繁体   English

为什么我需要显式输出IIS的HTTP头而不是Apache?

[英]Why do I need to explicitly output the HTTP header for IIS but not Apache?

I am trying to set up apache instead of IIS because IIS needlessly crashes all the time, and it would be nice to be able to have my own checkout of the source instead of all of us editing a common checkout. 我正在尝试设置apache而不是IIS,因为IIS一直在不必要地崩溃 ,能够自己检查源代码而不是我们所有人编辑一个常见的签出都会很好。

In IIS we must do something like this at the beginning of each file: 在IIS中,我们必须在每个文件的开头执行类似的操作:

use CGI;
my $input = new CGI();
print "HTTP/1.0 200 OK";
print $input->header();

whereas with apache we must leave off the 200 OK line. 而对于apache,我们必须离开200 OK线。 The following works with both: 以下两者兼容:

use CGI;
my $input = new CGI();
print $input->header('text/html','200 OK');

Can anyone explain why? 有谁能解释为什么? And I was under the impression that the CGI module was supposed to figure out these kind of details automatically... 而且我的印象是CGI模块应该自动找出这些细节......

Thanks! 谢谢!

Update : brian is right, nph fixes the problem for IIS, but it is still broken for Apache. 更新 :brian是对的,nph解决了IIS的问题,但它仍然在Apache中被打破。 I don't think it's worth it to have conditionals all over the code so I will just stick with the last method, which works with and without nph. 我不认为在整个代码中都有条件,所以我会坚持使用最后一个方法,它可以使用和不使用nph。

HTTP and CGI are different things. HTTP和CGI是不同的东西。 The Perl CGI module calls what it does an "HTTP header", but it's really just a CGI header for the server to fix up before it goes back to the client. Perl CGI模块调用它所做的“HTTP头”,但它实际上只是服务器在返回客户端之前修复的CGI头。 They look a lot alike which is why people get confused and why the CGI.pm docs don't help by calling them the wrong thing. 它们看起来很相似,这就是为什么人们会感到困惑,以及为什么CGI.pm文档无法通过将它们称为错误的东西来帮助它们。

Apache fixes up the CGI headers to make them into HTTP headers, including adding the HTTP status line and anything else it might need. Apache修复了CGI标头,使其成为HTTP标头,包括添加HTTP状态行以及可能需要的任何其他内容。

If you webserver isn't fixing up the header for you, it's probably expecting a "no-parsed header" where you take responsibility for the entire header. 如果您的网络服务器没有为您修复标头,那么可能需要一个“未解析的标头”,您负责整个标头。 To do that in CGI.pm, you have to add the -nph option to your call to header, and you have to make the complete header yourself, including headers such as Expires and Last-Modified . 要在CGI.pm中执行此操作,您必须将-nph选项添加到对标头的调用中,并且您必须自己创建完整标头,包括ExpiresLast-Modified等标头。 See the docs under Creating a Standard HTTP Header . 请参阅创建标准HTTP标头下的文档。 You can turn on NPH in three ways: 您可以通过三种方式打开NPH:

use CGI qw(-nph)

CGI::nph(1)

print header( -nph => 1, ...)

Are you using an older version of IIS? 您使用的是旧版本的IIS吗? CGI.pm used to turn on the NPH feature for you automatically for IIS, but now that line is commented out in the source in CGI.pm: CGI.pm用于为IIS自动打开NPH功能,但现在该行已在CGI.pm的源代码中注释掉:

# This no longer seems to be necessary
# Turn on NPH scripts by default when running under IIS server!
# $NPH++ if defined($ENV{'SERVER_SOFTWARE'}) && $ENV{'SERVER_SOFTWARE'}=~/IIS/;

I'm still experiencing this problem with ActivePerl 5.14 running under IIS 7 via ISAPI. 我仍然遇到通过ISAPI在IIS 7下运行的ActivePerl 5.14的这个问题。 The ActivePerl 5.10 FAQ claims the problem is fixed (the 5.14 FAQ doesn't even address the issue), but it doesn't appear to be and setting the registry key they suggest using has no effect in this environment. ActivePerl 5.10 FAQ声称问题已得到解决(5.14常见问题解答甚至没有解决问题),但似乎并未设置他们建议使用的注册表项在此环境中无效。

Using $ENV{PerlXS} eq 'PerlIS' to detect ISAPI and turn on the NPH key per the aforementioned FAQ seems to work. 使用$ENV{PerlXS} eq 'PerlIS'来检测ISAPI并按照上述常见问题解答打开NPH密钥似乎可行。 I hacked my CGI.pm to add the final two lines below under the old IIS handler: 我攻击了我的CGI.pm,在旧的IIS处理程序下添加了下面的最后两行:

# This no longer seems to be necessary
# Turn on NPH scripts by default when running under IIS server!
# $NPH++ if defined($ENV{'SERVER_SOFTWARE'}) && $ENV{'SERVER_SOFTWARE'}=~/IIS/;
# Turn on NPH scripts by default when running under IIS server via ISAPI!
$NPH++ if defined($ENV{'SERVER_SOFTWARE'}) && $ENV{PERLXS} eq 'PerlIS';

I had similar problem with perl (it was a DOS/Unix/Mac newline thing !) 我和perl有类似的问题(这是一个DOS / Unix / Mac换行的东西!)

binmode(STDOUT);
my $CRLF = "\r\n"; # "\015\012"; # ^M: \x0D  ^L: \x0A
print "HTTP/1.0 200 OK",$CRLF if ($0 =~ m/nph-/o);
print "Content-Type: text/plain".$CRLF;
print $CRLF; print "OK !\n";

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM