| =head1 NAME |
| |
| Mod_perl_faq - frequently asked questions about mod_perl ($Date$) |
| |
| =head1 DESCRIPTION |
| |
| Mod_perl allows an Apache Web Server to directly execute perl code. This |
| document is designed to answer questions that arise when designing new |
| applications, and converting existing applications, to run in the mod_perl |
| environment. |
| |
| =head1 QUESTIONS & ANSWERS |
| |
| =head2 What is mod_perl? |
| |
| The Apache/Perl integration project brings together the full power of the |
| Perl programming language and the Apache HTTP server. This is achieved by |
| linking the Perl runtime library into the server and providing an |
| object-oriented Perl interface to the server's C language API. |
| |
| Mod_perl is a bundle of software. One part of the bundle is designed to |
| be compiled and linked together with Apache and Perl. The remainder is |
| perl code that provides the object-oriented interface to the "perl-enabled" |
| web server. |
| |
| The primary advantages of mod_perl are power and speed. You have full |
| access to the inner-workings of the web server and can intervene at any |
| stage of request-processing. This allows for customized processing of (to |
| name just a few of the phases) URI->filename translation, authentication, |
| response generation and logging. There is very little run-time overhead. |
| In particular, it is not necessary to start a separate process, as is |
| often done with web-server extensions. The most wide-spread such |
| extension mechanism, the Common Gateway Interface (CGI), can be replaced |
| entirely with perl-code that handles the response generation phase of |
| request processing. Mod_perl includes a general purpose module for this |
| purpose (Apache::Registry) that can transparently run existing perl CGI |
| scripts. |
| |
| =head2 Where can I get mod_perl? |
| |
| Mod_perl can be found at |
| http://www.perl.com/CPAN/modules/by-module/Apache/ |
| |
| =head2 What else do I need? |
| |
| =over 4 |
| |
| =item Perl |
| |
| http://www.perl.com/CPAN/src/latest.tar.gz |
| |
| Win32 users note: mod_perl compiles cleanly and works with ActivePerl |
| (build 626, June 2001). In |
| http://www.mail-archive.com/modperl@apache.org/msg11513.html Randy |
| Kobes wrote: |
| |
| A ppd for mod_perl, suitable for use with ActivePerls |
| based on Perl-5.6.0, is now available. Installation is as ppm |
| install |
| |
| http://theoryx5.uwinnipeg.ca/ppmpackages/mod_perl.ppd |
| |
| or in ftp://theoryx5.uwinnipeg.ca/pub/ppmpackages/. |
| A post-install script will subsequently be run which |
| will download and install the required ApacheModulePerl.dll; |
| this should be placed in your Apache modules directory. |
| If for some reason the script fails, this dll can be |
| obtained from http://theoryx5.uwinnipeg.ca/ppmpackages/. |
| Also available in this directory is a sample Apache |
| httpd.conf suitable to test mod_perl on Win32. |
| |
| =item Apache |
| |
| http://www.apache.org/dist/ |
| |
| =back |
| |
| =head2 How do I install it? |
| |
| Configuring and installing apache with mod_perl is a complex process, |
| so it is really not a good idea to attempt to do it manually. If you |
| are used to configuring third-party modules into Apache using the |
| apache configuration process, please realize that running mod_perl's |
| Makefile.PL with the right parameters does this for you. |
| |
| Read the INSTALL* files in the top-level mod_perl distribution |
| directory and then choose one of the INSTALL.simple* recipes that is |
| close to your requirements, as a starting point. When you succeed in |
| compiling and linking an httpd, a quick way to check that everything |
| is configured according to plan is to run it with the C<-l> (list |
| compiled-in modules) and C<-V> (show paths) flags. |
| |
| =head2 What documentation should I read? |
| |
| The mod_perl documentation in mod_perl.pod. After you have installed |
| mod_perl you can read it with the command: C<perldoc mod_perl>. |
| |
| The complete list of available documentation can be found at the end |
| of mod_perl's README file. |
| |
| If you are using mod_perl to extend the server functionality, you will |
| need to read C<perldoc Apache> and the Apache API notes, which can be |
| found in apache_x.x.x/htdocs/manual/misc/API.html. |
| |
| Existing (perl-) CGI scripts should run as-is under mod_perl. There are a |
| number of reasons why they may need to be adjusted, and these are |
| discussed later in this FAQ. If you are developing a new CGI script it is |
| probably best to use CGI.pm. It is part of the standard perl distribution |
| and its documentation can be read with the command: C<perldoc CGI>. |
| |
| =head2 How do I run CGI scripts under mod_perl? |
| |
| Refer to L<mod_perl_cgi> for tips on writing and converting CGI |
| scripts for mod_perl. |
| |
| =head2 How do I access the Apache API from mod_perl? |
| |
| Interfacing with Apache is discussed in L<mod_perl_api>. |
| |
| =head2 How secure are mod_perl scripts? |
| |
| Because mod_perl runs within an httpd child process, it runs with the |
| user-id and group-id specified in the httpd.conf file. This user/group |
| should have the lowest possible privileges. It should only have access |
| to world readable files. Even so, careless scripts can give away |
| information. You would not want your /etc/passwd file to be readable over |
| the net, for instance. |
| |
| Different mod_perl scripts run successively using the same Perl |
| interpreter instance. So, in addition to classical CGI mischiefs, a |
| malicious mod_perl script can redefine any Perl object and change the |
| behavior of other mod_perl scripts. |
| |
| If you turn on tainting checks, perl can help you to avoid the pitfalls of |
| using data received from the net. Setting the C<-T> switch on the first line |
| of the script is not sufficient to enable tainting checks under mod_perl. |
| You have to include the directive C<PerlTaintCheck On> in the httpd.conf |
| file. |
| |
| =head2 What if my script needs higher privileges? |
| |
| You will have to start a new process that runs under a suitable user-id |
| (or group-id). If all requests handled by the script will need the higher |
| privileges, you might as well write it as a suid CGI script. Read the |
| documentation about suEXEC in the Apache documentation. |
| |
| Alternatively, pre-process the request with mod_perl and fork a suid |
| helper process to handle the privileged part of the task. |
| |
| =head2 Why is httpd using so much memory? |
| |
| Read the section on "Memory Consumption" in the mod_perl.pod. |
| |
| Make sure that your scripts are not leaking memory. Global variables |
| stay around indefinitely, lexical variables (declared with my()) are |
| destroyed when they go out of scope, provided there are no references |
| to them from outside of that scope. The Apache::Leak module can warn |
| about some types of memory leak. |
| |
| To get information about the modules that have been loaded and their |
| symbol-tables, use the Apache::Status module. It is enabled by adding |
| these lines to the httpd configuration file. |
| |
| <Location /perl-status> |
| SetHandler perl-script |
| PerlHandler Apache::Status |
| </Location> |
| |
| Then look at the URL http://www.your.host/perl-status |
| |
| Joel Wagner reports that calling an undefined subroutine in a module |
| can cause a tight loop that consumes all memory. Here is a way to |
| catch such errors. Define an autoload subroutine |
| |
| sub UNIVERSAL::AUTOLOAD { |
| my $class = shift; |
| warn "$class can't `$UNIVERSAL::AUTOLOAD'!\n"; |
| } |
| |
| It will produce a nice error in error_log, giving the line number of |
| the call and the name of the undefined subroutine. |
| |
| =head2 Do I have to restart the server when I change my Perl code? |
| |
| Apache::Registry checks the timestamp of scripts that it has loaded |
| and reloads them if they change. Other handlers and library modules |
| are not automatically reloaded by mod_perl, but you can use the |
| Apache::StatINC module to do this for you. |
| |
| =head2 So how do I use mod_perl in conjunction with ErrorDocument? |
| |
| Andreas Koenig writes: |
| |
| =over 4 |
| |
| =item * |
| |
| Set up your testing engine: |
| |
| LWP comes with debugging capabilities that are sometimes better than |
| your browser, sometimes your browser is the better testing |
| device. Make sure you can call lwp-request from the command line and |
| have your browser ready before you start. I find the C<-x> switch |
| (extended debugging) and the C<-d> switch (do not display content) most |
| useful. |
| |
| =item * |
| |
| Test your server with |
| |
| lwp-request -xd http://your.server/test/file.not_there |
| |
| Carefully examine if the status is 404 and if the headers look good. |
| |
| If you try 'lwp-request -es', the HTML output will not be the one you |
| are sending, instead lwp-request will send its own cooked HTML text |
| (as of version libwww-perl-5.09). Check the real text either with the |
| C<-x> switch or with telnet or your browser. |
| |
| =item * |
| |
| Set up your Errordocument configuration in the testing area. I have |
| this in my .htaccess file: |
| |
| ErrorDocument 404 /perl/errors/err404-01 |
| |
| The /perl/ directory is configured to |
| |
| <Location /perl> |
| SetHandler perl-script |
| PerlHandler Apache::Registry::handler |
| Options ExecCGI |
| </Location> |
| |
| I have no PerlSendHeader and no PerlNewSendHeader directive in any |
| configuration file. |
| |
| =item * |
| |
| Repeat step 2 (Test your server) |
| |
| =item * |
| |
| Write your error handler in mod_perl. You have to be prepared that you |
| have to tell both apache *and* the browser the right thing. Basically |
| you have to tell the browser what the error is, but you have to |
| pretend to apache that everything was OK. If you tell apache the error |
| condition, it will handle the situation on its own and add some |
| unwanted stuff to the output that goes to the browser. |
| |
| The following works fine for me: |
| |
| my $r = Apache->request; |
| $r->content_type('text/html; charset=ISO-8859-1'); |
| $r->send_http_header; |
| $r->status(200); |
| ...send other HTML stuff... |
| |
| At the time of the send_http_header we have an error condition of type |
| 404--this is what gets sent to the browser. After that I set status to |
| 200 to silence the apache engine. |
| |
| I was not successful in trying to do the same with CGI.pm, but I |
| didn't try very hard. |
| |
| =item * |
| |
| Repeat step 2 (Test your server) |
| |
| =item * |
| |
| The above is tested with mod_perl/0.98 and 0.99 |
| |
| =item * |
| |
| Open questions I could not find documentation for (except RTFS): what |
| exactly is PerlSendHeaders and PerlNewSendHeaders. What is the default |
| setting for those? How do these cooperate with CGI.pm, Apache.pm, |
| Apache::Registry? |
| |
| =back |
| |
| =head2 How can I reference private library modules? |
| |
| If you put your modules into one of the directories on perl's search |
| path (the @INC array), they will be found automatically. |
| Traditionally, site-specific modules go in /usr/lib/perl5/site_perl/. |
| Newer versions of mod_perl add the directory $ServerRoot/lib/perl to |
| @INC on startup so that is a good place for modules that are only used |
| by mod_perl scripts. |
| |
| If you need to load files from other non-standard locations, you can |
| add directories to the @INC array with a 'use lib' statement in a |
| startup script. See L<mod_perl_tuning> for an example. |
| |
| =head2 How can I pass arguments to a SSI script? |
| |
| Following the documentation, I have put the following in the html |
| file: |
| |
| <!--#perl sub="Apache::Include" arg="/perl/ssi.pl" --> |
| |
| I want to send an argument to the ssi.pl script. How? |
| |
| It won't work with Apache::Include. Instead of a script, define a |
| subroutine that's pulled in with PerlRequire or PerlModule, like so: |
| |
| sub My::ssi { |
| my($r, $one, $two, $three) = @_; |
| ... |
| } |
| |
| In the html file: |
| |
| <!--#perl sub="My::ssi" arg="one" arg="two" arg="three" --> |
| |
| =head2 Why is image-file loading so slow when testing with httpd C<-X> ? |
| |
| If you use Netscape while your server is running in single-process |
| mode, the "KeepAlive" feature gets in the way. Netscape tries to open |
| multiple connections and keep them open. Because there is only one |
| server process listening, each connection has to time-out before the |
| next succeeds. Turn off KeepAlive in httpd.conf to avoid this effect. |
| |
| =head2 What can cause a subroutine or variable to be sporadically undefined? |
| |
| If you sometimes see error messages like this: |
| |
| [Thu Sep 11 11:03:06 1997] Undefined subroutine |
| &Apache::ROOT::perl::script1::sub_foo called at |
| /some/path/perl/script2 line 42. |
| |
| despite the fact that script2 normally works just fine, it looks like |
| you have a namespace problem in a library file. If sub_foo is located |
| in a file that is pulled in by 'require' and both script1 and script2 |
| require it, you need to be sure that the file containing sub_foo sets |
| a package name. Otherwise, sub_foo gets defined in the namespace that |
| is active the first time it is required, and the next require is a |
| no-op because that file is already in %INC. The same problem can |
| happen with global variables. |
| |
| The solution is simple, set up your require'd file something along |
| these lines: |
| |
| package SomeName; |
| |
| sub sub_foo {...} |
| |
| Now, have scripts call SomeName::sub_foo() instead of sub_foo(). |
| |
| =head2 Is there a bug that causes httpd processes to crash? |
| |
| You may see httpd child processes crashing with segmentation fault |
| when you restart the server with a HUP or USR1 signal. This is not a |
| bug in mod_perl. If you have 'PerlFreshRestart On' in the |
| configuration, the main httpd daemon reloads all the perl modules that |
| it has preloaded when it gets a HUP or USR1 signal. Unfortunately, |
| not all perl modules are robust enough to survive this, for them, |
| unusual situation. |
| |
| =head2 What could be causing sporadic errors "in cleanup"? |
| |
| Some people have seen error messages such as this: |
| |
| [Fri Sep 26 10:50:08 1997] (in cleanup) no dbproc key in hash |
| at /usr/lib/perl5/site_perl/Apache/Registry.pm line 119. |
| |
| Doug writes: |
| |
| "I have yet to figure out why, but there have been a few arbitrary |
| cases where Perl (in mod_perl) _insists_ on finding and/or calling a |
| DESTROY method for an object. Defining an empty sub DESTROY has been |
| the bandaid for these few cases." |
| |
| If the specific error message gives you a hint about which object is |
| causing difficulty, put the C<sub DESTROY { }> in the module that |
| defines that object class. |
| |
| =head2 How can I test that my script is running under mod_perl? |
| |
| There are 2 environment variables you can test. |
| |
| exists $ENV{"MOD_PERL"} # if running under mod_perl |
| |
| $ENV{"GATEWAY_INTERFACE"} eq "CGI-Perl/1.1" |
| |
| The MOD_PERL variable gets set immediately when the perl interpreter |
| starts up, whereas GATEWAY_INTERFACE may not be set yet when BEGIN |
| blocks are being processed. |
| |
| =head2 Why don't "format" and "write" work under mod_perl? |
| |
| The Perl tie'd filehandle interface is not complete, format/write is |
| one of the missing pieces. If you configure Perl with sfio, write() |
| should work just fine. |
| |
| =head2 Where can I get help that I did not find in here? |
| |
| There is a mailing-list dedicated to mod_perl. It is archived at |
| http://outside.organic.com/mail-archives/modperl/ and at |
| http://forum.swarthmore.edu/epigone/modperl (which has a search |
| engine) and also at |
| http://www.progressive-comp.com/Lists/?l=apache-modperl&r=1#apache-modperl |
| (threaded and indexed). |
| |
| You can subscribe to the list by sending a mail to |
| C<modperl-subscribe@perl.apache.org> and responding to the confirmation |
| message that you will receive. To unsubscribe, send mail to |
| C<modperl-unsubscribe@perl.apache.org> B<from the address you are |
| subscribed at> and reply to the confirmation message. Look at the |
| full headers of mails that you receive from the list to see the |
| address that they were sent to. The address is embedded in the |
| C<Return-Path> header (you will probably have to activate a "show full |
| headers" function in your mail reader to see it). To find the |
| address, delete C<modperl-return-nnnn-> from the front of the return path |
| and C<@perl.apache.org> from the back, then replace the C<=> with C<@>. |
| |
| Remember: the mailing list is for questions about and discussion of |
| mod_perl. Quetions about perl programming in general should be asked |
| in the newsgroup comp.lang.perl.misc, after consulting the fine perl |
| faqs. There is a whole set of newsgroups dedicated to web authoring, |
| web servers etc.: comp.infosystems.www.* |
| |
| The mod_perl homepage http://perl.apache.org/ has links to other |
| mod_perl resources. |
| |
| The pod source of this FAQ is available at |
| http://www.ping.de/~fdc/mod_perl/mod_perl_faq.tar.gz |
| |
| =head2 Where do I send suggestions and corrections concerning this FAQ? |
| |
| mailto:fdc@cliwe.ping.de |