You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by Puneet Lakhina <pu...@cs.ucsb.edu> on 2008/11/02 11:11:54 UTC

Mod Perl 2.0 HTTP Handlers

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

Posted by Torsten Foertsch <to...@gmx.net>.
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

Re: Mod Perl 2.0 HTTP Handlers

Posted by Puneet Lakhina <pu...@cs.ucsb.edu>.
>> 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

Posted by Torsten Foertsch <to...@gmx.net>.
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

Posted by Torsten Foertsch <to...@gmx.net>.
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

Posted by Puneet Lakhina <pu...@cs.ucsb.edu>.
> 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

Posted by Torsten Foertsch <to...@gmx.net>.
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