perl - hello - ¿Por qué tengo que generar explícitamente el encabezado HTTP para IIS pero no para Apache?
modulo cgi apache (3)
HTTP y CGI son cosas diferentes. El módulo Perl CGI llama a lo que hace un "encabezado HTTP", pero en realidad es solo un encabezado CGI para que el servidor lo arregle antes de volver al cliente. Se parecen mucho, razón por la cual la gente se confunde y por qué los documentos CGI.pm no ayudan llamándolos equivocadamente.
Apache arregla los encabezados CGI para convertirlos en encabezados HTTP, incluida la adición de la línea de estado HTTP y cualquier otra cosa que pueda necesitar.
Si su servidor web no está arreglando el encabezado para usted, probablemente esté esperando un "encabezado sin análisis" en el que asuma la responsabilidad de todo el encabezado. Para hacer eso en CGI.pm, debe agregar la opción -nph
a su llamada al encabezado, y debe crear el encabezado completo usted mismo, incluidos encabezados como Expires
y Last-Modified
. Consulte los documentos en Creación de un encabezado HTTP estándar . Puede activar NPH de tres maneras:
use CGI qw(-nph)
CGI::nph(1)
print header( -nph => 1, ...)
¿Estás usando una versión anterior de IIS? CGI.pm solía activar automáticamente la característica de NPH para IIS, pero ahora esa línea está comentada en la fuente en 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/;
Estoy intentando configurar Apache en lugar de IIS porque IIS se cuelga innecesariamente todo el tiempo, y sería bueno poder tener mi propia verificación de la fuente en lugar de que todos nosotros editemos una salida común.
En IIS debemos hacer algo como esto al comienzo de cada archivo:
use CGI;
my $input = new CGI();
print "HTTP/1.0 200 OK";
print $input->header();
mientras que con Apache debemos dejar fuera de la línea 200 OK. Lo siguiente funciona con ambos:
use CGI;
my $input = new CGI();
print $input->header(''text/html'',''200 OK'');
¿Alguien puede explicar por qué? Y tenía la impresión de que el módulo CGI debía resolver este tipo de detalles automáticamente ...
¡Gracias!
Actualización : Brian tiene razón, nph soluciona el problema de IIS, pero todavía está roto para Apache. No creo que valga la pena tener condicionales en todo el código, así que me quedaré con el último método, que funciona con y sin nph.
Todavía estoy experimentando este problema con ActivePerl 5.14 que se ejecuta en IIS 7 a través de ISAPI. Las preguntas más frecuentes de ActivePerl 5.10 afirman que el problema está solucionado (las preguntas más frecuentes 5.14 ni siquiera abordan el problema), pero no parece ser así y establecer la clave de registro que sugieren utilizar no tiene ningún efecto en este entorno.
Usar $ENV{PerlXS} eq ''PerlIS''
para detectar ISAPI y activar la tecla NPH según las preguntas frecuentes antes mencionadas parece funcionar. Corté mi CGI.pm para agregar las dos líneas finales debajo del antiguo controlador 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'';
Tuve un problema similar con Perl (¡era una cosa nueva de 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";