OReilly Writing Apache Modules With Perl And C Apr 1999 ISBN 156592567X

10.5 The Table API
Apache provides a general API for creating and maintaining lookup
tables. Apache tables are ubiquitous, used for everything from storing the
current request's outgoing HTTP headers to maintaining the list of
environment variables passed to subprocesses.
Tables are similar to Perl hashes in that they are lists of key/value pairs.
However, unlike a Perl hash, keys are case-insensitive, and a single key
may correspond to a list of several values.[2] In addition, Apache table
keys and values are always strings; arbitrary data types cannot be used.
[2] Despite the differences between Perl hashes and Apache tables,

the Perl API allows programmers to access tables via tied Perl
hashes. See Section 9.2.5.
10.5.1 The table and table_entry Data Types

Currently, a table is an Apache array containing array elements of the
table_entry data type (defined in include/alloc.h):
typedef struct {
char *key; /* the key */
char *val; /* the value */
} table_entry;

When fetching or setting the value of a key, Apache searches for the key
using a simple linear search. Since most tables are short, this usually
doesn't impose a significant overhead. You will usually not want to
access the table_entry directly, but use API function calls to
manipulate the keys and values for you. If you do read directly from the
table_entry, a note in the include file indicates that you should check
the key for null. This is because the table_entry may be made part of
a more sophisticated hash table in the future.
The table structure itself is a private data type intended to be accessed
via an opaque table *. If you want to peek at its definition, you can find

it in include/alloc.c. It is equally straightforward:
struct table {
array_header a;
#ifdef MAKE_TABLE_PROFILE
void *creator;
#endif
};
The MAKE_TABLE_PROFILE define is part of Apache's debugging code
and is usually undefined, so table is really just an array header.

10.5.2 Creating and Copying Tables
If you need a table of key/value pairs that is private to your own module,
you can use these API routines to create it. You can either create a new
empty table or start with one that is already defined and make a copy of
it. These functions are defined in the include/alloc.h file, which is
automatically included when you bring in include/httpd.h.
table *ap_make_table (pool *p, int nelts)
ap_make_table() creates a new empty table, given a resource pool
pointer and an estimate of the number of elements you expect to
add. If the nelts argument is nonzero, that number of table_entry
tables will be pre-allocated for efficiency. Regardless of its initial size,
the table grows as necessary to accommodate new entries and table
merging operations.
Accessitable *my_table = ap_make_table(p, 25);
table * ap_copy_table (pool *p, const table *t)
This function takes a resource pool and an existing table and makes
a replica of the table, returning a pointer to the copy. You can then
change the contents of the copy without modifying the original. In
this example, we make a copy of the headers_in table:
table *my_headers = ap_copy_table(r->pool, r->headers_in);


10.5.3 Getting and Setting Table Values
These routines allow you to add new entries to the table, to change
existing ones, and to retrieve entries.
const char *ap_table_get (const table *t, const char *key)
Given a table pointer and a key, ap_table_get() returns the value of
the entry at that key as a char *. If there are multiple values for that
particular key, the function will only return the first one it finds, which
will be the first entry added.
In this example, we recover the string value of the incoming Useragent header:
const char *ua = ap_table_get(r->headers_in, "User-agent");
To iterate through the multiple values for the same key, use the
ap_table_do() function described later in this section.
void ap_table_set (table *t, const char *key, const char *val)
ap_table_set() sets the entry named by key to the character string in
val. If an entry with the same key already exists, its value is
replaced. Otherwise, a new entry is created. If more than one entry
has the same key, the extraneous ones are deleted, making the key
single-valued.
Internally, Apache calls ap_pstrdup() on the key and the value and

stores copies of them in the table. This means that you are able to
change or dispose of the original variables without worrying about
disrupting the table.
Here's an example of using this function to set the outgoing headers
field Location to the string http://www.modperl.com/. Because
Location is a single-valued field, ap_table_set() is the correct call to
use:

ap_table_set(r->headers_out, "Location", "http://www.modperl

void ap_table_setn (table *t, const char *key, const char *val)
This function behaves the same as ap_table_set(), but the character
strings for key and val are not copied with ap_pstrdup(). You must
ensure that the strings remain valid for the lifetime of the table. The
previous example is a good candidate for ap_table_setn(), as it uses
static strings for both the key and value.
void ap_table_add (table *t, const char *key, const char *val)
This function is similar to ap_table_set(), but existing entries with the
same key are not replaced. Instead, the new entry is added to the
end of the list, making the key multivalued.

Internally, Apache calls ap_pstrdup() on the key and the value,
allowing you to change or dispose of the original variables without
worrying about disrupting the table.
This example adds several Set-cookie fields to the outgoing HTTP
headers table:
for(i=0; cookies[i]; i++) {
ap_table_add(r->headers_out, "Set-cookie", cookies[i]);
}
void ap_table_addn (table *t, const char *key, const char *val)
This function behaves like ap_table_add(), but key and val are not
duplicated before storing them into the table. This function saves a
little time and memory if you are working with static strings.
void ap_table_merge (table *t, const char *key, const char *val)
ap_table_merge() merges a new key value into the existing entry by
appending it to what's already there. This is used for commadelimited header fields such as Content-language. For example, this
series of calls will result in a value of en, fr, sp in the Contentlanguage field:
ap_table_merge(r->headers_out, "Content-language", "en");

ap_table_merge(r->headers_out, "Content-language", "fr");
ap_table_merge(r->headers_out, "Content-language", "sp");

Like ap_table_set(), the key and value are copied using ap_pstrdup()
before moving them into the table.
void ap_table_mergen (table *t, const char *key, const char *val)
This function is the same as ap_table_merge, but the key and val
arguments are not copied with ap_pstrdup() before entering them
into the table.
void ap_table_unset (table *t, const char *key)
ap_table_unset() deletes all entries having the indicated key. This
example removes the Referer field from the incoming headers,
possibly in preparation for making an anonymous proxy request (see
Chapter 7):
ap_table_unset(r->headers_in, "Referer");
void ap_table_do (int (*comp)(void *, const char *, const char *), void
*rec, const table *t,...);
ap_table_get() and ap_table_getn() work well for single-valued keys,
but there are a few instances in which keys are not unique. To
access all the values of these keys, you will have to use
ap_table_do() to iterate over the table.
As its prototype indicates, this function is more complicated than the
ones we've seen before. The function's first argument is a pointer to

a callback function that will be called during the iteration process.
The second argument is a void * that can be used to pass some
arbitrary information to the callback. The third argument is the table
* itself. This is followed by a variable number of char * key
arguments, terminated by a null. ap_table_do() will iterate over the
table, invoking the callback routine only when a table entries' key
matches a key in the given list. If no keys are given, the function will
invoke the callback routine for all of the table entries.

The callback function should have this function prototype:

int callback(void *rec, const char *key, const char *value);
The first argument corresponds to the void * argument passed to
ap_table_do(), and the second and third arguments are the key and
value of the current table entry. The callback should do whatever
work it needs to do (for example, copying the value into an Apache
array), and return a true value. The callback can return in order to
abort ap_table_do() prematurely.
Here's a callback that simply prints out the key name and value
without performing further processing:


static int header_trace(void *data, const char *key, const c
{
request_rec *r = (request_rec *)data;
ap_rprintf(r, "Header Field `%s' == `%s'\n", key, val);
return TRUE;
}
Here's how the callback can be used to print out the contents of the
outgoing headers table:
ap_table_do(header_trace, r, r->headers_out, NULL);
And in this example, the callback is only invoked for the Content-type
and Content-length fields:
ap_table_do(header_trace, (void*)r, r->headers_out,
"Content-type", "Content-length", NULL);
10.5.4 Other Table Functions
Here are a few miscellaneous table functions that don't fit into the
previous categories:
table *ap_overlay_tables (pool *p, const table *overlay, const table *base)

This function takes the contents of the table at overlay and adds it

to the table at base. Entries in overlay that don't exist in base are
added to base. Entries that already exist in base are overwritten. You
can use ap_overlay_tables() to perform a bulk update of a table. This
example overlays the fields listed in my_headers onto the table of
outgoing headers:

table *new_table = _ap_overlay_tables(r->pool, my_headers, r
array_header *ap_table_elts (table *t)
If you wish to access the contents of the table directly, you can call
the ap_table_elts() function (it's a preprocessor macro, actually). It
will return an array_header*, which you can then iterate through,
casting each element to a table_entry.
array_header *arr = ap_table_elts(my_table);
int ap_is_empty_table (table *t)
This function (it's a preprocessor macro, actually) returns true if there
are no entries in the given table, or false otherwise.
if(!ap_is_empty_table(my_table)) {
/* this table has one or more elements */
}
void ap_clear_table (table *t)

The ap_clear_table() function clears all entries from the table.
Example:
ap_clear_table(my_table);

9.2 Other Core Perl API Classes
The vast bulk of the functionality of the Perl API is contained in the
Apache object. However, a number of auxiliary classes, including
Apache::Table, Apache::Connection, and Apache::Server, provide
additional methods for accessing and manipulating the state of the
server. This section discusses these classes.
9.2.1 The Apache TIEHANDLE Interface
In the CGI environment, the standard input and standard output file
descriptors are redirected so that data read and written is passed through
Apache for processing. In the Apache module API, handlers ordinarily
use the Apache read() and print() methods to communicate with the
client. However, as a convenience, mod_perl ties the STDIN and
STDOUT filehandles to the Apache class prior to invoking Perl API
modules. This allows handlers to read from standard input and write to
standard output exactly as if they were in the CGI environment.
The Apache class supports the full TIEHANDLE interface, as described

in perltie(1). STDIN and STDOUT are already tied to Apache by the time
your handler is called. If you wish to tie your own input or output
filehandle, you may do so by calling tie() with the request object as the
function's third parameter:
tie *BROWSER, 'Apache', $r;
print BROWSER 'Come out, come out, wherever you are!';
Of course, it is better not to hardcode the Apache class name, as $r
might be blessed into a subclass:
tie *BROWSER, ref $r, $r;
9.2.2 The Apache::SubRequest Class
The Apache methods lookup_uri( ) and lookup_file( ) return a request
record object blessed into the Apache::SubRequest class. The

Apache::SubRequest class is a subclass of Apache and inherits most of
its methods from there. Here are two examples of fetching subrequest
objects:
my $subr = $r->lookup_file($filename);
my $subr = $r->lookup_uri($uri);
The Apache::SubRequest class adds a single new method, run().
run()
When a subrequest is created, the URI translation, access checks,
and MIME checking phases are run, but unlike a real request, the
content handler for the response phase is not actually run. If you
would like to invoke the content handler, the run( ) method will do it:
my $status = $subr->run;
When you invoke the subrequest's response handler in this way, it
will do everything a response handler is supposed to, including
sending the HTTP headers and the document body. run( ) returns
the content handler's status code as its function result. If you are
invoking the subrequest run( ) method from within your own content
handler, you must not send the HTTP header and document body
yourself, as this would be appended to the bottom of the information
that has already been sent. Most handlers that invoke run() will
immediately return its status code, pretending to Apache that they
handled the request themselves:
my $status = $subr->run;
return $status;
9.2.3 The Apache::Server Class
The Apache::Server class provides the Perl interface to the C API
server_rec data structure, which contains lots of low-level information
about the server configuration. Within a handler, the current
Apache::Server object can be obtained by calling the Apache request
object's server( ) method. At Perl startup time (such as within a startup

script or a module loaded with PerlModule), you can fetch the server
object by invoking Apache->server directly. By convention, we use the
variable $s for server objects.
#at request time
sub handler {
my $r = shift;
my $s = $r->server;
....
}
#at server startup time, e.g., PerlModule or PerlRequire
my $s = Apache->server;
This section discusses the various methods that are available to you via
the server object. They correspond closely to the fields of the
server_rec structure, which we revisit in Chapter 10.
is_virtual()
This method returns true if the current request is being applied to a
virtual server. This is a read-only method.
my $is_virtual = $s->is_virtual;
log()
The log( ) method retrieves an object blessed into the Apache::Log
class. You can then use this object to access the full-featured
logging API. See Section 9.1.6.2" for details.
use Apache::Log ();
my $log = $s->log;
The Apache::Server::log() method is identical in most respects to the
Apache::log() method discussed earlier. The difference is that
messages logged with Apache::log() will include the IP address of
the browser and add the messages to the notes table under a key
named error-notes. See the description of notes() under Section

9.1.4."
port()
This method returns the port on which this (virtual) server is listening.
If no port is explicitly listed in the server configuration file (that is, the
server is listening on the default port 80), this method will return 0.
Use the higher-level Apache::get_server_port() method if you wish to
avoid this pitfall.
my $port = $r->server->port || 80;
This method is read-only.
server_admin()
This method returns the email address of the person responsible for
this server as configured by the ServerAdmin directive.
my $admin = $s->server_admin;
This method is read-only.
server_hostname()
This method returns the (virtual) hostname used by this server, as
set by the ServerName directive.
my $hostname = $s->server_hostname;
This method is read-only.
names()
If this server is configured to use virtual hosts, the names( ) method
will return the names by which the current virtual host is recognized
as specified by the ServerAlias directives (including wildcarded
names). The function result is an array reference containing the
hostnames. If no alias names are present or the server is not using
virtual hosts, this will return a reference to an empty list.

my $s = $r->server;
my $names = $s->names;
print "Names = @$names\n";
next()
Apache maintains a linked list of all configured virtual servers, which
can be accessed with the next( ) method.

for(my $s = Apache->server; $s; $s = $s->next) {
printf "Contact %s regarding problems with the %s site\n
$s->server_admin, $s->server_hostname;
}
log_error()
This method is the same as the Apache::log_error( ) method, except
that it's available through the Apache::Server object. This allows you
to use it in Perl startup files and other places where the request
object isn't available.
my $s = Apache->server;
$s->log_error("Can't open config file $!");
warn()
This method is the same as the Apache::warn( ) method, but it's
available through the Apache::Server object. This allows you to use
it in Perl startup files and other places where the request object isn't
available.
my $s = Apache->server;
$s->warn("Can't preload script $file $!");
9.2.4 The Apache::Connection Class
The Apache::Connection class provides a Perl interface to the Clanguage conn_rec data structure, which provides various low-level
details about the network connection back to the client. Within a handler,

the connection object can be obtained by calling the Apache request
object's connection( ) method. The connection object is not available
outside of handlers for the various request phases because there is no
connection established in those cases. By convention, we use the
variable $c for connection objects.
sub handler {
my $r = shift;
my $c = $r->connection;
...
}
In this section we discuss the various methods made available by the
connection object. They correspond closely to the fields of the C API
conn_rec structure discussed in Chapter 10.
aborted()
This method returns true if the client has broken the connection
prematurely. This can happen if the remote user's computer has
crashed, a network error has occurred, or, more trivially, the user
pressed the stop button before the request or response was fully
transmitted. However, this value is only set if a soft timeout occurred.
if($c->aborted) {
warn "uh,oh, the client has gone away!";
}
See the description of soft_timeout() earlier.
auth_type()
If authentication was used to access a password protected
document, this method returns the type of authentication that was
used, currently either Basic or Digest. This method is different from
the request object's auth_type( ) method, which we discussed
earlier, because the request object's method returns the value of the
AuthType configuration directive; in other words, the type of
authentication the server would like to use. The connection object's

auth_type() method returns a value only when authentication was
successfully completed and returns undef otherwise.
if($c->auth_type ne 'Basic') {
warn "phew, I feel a bit better";
}
This method is read-only.
local_addr()
This method returns a packed SOCKADDR_IN structure in the same
format as returned by the Perl Socket module's pack_sockaddr_in( )
function. This packed structure contains the port and IP address at
the server's side of the connection. This is set by the server when
the connection record is created, so it is always defined.
use Socket ();
sub handler {
my $r = shift;
my $local_add = $r->connection->local_addr;
my($port, $ip) = Socket::unpack_sockaddr_in($local_add);
...
}
For obvious reasons, this method is read-only.
remote_addr()
This method returns a packed SOCKADDR_IN structure for the port
and IP address at the client's side of the connection. This is set by
the server when the connection record is created, so it is always
defined.
Among other things, the information returned by this method and
local_addr() can be used to perform RFC 1413 ident lookups on the
remote client, even when the configuration directive IdentityCheck is
turned off. Here is an example using Jan-Pieter Cornet's Net::Ident
module:

use Net::Ident qw(lookupFromInAddr);
my $remoteuser = lookupFromInAddr ($c->local_addr,
$c->remote_addr, 2);
remote_host()
This method returns the hostname of the remote client. It only
returns the name if the HostNameLookups directive is set to On and
the DNS lookup was successfulthat is, the DNS contains a reverse
name entry for the remote host. If hostname-based access control is
in use for the given request, a double-reverse lookup will occur
regardless of the HostNameLookups setting, in which case, the
cached hostname will be returned. If unsuccessful, the method
returns undef.
It is almost always better to use the high-level get_remote_host()
method available from the Apache request object (discussed earlier).
The high-level method returns the dotted IP address of the remote
host if its DNS name isn't available, and it caches the results of
previous lookups, avoiding overhead when you call the method
multiple times.

my $remote_host = $c->remote_host || "nohost";
my $remote_host = $r->get_remote_host(REMOTE_HOST); # better
This method is read-only.
remote_ip()
This method returns the dotted decimal representation of the remote
client's IP address. It is set by the server when the connection record
is created and is always defined.
my $remote_ip = $c->remote_ip;
The remote_ip() can also be changed, which is helpful if your server
is behind a proxy such as the squid accelerator. By using the XForwarded-For header sent by the proxy, the remote_ip can be set to
this value so logging modules include the address of the real client.

The only subtle point is that X-Forwarded-For may be multivalued in
the case of a single request that has been forwarded across multiple
proxies. It's safest to choose the last IP address in the list since this
corresponds to the original client.
my $header = $r->headers_in->{'X-Forwarded-For'};
if( my $ip = (split /,\s*/, $header)[-1] ) {
$r->connection->remote_ip($ip);
}
remote_logname()
This method returns the login name of the remote user, provided that
the configuration directive IdentityCheck is set to On and the remote
user's machine is running an identd daemon. If one or both of these
conditions is false, the method returns undef.
It is better to use the high-level get_remote_logname() method which
is provided by the request object. When the high-level method is
called, the result is cached and reused if called again. This is not
true of remote_logname().
my $remote_logname = $c->remote_logname || "nobody";
my $remote_logname = $r->get_remote_logname; # better
user()
When Basic authentication is in effect, user( ) returns the name that
the remote user provided when prompted for his username and
password. The password itself can be recovered from the request
object by calling get_basic_auth_pw( ).
my $username = $c->user;
9.2.5 The Apache::Table Class
The HTTP message protocol is simple largely because of its consistent
use of the key/value paradigm in its request and response header fields.
Because much of an external module's work is getting and setting these

header fields, Apache provides a simple yet powerful interface called the
table structure. Apache tables are keyed case-insensitive lookup
tables. API function calls allow you to obtain the list of defined keys,
iterate through them, get the value of a key, and set key values. Since
many HTTP header fields are potentially multivalued, Apache also
provides functionality for getting, setting, and merging the contents of
multivalued fields.
The following five C data structures are implemented as tables. This list
is likely to grow in the future.
headers_in
headers_out
err_headers_out
notes
subprocess_env
As discussed in Section 9.1," the Perl API provides five method calls,
named headers_in(), headers_out(), err_headers_out(), notes(), and
subprocess_env(), that retrieve these tables. The Perl manifestation of
the Apache table API is the Apache::Table class. It provides a TIEHASH
interface that allows transparent access to its methods via a tied hash
reference, as well as API methods that can be called directly.
The TIEHASH interface is easy to use. Simply call one of the methods
listed earlier in a scalar context to return a tied hash reference. For
example:
my $table = $r->headers_in;
The returned object can now be used to get and set values in the
headers_in table by treating it as an ordinary hash reference, but the
keys are looked up case-insensitively. Examples:
my $type = $table->{'Content-type'};

my $type = $table->{'CONTENT-TYPE'}; # same thing
$table->{'Expires'} = 'Sat, 08 Aug 1998 01:39:20 GMT';
If the field you are trying to access is multivalued, then the tied hash
interface suffers the limitation that fetching the key will only return the first
defined value of the field. You can get around this by using the objectoriented interface to access the table (we show an example of this later)
or by using the each operator to access each key and value sequentially.
The following code snippet shows one way to fetch all the Set-cookie
fields in the outgoing HTTP header:
while (my($key, $value) = each %{$r->headers_out}) {
push @cookies, $value if lc($key) eq 'set-cookie';
}
When you treat an Apache::Table object as a hash reference, you are
accessing its internal get() and set() methods (among others) indirectly.
To gain access to the full power of the table API, you can invoke these
methods directly by using the method call syntax.
Here is the list of publicly available methods in Apache::Table, along with
brief examples of usage:
add()
The add( ) method will add a key/value pair to the table. Because
Apache tables can contain multiple instances of a key, you may call
add( ) multiple times with different values for the same key. Instead
of the new value of the key replacing the previous one, it will simply
be appended to the list. This is useful for multivalued HTTP header
fields such as Set-Cookie. The outgoing HTTP header will contain
multiple instances of the field.
my $out = $r->headers_out;
for my $cookie (@cookies) {
$out->add("Set-cookie" => $cookie);
}
Another way to add multiple values is to pass an array reference as
the second argument. This code has the same effect as the previous

example:
my $out = $r->headers_out;
$out->add("Set-cookie" => \@cookies);
clear()
This method wipes the current table clean, discarding its current
contents. It's unlikely that you would want to perform this on a public
table, but here's an example that clears the notes table:
$r->notes->clear;
do()
This method provides a way to iterate through an entire table item by
item. Pass it a reference to a code subroutine to be called once for
each table entry. The subroutine should accept two arguments
corresponding to the key and value, respectively, and should return a
true value. The routine can return a false value to terminate the
iteration prematurely.
This example dumps the contents of the headers_in field to the
browser:
$r->headers_in->do(sub {
my($key, $value) = @_;
$r->print("$key => $value\n");
1;
});
For another example of do(), see Chapter 7, where we use it to
transfer the incoming headers from the incoming Apache request to
an outgoing LWP HTTP::Request object.
get()
Probably the most frequently called method, the get( ) function
returns the table value at the given key. For multivalued keys, get( )
implements a little syntactic sugar. Called in a scalar context, it

returns the first value in the list. Called in an array context, it returns
all values of the multivalued key.
my $ua = $r->headers_in->get('User-agent');
my @cookies = $r->headers_in->get('Cookie');
get() is the underlying method that is called when you use the tied
hash interface to retrieve a key. However, the ability to fetch a
multivalued key as an array is only available when you call get()
directly using the object-oriented interface.
merge()
merge( ) behaves like add( ), except that each time it is called the
new value is merged into the previous one, creating a single HTTP
header field containing multiple comma-delimited values.
In the HTTP protocol, a comma-separated list of header values is
equivalent to the same values specified by repeated header lines.
Some buggy clients may not accept merged headers, however. In
this case, it is worthwhile to control the merging explicitly and avoid
merging headers that cause trouble (like Set-cookie).
merge() works like add(). You can either merge a series of entries
one at a time:
my @languages = qw(en fr de);
foreach (@languages) {
$r->headers_out->merge("Content-language" => $_);
}
or merge a bunch of entries in a single step by passing an array
reference:
$r->headers_out->merge("Content-language" => \@languages);
new()
The new( ) method is available to create an Apache::Table object
from scratch. It requires an Apache object to allocate the table and,

optionally, the number of entries to initially allocate. Note that just like
the other Apache::Table objects returned by API methods,
references cannot be used as values, only strings.

my $tab = Apache::Table->new($r); #default, allocates 10 ent
my $tab = Apache::Table->new($r, 20); #allocate 20 entries
set()
set( ) takes a key/value pair and updates the table with it, creating
the key if it didn't exist before, or replacing its previous value(s) if it
did. The resulting header field will be single-valued. Internally this
method is called when you assign a value to a key using the tied
hash interface.
Here's an example of using set() to implement an HTTP redirect:

$r->headers_out->set(Location => 'http://www.modperl.com/');
unset()
This method can be used to remove a key and its contents. If there
are multiple entries with the same key, they will all be removed.
$r->headers_in->unset('Referer');
9.2.6 The Apache::URI Class
Apache Version 1.3 introduced a utility module for parsing URIs,
manipulating their contents, and unparsing them back into string form.
Since this functionality is part of the server C API, Apache::URI offers a
lightweight alternative to the URI::URL module that ships with the
libwww-perl package.[5]
[5] At the time of this writing, URI::URL was scheduled to be

replaced by URI.pm, which will be distributed separately from the
libwww-perl package.

An Apache::URI object is returned when you call the request object's
parsed_uri() method. You may also call the Apache::URI parse()
constructor to parse an arbitrary string and return a new Apache::URI
object, for example:
use Apache::URI ();
my $parsed_uri = $r->parsed_uri;
fragment()
This method returns or sets the fragment component of the URI. You
know this as the part that follows the hash mark (#) in links. The
fragment component is generally used only by clients and some web
proxies.
my $fragment = $uri->fragment;
$uri->fragment('section_1');
hostinfo()
This method gets or sets the remote host information, which usually
consists of a hostname and port number in the format
hostname:port. Some rare URIs, such as those used for
nonanonymous FTP, attach a username and password to this
information, for use in accessing private resources. In this case, the
information returned is in the format
username:password@hostname:port.
This method returns the host information when called without
arguments, or sets the information when called with a single string
argument.
my $hostinfo = $uri->hostinfo;
$uri->hostinfo('www.modperl.com:8000');
hostname()
This method returns or sets the hostname component of the URI
object.

my $hostname = $uri->hostname;
$uri->hostname('www.modperl.com');
parse()
The parse( ) method is a constructor used to create a new
Apache::URI object from a URI string. Its first argument is an Apache
request object, and the second is a string containing an absolute or
relative URI. In the case of a relative URI, the parse( ) method uses
the request object to determine the location of the current request
and resolve the relative URI.

my $uri = Apache::URI->parse($r, 'http://www.modperl.com/');
If the URI argument is omitted, the parse() method will construct a
fully qualified URI from $r, including the scheme, hostname, port,
path, and query string.
my $self_uri = Apache::URI->parse($r);
password()
This method gets or sets the password part of the hostinfo
component.
my $password = $uri->password;
$uri->password('rubble');
path()
This method returns or sets the path component of the URI object.
my $path = $uri->path;
$uri->path('/perl/hangman.pl');
path_info()
After the "real path" part of the URI comes the "additional path
information." This component of the URI is not defined by the official
URI RFC, because it is an internal concept from web servers that

need to do something with the part of the path information that is left
over from translating the path into a valid filename.
path_info() gets or sets the additional path information portion of the
URI, using the current request object to determine what part of the
path is real and what part is additional.
$uri->path_info('/foo/bar');
port()
This method returns or sets the port component of the URI object.
my $port = $uri->port;
$uri->port(80);
query()
This method gets or sets the query string component of the URI; in
other words, the part after the ?.
my $query = $uri->query;
$uri->query('one+two+three');
rpath()
This method returns the "real path;" that is, the path( ) minus the
path_info( ).
my $path = $uri->rpath();
scheme()
This method returns or sets the scheme component of the URI. This
is the part that identifies the URI's protocol, such as http or ftp.
Called without arguments, the current scheme is retrieved. Called
with a single string argument, the current scheme is set.
my $scheme = $uri->scheme;
$uri->scheme('http');

unparse()
This method returns the string representation of the URI. Relative
URIs are resolved into absolute ones.
my $string = $uri->unparse;
Beware that the unparse() method does not take the additional path
information into account. It returns the URI minus the additional
information.
user()
This method gets or sets the username part of the hostinfo
component.
my $user = $uri->user;
$uri->user('barney');
9.2.7 The Apache::Util Class
The Apache API provides several utility functions that are used by
various standard modules. The Perl API makes these available as
function calls in the Apache::Util package.
Although there is nothing here that doesn't already exist in some existing
Perl module, these C versions are considerably faster than their
corresponding Perl functions and avoid the memory bloat of pulling in yet
another Perl package.
To make these functions available to your handlers, import the
Apache::Util module with an import tag of :all :
use Apache::Util qw(:all);
escape_uri()
This function encodes all unsafe characters in a URI into %XX hex
escape sequences. This is equivalent to the
URI::Escape::uri_escape( ) function from the LWP package.

use Apache::Util qw(escape_uri);
my $escaped = escape_uri($url);
escape_html()
This function replaces unsafe HTML character sequences (, and
&) with their entity representations. This is equivalent to the
HTML::Entities::encode( ) function.

use Apache::Util qw(escape_html);
my $display_html = escape_html("Header Level 1 Exampleexport(qw( HTTP_MULTIPLE_CHOICES ));
#runtime module
use Apache::Constants qw(:common HTTP_MULTIPLE_CHOICES);
...
return HTTP_MULTIPLE_CHOICES;
While the HTTP constants generally use a return code from handler
subroutines, it is also possible to use the built-in die() function to jump out
of a handler with a status code that will be propagated back to Apache:
unless (-r _) {
die FORBIDDEN;
}

Chapter 7. Other Request Phases
The previous chapters have taken you on a wide-ranging tour of the most
popular and useful areas of the Apache API. But we're not done yet! The
Apache API allows you to customize URI translation, logging, the
handling of proxy transactions, and the manner in which HTTP headers
are parsed. There's even a way to incorporate snippets of Perl code
directly into HTML pages that use server-side includes.
We've already shown you how to customize the response, authentication,
authorization, and access control phases of the Apache request cycle.
Now we'll fill in the cracks. At the end of the chapter, we show you the
Perl server-side include system, and demonstrate a technique for
extending the Apache Perl API by subclassing the Apache request object
itself.

Chapter 10. C API Reference Guide, Part I
The last two chapters of this book, Chapters Chapter 10 and Chapter
11, focus on aspects of the Apache module API that C-language
programmers need to know. The majority of the API has already been
covered in previous chapters, where we looked at it from the perspective
of its Perl incarnation. We will briefly revisit each of the topics that we've
already discussed in order to show you how the API appears in C. Topics
that are specific to the C API, such as memory management, are covered
in more detail.
Because the C API is so much of a recapitulation of the Perl API,[1] we
won't show you as many complete examples in this chapter as we have
in the previous ones, although there are still plenty of code snippets. For
a complete C module skeleton, have a look at mod_example.c, which
can be found in the Apache distribution in the directory
src/modules/example. It implements handlers for each of the phases and
writes out a log entry when each phase has been activated. For "how did
they do that?" questions, peruse the source code for the standard
modules in src/modules/standard. You'll also find a number of complete C
API example modules at this book's companion web site,
http://www.modperl.com.
[1] Technically, it's the other way around.

This chapter covers the most common parts of the API, including the data
types that all handlers must know about, functions for manipulating
arrays, tables, and resource pools, and techniques for getting and setting
information about the request. The next chapter describes how to define
and manage configuration directives and covers the less essential parts
of the C API, such as string manipulation functions, and esoterica such
as opening pipes to subprocesses.
We do our best to follow the Apache coding style guide throughout. You'll
find this guide along with other developer resources at the Apache
Project Development site, http://dev.apache.org/.

9.1 The Apache Request Object
The Apache request object implements a huge number of methods. To
help you find the method you're looking for, we've broken them down into
eight broad categories:
Client request methods
Methods that have to do with retrieving information about the current
request, such as fetching the requested URI, learning the request
document's filename, or reading incoming HTTP headers.
Server response methods
Methods that are concerned with setting outgoing information, such
as setting outgoing headers and controlling the document language
and compression.
Sending data to the client
Methods for sending document content data to the client.
Server core functions
Methods that control key aspects of transaction processing but are
not directly related to processing browser data input or output. For
example, the subrequest API is covered in this section.
Server configuration methods
Methods for retrieving configuration information about the server.
Logging
Methods for logging error messages and warnings to the server error
log.
Access control methods

Methods for controlling access to restricted documents and for
authenticating remote users.
mod_perl-specific methods
Methods that use special features of mod_perl which have no
counterpart in the C API. They include such things as the gensym()
method for generating anonymous filehandles and set_handlers() for
altering the list of subroutines that will handle the current request.
Should you wish to subclass the Apache object in order to add
application-specific features, you'll be pleased to find that it's easy to do
so. Please see Section 7.11, for instructions.
9.1.1 Client Request Methods
This section covers the request object methods that are used to query or
modify the incoming client request. These methods allow you to retrieve
such information as the URI the client has requested, the request method
in use, the content of any submitted HTML forms, and various items of
information about the remote host.
args( )
The args( ) method returns the contents of the URI query string (that
part of the request URI that follows the ? character, if any). When
called in a scalar context, args( ) returns the entire string. When
called in a list