home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam  


Practical mod_perlPractical mod_perlSearch this book

24.5. Configuring mod_perl 2.0

Similar to mod_perl 1.0, in order to use mod_perl 2.0 a few configuration settings should be added to httpd.conf. They are quite similar to the 1.0 settings, but some directives were renamed and new directives were added.

24.5.3. Startup File

Next, a startup file with Perl code usually is loaded:

PerlRequire "/home/httpd/httpd-2.0/perl/startup.pl"

It's used to adjust Perl module search paths in @INC, preload commonly used modules, precompile constants, etc. A typical startup.pl file for mod_perl 2.0 is shown in Example 24-1.

Example 24-1. startup.pl

use Apache2 ( );

use lib qw(/home/httpd/perl);

# enable if the mod_perl 1.0 compatibility is needed
# use Apache::compat ( );

# preload all mp2 modules
# use ModPerl::MethodLookup;
# ModPerl::MethodLookup::preload_all_modules( );

use ModPerl::Util ( ); #for CORE::GLOBAL::exit

use Apache::RequestRec ( );
use Apache::RequestIO ( );
use Apache::RequestUtil ( );

use Apache::Server ( );
use Apache::ServerUtil ( );
use Apache::Connection ( );
use Apache::Log ( );

use APR::Table ( );

use ModPerl::Registry ( );

use Apache::Const -compile => ':common';
use APR::Const -compile => ':common';

1;

In this file the Apache2 module is loaded, so the 2.0 modules will be found. Afterwards, @INC is adjusted to include nonstandard directories with Perl modules:

use lib qw(/home/httpd/perl);

If you need to use the backward-compatibility layer, to get 1.0 modules that haven't yet been ported to work with mod_perl 2.0, load Apache::compat:

use Apache::compat ( );

Next, preload the commonly used mod_perl 2.0 modules and precompile the common constants. You can preload all mod_perl 2.0 modules by uncommenting the following two lines:

use ModPerl::MethodLookup;
ModPerl::MethodLookup::preload_all_modules( );

Finally, the startup.pl file must be terminated with 1;.

24.5.5. mod_perl 2.0 Core Handlers

mod_perl 2.0 provides two types of core handlers: modperl and perl-script.

24.5.5.3. A simple response handler example

Let's demonstrate the differences between the modperl and perl-script core handlers. Example 24-2 represents a simple mod_perl response handler that prints out the environment variables as seen by it.

Example 24-2. Apache/PrintEnv1.pm

package Apache::PrintEnv1;

use strict;
use warnings;

use Apache::RequestRec ( ); # for $r->content_type

use Apache::Const -compile => 'OK';

sub handler {
    my $r = shift;

    $r->content_type('text/plain');
    for (sort keys %ENV){
        print "$_ => $ENV{$_}\n";
    }

    return Apache::OK;
}

1;

This is the required configuration for the perl-script handler:

PerlModule Apache::PrintEnv1
<Location /print_env1>
    SetHandler perl-script
    PerlResponseHandler Apache::PrintEnv1
</Location>

Now issue a request to http://localhost/print_env1, and you should see all the environment variables printed out.

The same response handler, adjusted to work with the modperl core handler, is shown in Example 24-3.

Example 24-3. Apache/PrintEnv2.pm

package Apache::PrintEnv2;

use strict;
use warnings;

use Apache::RequestRec ( ); # for $r->content_type
use Apache::RequestIO ( );  # for $r->print

use Apache::Const -compile => 'OK';

sub handler {
    my $r = shift;

    $r->content_type('text/plain');
    $r->subprocess_env;
    for (sort keys %ENV){
        $r->print("$_ => $ENV{$_}\n");
    }

    return Apache::OK;
}

1;

The configuration now will look like this:

PerlModule Apache::PrintEnv2
<Location /print_env2>
    SetHandler modperl
    PerlResponseHandler Apache::PrintEnv2
</Location>

Apache::PrintEnv2 cannot use print( ), so it uses $r->print( ) to generate a response. Under the modperl core handler, %ENV is not populated by default; therefore, subprocess_env( ) is called in a void context. Alternatively, we could configure this section to do:

PerlOptions +SetupEnv

If you issue a request to http://localhost/print_env2, you should see all the environment variables printed out as with http://localhost/print_env1.

24.5.6. PerlOptions Directive

The PerlOptions directive provides fine-grained configuration for what were compile-time-only options in the first mod_perl generation. It also provides control over what class of PerlInterpreter is used for a <VirtualHost> or location configured with <Location>, <Directory>, etc.

Options are enabled by prepending + and disabled with -. The options are discussed in the following sections.

24.5.6.9. SetupEnv

Set up environment variables for each request, à la mod_cgi.

When this option is enabled, mod_perl fiddles with the environment to make it appear as if the code is called under the mod_cgi handler. For example, the $ENV{QUERY_STRING} environment variable is initialized with the contents of Apache::args( ), and the value returned by Apache::server_hostname( ) is put into $ENV{SERVER_NAME}.

Those who have moved to the mod_perl API no longer need this extra %ENV population and can gain by disabling it, since %ENV population is expensive. Code using the CGI.pm module requires PerlOptions +SetupEnv because that module relies on a properly populated CGI environment table.

This option is enabled by default for sections configured as:

<Location ...>
    SetHandler perl-script
    ...
</Location>

Since this option adds an overhead to each request, if you don't need this functionality you can turn it off for a certain section:

<Location ...>
    SetHandler perl-script
    PerlOptions -SetupEnv
    ...
</Location>

or globally affect the whole server:

PerlOptions -SetupEnv
<Location ...>
    ...
</Location>

It can still be enabled for sections that need this functionality.

When this option is disabled you can still read environment variables set by you. For example, when you use the following configuration:

PerlOptions -SetupEnv
<Location /perl>
  PerlSetEnv TEST hi
  SetHandler perl-script
  PerlHandler ModPerl::Registry
  Options +ExecCGI
</Location>

and you issue a request for setupenvoff.pl from Example 24-4.

Example 24-4. setupenvoff.pl

use Data::Dumper;
my $r = Apache->request( );
$r->send_http_header('text/plain');
print Dumper(\%ENV);

you should see something like this:

$VAR1 = {
          'GATEWAY_INTERFACE' => 'CGI-Perl/1.1',
          'MOD_PERL' => 'mod_perl/2.0.1',
          'PATH' => '/bin:/usr/bin',
          'TEST' => 'hi'
        };

Notice that we got the value of the environment variable TEST.

24.5.7. Thread-Mode-Specific Directives

The following directives are enabled only in a threaded MPM mod_perl:

24.5.7.1. PerlInterpStart

The number of interpreters to clone at startup time.

24.5.7.2. PerlInterpMax

If all running interpreters are in use, mod_perl will clone new interpreters to handle the request, up until this number of interpreters is reached. When PerlInterpMax is reached, mod_perl will block until an interpreter becomes available.

24.5.7.3. PerlInterpMinSpare

The minimum number of available interpreters this parameter will clone before a request comes in.

24.5.7.4. PerlInterpMaxSpare

mod_perl will throttle down the number of interpreters to this number as those in use become available.

24.5.7.5. PerlInterpMaxRequests

The maximum number of requests an interpreter should serve. The interpreter is destroyed and replaced with a fresh clone when this number is reached.

24.5.7.6. PerlInterpScope

As mentioned, when a request in a threaded MPM is handled by mod_perl, an interpreter must be pulled from the interpreter pool. The interpreter is then available only to the thread that selected it, until it is released back into the interpreter pool. By default, an interpreter will be held for the lifetime of the request, equivalent to this configuration:

PerlInterpScope request

For example, if a PerlAccessHandler is configured, an interpreter will be selected before it is run and not released until after the logging phase.

Interpreters will be shared across subrequests by default; however, it is possible to configure the interpreter scope to be per subrequest on a per-directory basis:

PerlInterpScope subrequest

With this configuration, an autoindex-generated page, for example, would select an interpreter for each item in the listing that is configured with a Perl*Handler.

It is also possible to configure the scope to be per handler:

PerlInterpScope handler

With this configuration, an interpreter will be selected before PerlAccessHandlers are run and put back immediately afterwards, before Apache moves on to the authentication phase. If a PerlFixupHandler is configured further down the chain, another interpreter will be selected and again put back afterwards, before PerlResponseHandler is run.

For protocol handlers, the interpreter is held for the lifetime of the connection. However, a C protocol module (e.g., mod_ftp) might hook into mod_perl and provide a request_rec record. In this case, the default scope is that of the request (the download of one file). Should a mod_perl handler want to maintain state for the lifetime of an FTP connection, it is possible to do so on a per-<VirtualHost> basis:

PerlInterpScope connection

24.5.8. Retrieving Server Startup Options

The httpd server startup options can be retrieved using Apache::exists_config_define( ). For example, to check if the server was started in single-process mode:

panic% httpd -DONE_PROCESS

use the following code:

if (Apache::exists_config_define("ONE_PROCESS")) {
    print "Running in a single process mode";
}


Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.