Apache - Perl interface to the Apache server API
use Apache ();
This module provides a Perl interface the Apache API. It is here mainly for mod_perl, but may be used for other Apache modules that wish to embed a Perl interpreter. We suggest that you also consult the description of the Apache C API at http://www.apache.org/docs/.
The request object holds all the information that the server needs to
service a request. Apache Perl*Handlers will be given a reference to the
request object as parameter and may choose to update or use it in various
ways. Most of the methods described below obtain information from or
update the request object.
The perl version of the request object will be blessed into the Apache
package, it is really a request_rec*
in disguise.
The Apache->request method will return a reference to the request object.
Perl*Handlers can obtain a reference to the request object when it
is passed to them via @_
. However, scripts that run under
Apache::Registry, for example, need a way to access the request object.
Apache::Registry will make a request object available to these scripts
by passing an object reference to Apache->request($r)
.
If handlers use modules such as CGI::Apache that need to access
Apache->request
, they too should do this (e.g. Apache::Status).
undef
.
undef
if there is no previous request.
undef
if there is no next request.
!$r->main
, but will be more efficient.)
Get or set the allowed methods bitmask. This allowed bitmask should be set whenever a 405 (method not allowed) or 501 (method not implemented) answer is returned. The bit corresponding to the method number should be et.
unless ($r->method_number == M_GET) { $r->allowed($r->allowed | (1<<M_GET) | (1<<M_HEAD) | (1<<M_OPTIONS)); return HTTP_METHOD_NOT_ALLOWED; }
Apache provides a sub-request mechanism to lookup a uri or filename,
performing all access checks, etc., without actually running the
response phase of the given request. Notice, we have dropped the
sub_req_
prefix here. The request_rec*
returned by the lookup
methods is blessed into the Apache::SubRequest class. This way,
destroy_sub_request()
is called automatically during
Apache::SubRequest->DESTROY
when the object goes out of scope. The
Apache::SubRequest class inherits all the methods from the
Apache class.
my $subr = $r->lookup_uri($uri); my $filename = $subr->filename;
unless(-e $filename) { warn "can't stat $filename!\n"; }
my $subr = $r->lookup_file($filename);
if($subr->run != OK) { $subr->log_error("something went wrong!"); }
In this section we will take a look at various methods that can be used to retrieve the request parameters sent from the client. In the following examples, $r is a request object blessed into the Apache class, obtained by the first parameter passed to a handler subroutine or Apache->request
PerlTransHandler
.
Perl*Handler
is
being called.
The $r->args method will return the contents of the URI query string. When called in a scalar context, the entire string is returned. When called in a list context, a list of parsed key => value pairs are returned, i.e. it can be used like this:
$query = $r->args; %in = $r->args;
$r->args can also be used to set the query string. This can be useful when redirecting a POST request.
The $r->headers_in method will return a %hash of client request headers. This can be used to initialize a perl hash, or one could use the $r->header_in() method (described below) to retrieve a specific header value directly.
Will return a HASH reference blessed into the Apache::Table class when called in a scalar context with no "key" argument. This requires Apache::Table.
Return the value of a client header. Can be used like this:
$ct = $r->header_in("Content-type"); $r->header_in($key, $val); #set the value of header '$key'
application/x-www-form-urlencoded
.
When called in a scalar context, the entire string is
returned. When called in a list context, a list of parsed key =>
value pairs are returned. *NOTE*: you can only ask for this once,
as the entire body is read from the client.
This method is used to read data from the client,
looping until it gets all of $bytes_to_read
or a timeout happens.
An offset may be specified to place the read data at some other place than the beginning of the string.
In addition, this method sets a timeout before reading with
$r->soft_timeout
.
More information about the client can be obtained from the Apache::Connection object, as described below.
The $r->connection method will return a reference to the request
connection object (blessed into the Apache::Connection package).
This is really a conn_rec*
in disguise. The following methods can
be used on the connection object:
If the configuration directive HostNameLookups is set to on: then
the first time $r->get_remote_host
is called the server does a DNS
lookup to get the remote client's host name. The result is cached in
$c->remote_host
then returned. If the server was unable to resolve
the remote client's host name this will be set to "". Subsequent calls
to $r->get_remote_host
return this cached value.
If the configuration directive HostNameLookups is set to off: calls
to $r->get_remote_host
return a string that contains the dotted
decimal representation of the remote client's IP address. However this
string is not cached, and $c->remote_host
is undefined. So, it's
best to to call $r->get_remote_host
instead of directly accessing
this variable.
The dotted decimal representation of the remote client's IP address. This is set by the server when the connection record is created so is always defined.
You can also set this value by providing an argument to it. This is helpful if your server is behind a squid accelerator proxy which adds a X-Forwarded-For header.
A packed SOCKADDR_IN in the same format as returned by Socket/pack_sockaddr_in, containing the port and address on the remote host that the server is connected to. This is set by the server when the connection record is created so it is always defined.
Among other things, this can be used, together with $c->local_addr
, to
perform RFC1413 ident lookups on the remote client even when the
configuration directive IdentityCheck is turned off.
Can be used like:
use Net::Ident qw (lookupFromInAddr); ... my $remoteuser = lookupFromInAddr ($c->local_addr, $c->remote_addr, 2);
Note that the lookupFromInAddr interface does not currently exist in the Net::Ident module, but the author is planning on adding it soon.
If the configuration directive IdentityCheck is set to on: then the
first time $r->get_remote_logname
is called the server does an RFC
1413 (ident) lookup to get the remote users system name. Generally for
UNI* systems this is their login. The result is cached in $c->remote_logname
then returned. Subsequent calls to $r->get_remote_host
return the
cached value.
If the configuration directive IdentityCheck is set to off: then
$r->get_remote_logname
does nothing and $c->remote_logname
is
always undefined.
$c->user
, if any.
Returns the client file descriptor. If $direction is 0, the input fd is returned. If $direction is not null or ommitted, the output fd is returned.
This can be used to detect client disconnect without doing any I/O, e.g. using IO::Select.
The following methods are used to obtain information from server configuration and access control files.
Returns the value of a per-directory variable specified by the
PerlSetVar
directive.
# <Location /foo/bar> # PerlSetVar Key Value # </Location>
my $val = $r->dir_config('Key');
Keys are case-insensitive.
Will return a HASH reference blessed into the Apache::Table class when called in a scalar context with no "key" argument. See Apache::Table.
Returns the value of a per-directory array variable specified by the
PerlAddVar
directive.
# <Location /foo/bar> # PerlAddVar Key Value1 # PerlAddVar Key Value2 # </Location>
my @val = $r->dir_config->get('Key');
Alternatively in your code you can extend the setting with:
$r->dir_config->add(Key => 'Value3');
Keys are case-insensitive.
Will return a HASH reference blessed into the Apache::Table class when called in a scalar context with no "key" argument. See Apache::Table.
Basic
to use the basic authentication scheme defined in RFC 1945,
Hypertext Transfer Protocol -- HTTP/1.0. However, you could set to
something else and implement your own authentication scheme.
$r->auth_name
, to determine which set of
credentials to authenticate.
When called with no argument, returns a reference to the current value
of the per server configuration directive DocumentRoot. To quote the
Apache server documentation, "Unless matched by a directive like Alias,
the server appends the path from the requested URL to the document root
to make the path to the document." This same value is passed to CGI
scripts in the DOCUMENT_ROOT
environment variable.
You can also set this value by providing an argument to it. The following example dynamically sets the document root based on the request's "Host:" header:
sub trans_handler { my $r = shift; my ($user) = ($r->header_in('Host') =~ /^[^\.]+/); $r->document_root("/home/$user/www"); return DECLINED; } PerlTransHandler trans_handler
The $r->allow_options
method can be used for
checking if it is OK to run a perl script. The Apache::Options
module provides the constants to check against.
if(!($r->allow_options & OPT_EXECCGI)) { $r->log_reason("Options ExecCGI is off in this directory", $filename); }
server_rec*
in
disguise. The following methods can be used on the server object:
<Perl>
sections, PerlRequire or PerlModule.
Get or set the value of the current LogLevel. This method is added by the Apache::Log module, which needs to be pulled in.
use Apache::Log; print "LogLevel = ", $s->loglevel; $s->loglevel(Apache::Log::DEBUG);
If using Perl 5.005+, the following constants are defined (but not exported):
Apache::Log::EMERG Apache::Log::ALERT Apache::Log::CRIT Apache::Log::ERR Apache::Log::WARNING Apache::Log::NOTICE Apache::Log::INFO Apache::Log::DEBUG
Returns a reference to a list of handlers enabled for $hook. $hook is a string representing the phase to handle. The returned list is a list of references to the handler subroutines.
$list = $r->get_handlers( 'PerlHandler' );
Sets the list if handlers to be called for $hook. $hook is a string
representing the phase to handle. The list of handlers is an anonymous
array of code references to the handlers to install for this request
phase. The special list [ \&OK ]
can be used to disable a
particular phase.
$r->set_handlers( PerlLogHandler => [ \&myhandler1, \&myhandler2 ] ); $r->set_handlers( PerlAuthenHandler => [ \&OK ] );
Pushes a new handler to be called for $hook
. $hook
is a string
representing the phase to handle. The handler is a reference to a
subroutine to install for this request phase. This handler will be
called before any configured handlers.
$r->push_handlers( PerlHandler => \&footer);
Returns the name of the handler currently being run. This method is most useful to PerlDispatchHandlers who wish to only take action for certain phases.
if($r->current_callback eq "PerlLogHandler") { $r->warn("Logging request"); }
The following methods are used to set up and return the response back to the client. This typically involves setting up $r->status(), the various content attributes and optionally some additional $r->header_out() calls before calling $r->send_http_header() which will actually send the headers to the client. After this a typical application will call the $r->print() method to send the response content to the client.
Send the response line and all headers to the client. Takes an optional parameter indicating the content-type of the response, i.e. 'text/html'.
This method will create headers from the $r->content_xxx() and $r->no_cache() attributes (described below) and then append the headers defined by $r->header_out (or $r->err_header_out if status indicates an error).
If the current request is protected by Basic authentication, this method will return OK. Otherwise, it will return a value that ought to be propagated back to the client (typically AUTH_REQUIRED). The second return value will be the decoded password sent by the client.
($ret, $sent_pw) = $r->get_basic_auth_pw;
AuthName
.
Set the handler for a request.
Normally set by the configuration directive AddHandler
.
$r->handler( "perl-script" );
Return the value of a named entry in the Apache notes
table, or
optionally set the value of a named entry. This table is used by Apache
modules to pass messages amongst themselves. Generally if you are
writing handlers in mod_perl you can use Perl variables for this.
$r->notes("MY_HANDLER" => OK); $val = $r->notes("MY_HANDLER");
Will return a HASH reference blessed into the Apache::Table class when called in a scalar context with no "key" argument. This requires Apache::Table.
Like $r->notes, but takes any scalar as an value.
$r->pnotes("MY_HANDLER" => [qw(one two)]); my $val = $r->pnotes("MY_HANDLER"); print $val->[0]; # prints "one"
Advantage over just using a Perl variable is that $r->pnotes gets cleaned up after every request.
Return the value of a named entry in the Apache subprocess_env
table, or optionally set the value of a named entry. This table is
used by mod_include. By setting some custom variables inside
a perl handler it is possible to combine perl with mod_include nicely.
If you say, e.g. in a PerlHeaderParserHandler
$r->subprocess_env(MyLanguage => "de");
you can then write in your .shtml document:
<!--#if expr="$MyLanguage = en" --> English <!--#elif expr="$MyLanguage = de" --> Deutsch <!--#else --> Sorry <!--#endif -->
Will return a HASH reference blessed into the Apache::Table class when called in a scalar context with no "key" argument. This requires Apache::Table.
Get or set the content type being sent to the client. Content types are strings like "text/plain", "text/html" or "image/gif". This corresponds to the "Content-Type" header in the HTTP protocol. Example of usage is:
$previous_type = $r->content_type; $r->content_type("text/plain");
The $r->headers_out method will return a %hash of server response headers. This can be used to initialize a perl hash, or one could use the $r->header_out() method (described below) to retrieve or set a specific header value directly.
Will return a HASH reference blessed into the Apache::Table class when called in a scalar context with no "key" argument. This requires Apache::Table.
Change the value of a response header, or create a new one. You should not define any "Content-XXX" headers by calling this method, because these headers use their own specific methods. Example of use:
$r->header_out("WWW-Authenticate" => "Basic"); $val = $r->header_out($key);
The $r->err_headers_out method will return a %hash of server response headers. This can be used to initialize a perl hash, or one could use the $r->err_header_out() method (described below) to retrieve or set a specific header value directly.
The difference between headers_out and err_headers_out is that the latter are printed even on error, and persist across internal redirects (so the headers printed for ErrorDocument handlers will have them).
Will return a HASH reference blessed into the Apache::Table class when called in a scalar context with no "key" argument. This requires Apache::Table.
Change the value of an error response header, or create a new one. These headers are used if the status indicates an error.
$r->err_header_out("Warning" => "Bad luck"); $val = $r->err_header_out($key);
$r->no_cache(1)
adds the headers "Pragma: no-cache" and "Cache-control: no-cache" to
the reponse, therefore it must be called before $r->send_http_header
.
This method sends data to the client with $r->write_client
, but first
sets a timeout before sending with $r->soft_timeout
. This method is
called instead of CORE::print when you use print() in your mod_perl programs.
This method treats scalar references specially. If an item in @list is a scalar reference, it will be dereferenced before printing. This is a performance optimization which prevents unneeded copying of large strings, and it is subtly different from Perl's standard print() behavior.
Example:
$foo = \"bar"; print($foo);
The result is "bar", not the "SCALAR(0xDEADBEEF)" you might have expected. If
you really want the reference to be printed out, force it into a scalar
context by using print(scalar($foo))
.
Send the contents of a file to the client. Can for instance be used like this:
open(FILE, $r->filename) || return 404; $r->send_fd(FILE); close(FILE);
Redirect to a location in the server namespace without telling the client. For instance:
$r->internal_redirect("/home/sweet/home.html");
$r
is preserved.
This method provides a hook into the ErrorDocument mechanism, allowing you to configure a custom response for a given response code at request-time.
Example:
use Apache::Constants ':common';
sub handler { my($r) = @_;
if($things_are_ok) { return OK; }
#<Location $r->uri> #ErrorDocument 401 /error.html #</Location>
$r->custom_response(AUTH_REQUIRED, "/error.html");
#can send a string too #<Location $r->uri> #ErrorDocument 401 "sorry, go away" #</Location>
#$r->custom_response(AUTH_REQUIRED, "sorry, go away");
return AUTH_REQUIRED; }
(Documentation borrowed from http_main.h)
There are two functions which modules can call to trigger a timeout (with the per-virtual-server timeout duration); these are hard_timeout and soft_timeout.
The difference between the two is what happens when the timeout expires (or earlier than that, if the client connection aborts) --- a soft_timeout just puts the connection to the client in an "aborted" state, which will cause http_protocol.c to stop trying to talk to the client, but otherwise allows the code to continue normally. hard_timeout(), by contrast, logs the request, and then aborts it completely --- longjmp()ing out to the accept() loop in http_main. Any resources tied into the request resource pool will be cleaned up; everything that is not will leak.
soft_timeout() is recommended as a general rule, because it gives your code a chance to clean up. However, hard_timeout() may be the most convenient way of dealing with timeouts waiting for some external resource other than the client, if you can live with the restrictions.
When a hard timeout is in scope, critical sections can be guarded with block_alarms() and unblock_alarms() --- these are declared in alloc.c because they are most often used in conjunction with routines to allocate something or other, to make sure that the cleanup does get registered before any alarm is allowed to happen which might require it to be cleaned up; they * are, however, implemented in http_main.c.
kill_timeout() will disarm either variety of timeout.
reset_timeout() resets the timeout in progress.
Register a cleanup function which is called just before $r->pool is destroyed.
$r->register_cleanup(sub { my $r = shift; warn "registered cleanup called for ", $r->uri, "\n"; });
Cleanup functions registered in the parent process (before forking) will run once when the server is shut down:
#PerlRequire startup.pl warn "parent pid is $$\n"; Apache->server->register_cleanup(sub { warn "server cleanup in $$\n"});
The post_connection method is simply an alias for register_cleanup, as this method may be used to run code after the client connection is closed, which may not be a cleanup.
We also provide some methods that make it easier to support the CGI type of interface.
Take action on certain headers including Status:, Location: and Content-type: just as mod_cgi does, then calls $r->send_http_header(). Example of use:
$r->send_cgi_header(<<EOT); Location: /foo/bar Content-type: text/html
EOT
The following methods can be used to log errors.
The request failed, why?? Write a message to the server errorlog.
$r->log_reason("Because I felt like it", $r->filename);
Uh, oh. Write a message to the server errorlog.
$r->log_error("Some text that goes in the error_log");
log_error
. With 1.3+ versions of apache, this message will only be
send to the error_log if LogLevel is set to warn or higher.
Returns true if the specified callback hook is enabled:
for (qw(Access Authen Authz ChildInit Cleanup Fixup HeaderParser Init Log Trans Type)) { print "$_ hook enabled\n" if Apache::perl_hook($_); }
perl(1), Apache::Constants(3), Apache::Registry(3), Apache::Debug(3), Apache::Options(3), CGI::Apache(3)
Apache C API notes at http://www.apache.org/docs/
Perl interface to the Apache C API written by Doug MacEachern with contributions from Gisle Aas, Andreas Koenig, Eric Bartley, Rob Hartill, Gerald Richter, Salvador Ortiz and others.