Mod Perl 2.0 HTTP Handlers

Mod Perl 2.0 HTTP Handlers

am 02.11.2008 11:11:54 von Puneet Lakhina

Hi,

I am new to mod perl and apache. I am trying to write a URI
translation engine which needs to use the cookies set on the client.
Additionally I want mod_rewrite and other URI Translational hooks to
be invoked once my hook is done.

Initially I thought PerlTransHandler would be the right thing to use.
But as it turns out, the headers arent populated until that phase. I
dont understand why is this? Could someone give some pointers on what
might be the right way of doing this?

Thanks
--
Regards,
Puneet

Re: Mod Perl 2.0 HTTP Handlers

am 02.11.2008 11:30:14 von torsten.foertsch

On Sun 02 Nov 2008, Puneet Lakhina wrote:
> Initially I thought PerlTransHandler would be the right thing to use.

It is.

> But as it turns out, the headers arent populated until that phase.

Input headers are found in $r->headers_in and are set even before
PerlPostReadRequest. So, have a close look at your code. If that
doesn't help try to create a test case as simple as you can and post it
to the list.

Torsten

--
Need professional mod_perl support?
Just hire me: torsten.foertsch@gmx.net

Re: Mod Perl 2.0 HTTP Handlers

am 02.11.2008 11:48:12 von Puneet Lakhina

> Input headers are found in $r->headers_in and are set even before
> PerlPostReadRequest. So, have a close look at your code. If that
> doesn't help try to create a test case as simple as you can and post it
> to the list.
>
Not as per this:
http://perl.apache.org/docs/2.0/api/Apache2/RequestRec.html# C_headers_in_



--
Regards,
Puneet

Re: Mod Perl 2.0 HTTP Handlers

am 02.11.2008 12:58:50 von torsten.foertsch

On Sun 02 Nov 2008, Puneet Lakhina wrote:
> > Input headers are found in $r->headers_in and are set even before
> > PerlPostReadRequest. So, have a close look at your code. If that
> > doesn't help try to create a test case as simple as you can and
> > post it to the list.
>
> Not as per this:
> http://perl.apache.org/docs/2.0/api/Apache2/RequestRec.html# C_headers
>_in_

Then the documentation is wrong. (Perhaps is was that way with mp1?) Try
this one:

PerlPostReadRequestHandler "sub { \
my ($r)=@_; \
warn qq{Got Cookie: }.$r->headers_in->{Cookie}; \
return Apache2::Const::DECLINED; \
}"

and then

curl -b hugo=otto http://localhost/

You'll see something like the line below in your error_log:

Got Cookie: hugo=otto at (eval 91) line 1.

Torsten

--
Need professional mod_perl support?
Just hire me: torsten.foertsch@gmx.net

Re: Mod Perl 2.0 HTTP Handlers

am 02.11.2008 13:25:17 von torsten.foertsch

On Sun 02 Nov 2008, Torsten Foertsch wrote:
> On Sun 02 Nov 2008, Puneet Lakhina wrote:
> > > Input headers are found in $r->headers_in and are set even before
> > > PerlPostReadRequest. So, have a close look at your code. If that
> > > doesn't help try to create a test case as simple as you can and
> > > post it to the list.
> >
> > Not as per this:
> > http://perl.apache.org/docs/2.0/api/Apache2/RequestRec.html# C_heade
> >rs _in_
>
> Then the documentation is wrong.

To show you that that is not an modperl-thing but implemented that way
in apache, let's have a look at the ultimate docs. In
httpd-2.x.y/server/protocol.c you'll find the ap_read_request function.
It reads in a request, finds the virtual host that handles the request
and calls PostReadRequest handlers. It is a bit lengthy. So I have
removed the unnecessary for the problem stuff and put in a few
comments:

request_rec *ap_read_request(conn_rec *conn)
{
....
r->headers_in = apr_table_make(r->pool, 25);

Here $r->headers_in is created as an empty table.

/* Get the request... */
if (!read_request_line(r, tmp_bb)) {

This reads the first request line, something like "GET / HTTP/1.1"

if (!r->assbackwards) {
ap_get_mime_headers_core(r, tmp_bb);

And this line reads in the headers and populates $r->headers_in.

if (apr_table_get(r->headers_in, "Transfer-Encoding")
&& apr_table_get(r->headers_in, "Content-Length")) {

You see, even the function itself uses $r->headers_in.

ap_update_vhost_from_headers(r);

Another example of $r->headers_in usage. Here the correct
NamedVirtualHost is found. This function needs the Host request header.

if ((access_status = ap_run_post_read_request(r))) {

And here a PerlPostReadRequestHandler is called.

....
}


Torsten

--
Need professional mod_perl support?
Just hire me: torsten.foertsch@gmx.net

Re: Mod Perl 2.0 HTTP Handlers

am 02.11.2008 14:20:39 von Puneet Lakhina

>> Then the documentation is wrong.
Yeah I ran it with PerlTransHandler. It works. So the documentation is
indeed misleading. Thanks for taking time to give such detailed
explanation.

One more question, is it possible for me to ensure that my module/or
essenially mod_perl's processing of the URI translation happens before
mod_rewrite or any other similar modules, and essentially
mod_rewrite's rules work on the URI modified by me.

Thanks again.

--
Regards,
Puneet

Re: Mod Perl 2.0 HTTP Handlers

am 02.11.2008 14:59:33 von torsten.foertsch

On Sun 02 Nov 2008, Puneet Lakhina wrote:
> One more question, is it possible for me to ensure that my module/or
> essenially mod_perl's processing of the URI translation happens
> before mod_rewrite or any other similar modules, and essentially
> mod_rewrite's rules work on the URI modified by me.

That order is defined by the 4th parameter to ap_hook_translate_name().

mod_rewrite calls it as:

ap_hook_translate_name(hook_uri2file, NULL, NULL, APR_HOOK_FIRST);

and mod_perl as:

ap_hook_trans(modperl_trans_handler, NULL, NULL, APR_HOOK_REALLY_FIRST);

APR_HOOK_FIRST and APR_HOOK_REALLY_FIRST are integer numbers. Hence, you
can write APR_HOOK_REALLY_FIRST-42 or so.

The actual definitions can be found in
srclib/apr-util/include/apr_hooks.h:

/** run this hook first, before ANYTHING */
#define APR_HOOK_REALLY_FIRST (-10)
/** run this hook first */
#define APR_HOOK_FIRST 0
/** run this hook somewhere */
#define APR_HOOK_MIDDLE 10
/** run this hook after every other hook which is defined*/
#define APR_HOOK_LAST 20
/** run this hook last, after EVERYTHING */
#define APR_HOOK_REALLY_LAST 30

So, a PerlTransHandler is always called before the mod_rewrite
translation handler since APR_HOOK_REALLY_FIRST is less than
APR_HOOK_FIRST. The only way to change that is to patch and recompile
one of the modules.

Torsten

--
Need professional mod_perl support?
Just hire me: torsten.foertsch@gmx.net