Show Contents Previous Page Next Page Chapter 4 - Content Handlers In this section...
The C-language Apache API only allows a single content handler to completely process a request. Several handlers may be given a shot at it, but the first one to return an OK status will terminate the content handling phase of the transaction. There are times when it would be nice to chain handlers into a pipeline. For example, one handler could add canned headers and footers to the page, another could correct spelling errors, while a third could add trademark symbols to all proprietary names. Although the native C API can't do this yet,3 the Perl API can, using a technique called "stacked handlers."
It is actually quite simple to stack handlers. Instead of declaring a single module or subroutine in the PerlHandler directive, you declare several. Each handler will be called in turn in the order in which it was declared. The exception to this rule is if one of the handlers in the series returns an error code (anything other than Simple Case of Stacked Handlers Show Contents Go to Top Previous Page Next Page Example 4-20 gives a very simple example of
a stack of three content handlers. It's adapted slightly from the A suitable configuration section looks like this: PerlModule My <Location /My> SetHandler perl-script PerlHandler My::header My::body My::footer </Location> We first load the whole module into memory using the PerlModule directive. We then declare a URI location /My and assign the perl-script handler to it. Perl in turn is configured to run the My::header, My::body, and My::footer subroutines by passing them as arguments to a PerlHandler directive. In this case, the /My location has no corresponding physical directory, but there's no reason that it couldn't.
After bringing in the header text body text footer text Example 4-20.A Simple Stacked Handler package My; use strict; use Apache::Constants 'OK'; sub header { my $r = shift; $r->content_type('text/plain'); $r->send_http_header; $r->print("header text\n"); OK; } sub body { my $r = shift; $r->print("body text\n"); OK; } sub footer { my $r = shift; $r->print("footer text\n"); OK; } 1;Show Contents Go to Top Previous Page Next Page Stacked handlers often have to coordinate their activities. In the example of the previous section, the header() handler must be run before either of the other two in order for the HTTP header to come out correctly. Sometimes it's useful to make the first handler responsible for coordinating the other routines rather than relying on the configuration file. The request object's push_handlers() method will help you do this. push_handlers() takes two arguments: a string representing the phase to handle, and a reference to a subroutine to handle that phase. For example, this code fragment will arrange for the footer() subroutine to be the next content handler invoked: $r->push_handlers(PerlHandler => \&footer); With this technique, we can rewrite the previous example along the lines shown in Example 4-21. In the revised module, we declare a subroutine named handler() that calls push_handlers() three times, once each for the header, body, and footer of the document. It then exits. The other routines are unchanged. The revised configuration file entry looks like this: <Location /MyChain> SetHandler perl-script PerlHandler My::Chain </Location>
Because we followed the Example 4-21. Coordinated Stacked Handlers package My::Chain; use strict; use Apache::Constants 'OK'; sub handler { my $r = shift; for my $cv (\&header, \&body, \&footer) { sub header { my $r = shift; $r->content_type('text/plain'); $r->send_http_header; $r->print("header text\n"); OK; } sub body { my $r = shift; $r->print("body text\n"); OK; } sub footer { my $r = shift; $r->print("footer text\n"); OK; } 1; __END__Show Contents Go to Top Previous Page Next Page Copyright © 1999 by O'Reilly & Associates, Inc. |
HIVE: All information for read only. Please respect copyright! |