Perl on IIS 4

For a while, I've been using Microsoft's Internet Information Server 3 at work, with Perl5 providing all the application functionality. Recently, I moved to IIS4, and everything fell apart. There was a lot of work involved in getting it going, so I've recorded the issues here for convenience.

Problems

  1. IIS4 won't invoke Perl on my scripts.
  2. Perl can't run external commands.
  3. My script isn't producing any output.
  4. The registry settings don't work anymore.
  5. There aren't any logging options.
  6. Perl can't call other Perl scripts.
  7. Perl can't send mail with Blat.
  8. What are Microsoft playing at?
  9. Acknowledgements

Solutions

IIS4 won't invoke Perl on my scripts.

Here are the headers I use under IIS4:
if ($ENV{'PERLXS'} eq 'PerlIS')
{
print $ENV{'SERVER_PROTOCOL'}, " 200 OK\n";
if ($ENV{'SERVER_PROTOCOL'} ne "HTTP/0.9")

 

You've created your ScriptMap registry settings, and they still don't work, right? Right. They don't. Under IIS4, you specify the interpreter association differently:

  1. In the Management Console, select your web site.
  2. Pull up Properties.
  3. Go to the Home Directory tab.
  4. Click on Configure...
  5. Select the App Mappings tab (or whatever it's called - the Left one)

This is where you say that .pl files are handled by C:\perl\bin\perl.exe. I've got the following command:

C:\perl\bin\perl.exe %s
Others have suggested
C:\perl\bin\perl.exe %s %s
If there's a reason for the second argument, I'd like to know what it is....

You should also mark this entry as being a Script interpreter. This means that your directory with all your .pl scripts in can be marked as having Script permission, not Execute permission; that way, it's safer.

It's a good idea to select the option to make IIS4 verify that the .pl file exists before invoking Perl (I'm kinda scared that it doesn't, anyway....).

A side note: you shouldn't have the perl.exe file visible in any directory which has Execute permission, as far as the web server is concerned; to do so means that anyone can run their own scripts on your machine.

Perl can't run external commands.

Chances are, you've got something like:
$var = `$cmd`; # backticks
or
open(PIPE, "$cmd|");	# popen
@data = ;

You may also have noticed that the scripts run fine from the command-line, but not when invoked by the web server.

The problem here is that IIS4 runs processes without a console, and for some reason, this prevents Perl from redirecting I/O. You'll probably find that the external commands are running, but Perl is failing to receive output from them.

Under IIS2 and IIS3, the fix for this was quite simple: add the registry setting:

and set it to one. Naturally, since we've learned about this one, Microsoft have changed it. Now:

  1. It's called CreateCGIWithNewConsole instead;
  2. It's not in the registry anymore.

In their wisdom, Microsoft moved all the registry settings for IIS4 out of the registry into the metabase. Uh-huh. So how'd you change it? Well:

  1. Make sure that you've got Windows Scripting Host installed as part of Option Pack 4. You can verify this, because it should install the file C:\winnt\system32\cscript.exe.
  2. Go to C:\winnt\system32\inetsrv\adminsamples.
  3. Run this:
    adsutil.vbs SET W3SVC/1/CreateCGIWithNewConsole 1
    
    It'll say that CScript isn't set up to handle this. That's ok.
  4. Click Ok.
  5. Click yes, you want to register.
  6. Run it again.
  7. Restart the web site.
You should now be able to run Perl scripts that do redirection, and they should work.

My script isn't producing any output.

There are several likely reasons for this:
  1. Check that you've got working IO redirection.
  2. Your script is barfing before the headers are getting flushed.
In the second case, first of all, turn off buffering on output with the following:
$| = 1;
(this works on the currently-selected output filehandle, so it'll only work if you haven't select()ed any other filehandle)

Personally, I also find that it's best to redirect stderr to a file in C:\temp, right at the start of the script. At least, then when errors occur, I've got a reasonable chance of seeing any error messages. If anyone knows how to see stderr output with IIS4 normally, I'd like to know about it.

The registry settings don't work anymore.

Well, no, they don't. ScriptMap settings are now done in property sheets, and CreateProcessWithNewConsole is now in the metabase.

There aren't any logging options.

A small oversight. Do the following:
  1. cd \winnt\system32\inetsrv
  2. regsvr32 logui.ocx

Perl can't call other Perl scripts.

It can - it just depends on how you call them. I've got Edit with Notepad as the default association for .pl and .pm files, so clicking on them in NT Explorer allows me to edit the files. The problem is, if you then have in your Perl scripts:
system("\path\to\script.pl")
You'll find that Notepad (or whatever) will start up in the background. Not nice. On NT, always invoke other Perl scripts using:
system("c:\perl\bin\perl.exe \path\to\script.pl")
(of course, if you can eval the script instead, that's better)

Perl can't send mail with Blat.

Chances are, there's nothing wrong here, except that you need to enable the I/O redirection in the metabase.

What are Microsoft playing at?

I have no idea. With this console redirection thing, there was a lot of stress before my application worked. It turns out that this is reported as a problem-with-solution for IIS2, which also worked for IIS3. So given that that's two major releases where loadsa people are trying to use Perl on their servers, quite why Microsoft decided to make it even harder to fix on IIS4, I can only speculate.

I also don't know why any of this console messing-about is necessary. I'd really like someone to explain to me both the no-console thing to begin with, and why Perl doesn't like it.

In passing, I'd like to mention that in moving a system from one machine with IIS3 to another with IIS4, sorting out the console issue took half a week's work. In constrast, making the necessary changes to the 50 files containing 10,000 lines of Perl took about half an hour.

Acknowledgements

Steve Kilbane.