The second example on p. 128 of the Eagle book sets the content
type and send the HTTP headers itself before running a
subrequest.
However, on p. 468, the documentation for the run() method says
in part:
When you invoke the subrequest's response handler in
this way, it will do everything a response handler is
supposed to, includinf sendinf the HTTP headers and the
document body. ... If you arevoking the subrequest
urn() method from within your own content handler, you
must not sen the HTTP headers and document body
yourself ...
These seem to contradict each other. From testing, however, it
seems as though the example on p. 128 is correct and the
documentation on p. 468 isn't. Is this true?
The above aside, I'm having a problem when using subrequests
when the subrequest also involves a (different) content handler.
First, in a VirtualHost block, I have:
AddType text/html .chtml
<Files *.chtml>
SetHandler perl-script
PerlHandler +Apache::HTML::ClassParser
</Files>
that sets up the aforementioned "different" content handler
that uses .chtml files to generate dynamic content pages. The
ClassParser content handler, as expected, calls send_http_header()
when it's ready to generate output. It does, in part:
sub handler {
# ...
return DECLINED if $r->content_type ne 'text/html';
# ...
$r->send_http_header();
# ... generate content ...
return OK;
}
Using this content handler by itself works just fine; however,
when I try to use it in conjunction with another content
handler, things don't work right.
Briefly, I have a Location block like:
<Location /get>
SetHandler perl-script
PerlHandler +My::Get
</Location>
that is a content handler that will, among other things, do
on-the-fly conversions (similarly to the ImageMagick example in
the Eagle book). The My::Get handler does, in part:
my $sub_r = $r->lookup_file( $full_path );
my $status = $sub_r->status();
unless ( $status == DOCUMENT_FOLLOWS ) {
$r->log_error( "Can't look up $full_path" );
return $status;
}
$r->send_http_header( $sub_r->content_type() );
return OK if $r->header_only();
return $sub_r->run();
When I use My::Get by itself, it works fine: it will correctly
serve documents of any type. However, I'd like My::Get to
simply be able to serve dynamic content pages if that's what
it's asked to do to provide a uniform URL scheme.
If $full_path refers to some .chtml file, things don't work
right: I get two sets of response headers (200 OK) but the
message that Apache prints is the canned "Document moved" error
(with <A HREF="">here</A>, i.e., an empty URL). Things I
tried:
1. In My::Get(), not calling send_http_header(). This results in
ordinary documents not being served correctly, e.g., the
content type is wrong.
2. In My::Get(), if $full_path ends up being a .chtml file, do:
$r->filename( $full_path );
return DECLINED;
This results in the correct headers; however, the raw HTML is
served, i.e., the ClassParser handler is never called on the
file.
I looked in the Eagle book about calling send_http_header()
from within subrequests by reading the documentation for
is_initial_req() and is_main(), but neither says anything about
send_http_header().
How can I get Apache to do what I want, i.e., have My::Get serve
a file that is handled by another content handler?
- Paul