[Catalyst-dev] PATCH: factor out env quirks in C::E::FastCGI to _fix_env method and IIS env fix

Simon Bertrang janus at errornet.de
Thu Nov 27 21:05:31 GMT 2008


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;



More information about the Catalyst-dev mailing list