
janus at errornet
Nov 27, 2008, 1:05 PM
Views: 789
Permalink
|
|
PATCH: factor out env quirks in C::E::FastCGI to _fix_env method and IIS env fix
|
|
Hi, while deploying a Catalyst application on Windows (thanks to Evan Carroll!) i noticed that IIS has borked environment variables that will prevent redirects and such from working because $c->req->base is completely wrong. This is caused by wrong PATH_INFO and SCRIPT_NAME which obviously needs a workaround. With some feedback from t0m and other developers i even managed to assemble a test and furthermore factored the quirks from C::E::FastCGI::run() out into C::E::FastCGI::_fix_env() so all the fixes are in one place and relatively easy to test and extend (jshirleys recent nginx patch comes to mind). I've tested this on Windows 2003 with the app configured at the web root and in virtual directories, all working fine. Please provide some feedback and let us know if it works for you so it can be eventually committed. Kind regards, Simon Index: t/optional_iis6-fastcgi-env.t =================================================================== --- t/optional_iis6-fastcgi-env.t (revision 0) +++ t/optional_iis6-fastcgi-env.t (revision 0) @@ -0,0 +1,62 @@ +#!perl + +use strict; +use warnings; + +use Test::More; + +eval "use FCGI"; +plan skip_all => 'FCGI required' if $@; + +plan tests => 2; + +require Catalyst::Engine::FastCGI; + +my %env = ( + 'SCRIPT_NAME' => '/koo/blurb', + 'PATH_INFO' => '/koo/blurb', + 'HTTP_ACCEPT' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', + 'REQUEST_METHOD' => 'GET', + 'SCRIPT_FILENAME' => 'C:\\Foo\\script\\blurb', + 'INSTANCE_META_PATH' => '/LM/W3SVC/793536', + 'SERVER_SOFTWARE' => 'Microsoft-IIS/6.0', + 'AUTH_PASSWORD' => '', + 'AUTH_TYPE' => '', + 'HTTP_USER_AGENT' => 'Mozilla/5.0 (Windows; U; Windows NT 5.2; de; rv:1.9.0.4) Gecko/2008102920 Firefox/3.0.4 (.NET CLR 3.5.30729)', + 'REMOTE_PORT' => '1281', + 'QUERY_STRING' => '', + 'URL' => '/koo/blurb', + 'HTTP_ACCEPT_LANGUAGE' => 'de-de,de;q=0.8,en-us;q=0.5,en;q=0.3', + 'FCGI_ROLE' => 'RESPONDER', + 'HTTP_KEEP_ALIVE' => '300', + 'CONTENT_TYPE' => '', + 'LOCAL_ADDR' => '127.0.0.1', + 'GATEWAY_INTERFACE' => 'CGI/1.1', + 'HTTPS' => 'off', + 'DOCUMENT_ROOT' => 'C:\\Foo\\script', + 'REMOTE_HOST' => '127.0.0.1', + 'PATH_TRANSLATED' => 'C:\\Foo\\script\\blurb', + 'APPL_PHYSICAL_PATH' => 'C:\\Foo\\script\\', + 'SERVER_NAME' => '127.0.0.1', + 'HTTP_ACCEPT_ENCODING' => 'gzip,deflate', + 'HTTP_CONNECTION' => 'keep-alive', + 'INSTANCE_ID' => '793536', + 'CONTENT_LENGTH' => '0', + 'AUTH_USER' => '', + 'APPL_MD_PATH' => '/LM/W3SVC/793536/Root/koo', + 'HTTP_ACCEPT_CHARSET' => 'ISO-8859-1,utf-8;q=0.7,*;q=0.7', + 'REMOTE_USER' => '', + 'SERVER_PORT_SECURE' => '0', + 'SERVER_PORT' => 83, + 'REMOTE_ADDR' => '127.0.0.1', + 'SERVER_PROTOCOL' => 'HTTP/1.1', + 'REQUEST_URI' => '/koo/blurb', + 'APP_POOL_ID' => 'DefaultAppPool', + 'HTTP_HOST' => '127.0.0.1:83' +); + +Catalyst::Engine::FastCGI->_fix_env(\%env); + +is($env{PATH_INFO}, '//blurb', 'check PATH_INFO'); +is($env{SCRIPT_NAME}, '/koo', 'check SCRIPT_NAME'); + Index: lib/Catalyst/Engine/FastCGI.pm =================================================================== --- lib/Catalyst/Engine/FastCGI.pm (revision 8660) +++ lib/Catalyst/Engine/FastCGI.pm (working copy) @@ -134,14 +134,9 @@ sub run { while ( $request->Accept >= 0 ) { $proc_manager && $proc_manager->pm_pre_dispatch(); + + $self->_fix_env( \%env ); - # If we're running under Lighttpd, swap PATH_INFO and SCRIPT_NAME - # http://lists.rawmode.org/pipermail/catalyst/2006-June/008361.html - # Thanks to Mark Blythe for this fix - if ( $env{SERVER_SOFTWARE} && $env{SERVER_SOFTWARE} =~ /lighttpd/ ) { - $env{PATH_INFO} ||= delete $env{SCRIPT_NAME}; - } - $class->handle_request( env => \%env ); $proc_manager && $proc_manager->pm_post_dispatch(); @@ -205,6 +200,43 @@ sub daemon_detach { open STDOUT, ">&STDIN" or die $!; open STDERR, ">&STDIN" or die $!; POSIX::setsid(); +} + +=head2 $self->_fix_env( $env ) + +Adjusts the environment variables when necessary. + +=cut + +sub _fix_env +{ + my $self = shift; + my $env = shift; + + return unless ( $env->{SERVER_SOFTWARE} ); + + # If we're running under Lighttpd, swap PATH_INFO and SCRIPT_NAME + # http://lists.rawmode.org/pipermail/catalyst/2006-June/008361.html + # Thanks to Mark Blythe for this fix + if ( $env->{SERVER_SOFTWARE} =~ /lighttpd/ ) { + $env->{PATH_INFO} ||= delete $env->{SCRIPT_NAME}; + } + # Fix the environment variables PATH_INFO and SCRIPT_NAME when running under IIS 6.0 + elsif ( $env->{SERVER_SOFTWARE} =~ /IIS\/6.0/ ) { + my @script_name = split(m!/!, $env->{PATH_INFO}); + my @path_translated = split(m!/|\\\\?!, $env->{PATH_TRANSLATED}); + my @path_info; + + while ($script_name[$#script_name] eq $path_translated[$#path_translated]) { + pop(@path_translated); + unshift(@path_info, pop(@script_name)); + } + + unshift(@path_info, '', ''); + + $env->{PATH_INFO} = join('/', @path_info); + $env->{SCRIPT_NAME} = join('/', @script_name); + } } 1; _______________________________________________ Catalyst-dev mailing list Catalyst-dev[at]lists.scsys.co.uk http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst-dev
|