Category Archives: IIS

Porting Perl CGI Script From Linux Apache To Windows IIS

I am a linux guy. I mean, my laptop is windows based and all, but all the development is done on Linux. I prefer Java and Swing for desktop applications and Perl or Java for Web applications. I have a perl cgi script that I had to port it to IIS because a potential customer wanted it on Windows 2003 Server with IIS.

I have a laptop with Windows Vista Home Premium and so I wanted to try and figure out how to make the cgi script to work on IIS. After a lot of searching and researching, I figured out enabling IIS, installing ActivePerl, configuring to run the perl scripts and all. This article is not about how that can be done, but about what issue I ran into when porting the script.

First I thought I had to change the “#!/usr/bin/perl” to the appropriate perl interpreter path on Windows, but the way it works in IIS is that a specific url pattern can be mapped to a handler and program of that handler is configured. So, “*.pl” can be mapped to a specific program and windows will execute that program passing the script as input. This makes life easier, no need to maintain two separate versions of the program one for each platform.

However, the key issue I ran into is the error in loading the shipped modules. In Apache, a perl script is run with the current working directory set to the directory where the script is located. So, all the other modules of the program are resolved with respect to the current working directory and as a result there is no need for any special include path setting. But in IIS, this isn’t the case. The script is executed with the current working directory (BTW, pwd in linux and chdir in Windows) set to the virtual directory of the script. So, if the script is within a folder within the virtual directory, all the modules packaged with the script won’t be found.

So, I ended up doing the following to make it work with both Apache and IIS.

At the very beginning of the script, even before the modules are loaded, I have the following code.

BEGIN {
  $SCRIPT_PATH = $ENV{PATH_TRANSLATED}; # this env variable is available in IIS and not Apache
  if($SCRIPT_PATH) {
     $SCRIPT_PATH =~ s/[^\\\/]+$//;
     push @INC,$SCRIPT_PATH;
  }
  else {
     $SCRIPT_PATH = ".";
  } 
}

That’s it. This code will include the directory of the script into the include path so that the subsequent “use” and “require” statements are resolved appropriately.

One last note. If you have file opening logic in the script using a relative path, that should also be changed to resolve it w.r.t the $SCRIPT_PATH.

Advertisements

2 Comments

Filed under Apache, IIS, perl