Heidegger has asked for the wisdom of the Perl Monks concerning the following question:

I'm writing Perl CGI scripts, running Apache on Windows. I have set the Perl @INC path to the following (output from the "perl -V" command):
PERLLIB="C:/Apache/htdocs/mokslas/lib" @INC: C:/Apache/htdocs/mokslas/lib C:/Perl/lib C:/Perl/site/lib .
So, the Perl knows where my *.pm files are. Unfortunately, Apache doesn't know that (Apache error.log):
Can't locate Mokslas.pm in @INC (@INC contains: C:/Perl/lib C:/Perl/si +te/lib .) at c:\apache\htdocs\mokslas\index.cgi line 3.
So, the question is: how do I make Apache know my @INC variable under Windows? (I'm setting my @INC variable through the PERLLIB environment variable). I have restarted my computer - the Apache should "grab" @INC from Perl. Thanks for your help.

Replies are listed 'Best First'.
Re: Setting the @INC variable for Apache running on Windows
by bart (Canon) on Jan 23, 2003 at 10:49 UTC
    Apache only passes some environment variables to its CGI programs. You can control which are passed, in addition to the default ones, by using the PassEnv directive.

    You can also set environment variables for these programs, by using the SetEnv directive. Thus, these environment variables needn't even exist outside of Apache.

    Both are controled by the mod_env module. It is loaded by default, so you don't need to do anything to enable is — at least, if "ClearModuleList" is not commented out in the configuration file.

    You can set these directives in the main Apache configuration file, "httpd.conf", globally for the whole server; on a per directory basis by wrapping it in <Directory> tags; or per virtual host in a similar way. In addition, you can also set them in a ".htaccess" file, provided it is allowed by the "AllowOverride" directive in "httpd.conf", and as you can see from the mod_env docs, it's "AllowOverride FileInfo" (or "AllowOverride All") that's in charge.

    A practical example: I added this to my "httpd.conf" file:

    Alias /servertest "c:/server test" <Directory "c:/server test"> Options ExecCGI AllowOverride None AllowOverride FileInfo PassEnv PROMPT SetEnv PERL5LIB "C:/Apache/htdocs/mokslas/lib" Allow from all </Directory>
    I made sure the directory exists and contains a test CGI script "env.cgi", and a ".htaccess" file in which I put:
    SetEnv ENV "Hello, World!"
    Then when I run a CGI script, via the URL <http://localhost/servertest/env.cgi>, I get the following environment variables, among others:
    • ENV: Hello, World!
    • PERL5LIB: C:/Apache/htdocs/mokslas/lib
    • PROMPT: $p$g
    I hope this shows enough of the options.

    Note: Putting the directive in ".htaccess" allows you to change the value without restarting Apache. But for such a long-term environment variable like PERL5LIB, I'd rather put it in "httpd.conf".

Re: Setting the @INC variable for Apache running on Windows
by blokhead (Monsignor) on Jan 23, 2003 at 07:48 UTC
    If it's feasable with your code, adding a use lib 'c:/apache/htdocs/mokslas/lib'; line at the top of your program(s) should do the trick. Alternatively, changing the shebang line to include a -Ic:/apache/... argument is equivalent. Another solution would be to wrap the perl binary in a script (possibly a Perl script) that simply sets PERL5LIB and then executes the real perl binary.

    I know very little about Apache on Windows, but it may be doing some sort of environment sandboxing and trashing PERL5LIB. Just a wild guess, but Apache seems to have a good grip on the environment variables for spawned CGI processes.

    blokhead

Re: Setting the @INC variable for Apache running on Windows
by Coruscate (Sexton) on Jan 23, 2003 at 08:35 UTC

    So, the Perl knows where my *.pm files are. Unfortunately, Apache doesn't know that

    Actually, your statement there is not quite correct. It's not Apache that doesn't know where the module is, it is indeed Perl. Perl is the one who placed that error message in the Apache log, so for some reason Perl is confusing itself (or you have confused it). As the error message shows, Perl isn't seeing that c:/Apache/htdocs/mokslas/lib is part of @INC. Can I ask why you have PERLLIB="C:/Apache/htdocs/mokslas/lib" in the output of perl -V? (Read last paragraph for reason of strikeout)

    I'm quite curious as to why perl shows the directory as part of @INC within perl -V but why the added directory into @INC isn't being passed into the interpreter. The only way I can understand why this might happen is the following: do you have more than one installation of perl on the machine involved? If, for example, you have both perl 5.6.1 and perl 5.8.0 installed, and you modified the @INC for perl 5.6.1 and your script is loading perl 5.8.0, then perhaps perl versions keep seperate @INCs? The only scenerio that came instantly to mind...

    UPDATE, 5 seconds later: I believe the correct environment variable is PERL5LIB, not PERLLIB. Somebody correct me if I am wrong.

    UPDATE, several minutes later...: As This external page suggests, it seems that PERLLIB and PERL5LIB are both valid for this use. I'm still perplexed as to why perl is getting confused on your machine. But now I've half-thought of something else. Do you have Mokslas.pm in C:/Apache/htdocs/mokslas/lib or just in C:/Apache/htdocs/mokslas? I'm wondering if perhaps you just imitated the current @INC values by appending the /lib part on... however, that still does not explain the fact that the error logged does not mention the fact that the new directory is there... {still confused}

    Last, Final Update: Apparently it truly *IS* Apache that is at fault here. It seems (just learned from PodMaster via the CB) that Apache strips the environment variables on handing execution to Perl. It is for security purposes that this is done. pulls certain environment variables and doesn't even look at the rest of them. Thus Apache only import the environment variables that it is interested in. I really don't know much on the subject, discuss it with PodMaster if you wish to know more (he seems to understand it quite well). Therefore, use the 'use lib' functionality already suggested, or if possible, why not move your custom modules into C:/Perl/Site/Lib/Some/Module?

Re: Setting the @INC variable for Apache running on Windows
by crouchingpenguin (Priest) on Jan 23, 2003 at 15:56 UTC
    If you have mod_perl available you could try running the cgi's under Apache::Registry or ModPerl::Registry (depending on your mod_perl version), then use

    'use lib qw( dir1 dir2 etc);'

    in a startup file.

    That should setup @INC for you at the apache level.

    "Never be afraid to try something new. Remember, amateurs built the ark. Professionals built the Titanic."
Re: Setting the @INC variable for Apache running on Windows
by Heidegger (Hermit) on Jan 23, 2003 at 09:08 UTC
    Now I'm sure I'm running only this Perl version (5.6.1). Restarted Windows, but Apache still doesn't get the @INC variable. Also, I was setting the PERLIB variable. Now I set the PERL5LIB variable too. The "perl -V" looks good, but the Apache log looks bad. So, I think I'll stick to the use lib "...";directive.
Re: Setting the @INC variable for Apache running on Windows
by Heidegger (Hermit) on Jan 23, 2003 at 09:13 UTC
    Thank you Coruscate for the deep problem coverage. Now I know why Apache does that - security is the issue.