Show Contents Previous Page Next Page
Chapter 9 - Perl API Reference Guide / Other Core Perl API Classes 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 "The Apache Request Object," 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 object-oriented 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 Example 7-12,
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 entries
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');
Show Contents Previous Page Next Page Copyright © 1999 by O'Reilly & Associates, Inc. |