httpd-apreq-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Michael McLagan <mmcla...@invlogic.com>
Subject Subrequest after discard_request_body trashes POST params!!
Date Tue, 27 Dec 2005 21:38:00 GMT
Hello,

    I'm running into a bit of confusion between the results I'm getting and
what the docs on the web site read, specifically:

> parse
> 
>     $req->parse()
> 
> Forces the request to be parsed immediately. In void context, this will throw an APR::Request::Error
should the either the query-string or body parser fail. In all other contexts it will return
the two parsers' combined APR status code
> 
>     $req->body_status || $req->args_status
> 
> However parse should be avoided in most normal situations. For example, in a mod_perl
content handler it is more efficient to write
> 
>     sub handler {
>         my $r = shift;
>         my $req = Apache2::Request->new($r);
>         $r->discard_request_body;   # efficiently parses the request body
>         my $parser_status = $req->body_status;
> 
>         #...
>     }
> 
> Calling $r->discard_request_body outside the content handler is generally a mistake,
so use $req->parse there, but only as a last resort. The Apache2::Request API is designed
around a lazy-parsing scheme, so calling parse should not affect the behavior of any other
methods.

The results of which are "Not Good!(tm)", or so it seems.  I reduced it to a very
example of what's going on, which I'm going to C&P here so you can look at it.  The
basic problem is if that suggestion is followed, the POST parameters get lost when
you issue a subrequest!!

As I read the docs, issuing the discard should slurp in the rest of the params and
hold them for the duration of this request.  I put some debugging statements into
the little package I made up and this is what I get out:

> [Tue Dec 27 16:13:52 2005] [notice] Apache/2.2.0 (Fedora) configured -- resuming normal
operations
> n1: list: d, e, f, A, B, C, submit
> n2: list: d, e, f
> n3: list: d, e, f
> n4: list: d, e, f

It matters little if I call discard_request_body on '_request' or '_query'.  The result
is always the same.  When I comment out the call in the handler so that it is never called,
I get what I suspect is the expected overall behavior:

> [Tue Dec 27 16:10:04 2005] [notice] Apache/2.2.0 (Fedora) configured -- resuming normal
operations
> n1: list: d, e, f, A, B, C, submit
> n2: list: d, e, f, A, B, C, submit
> n3: list: d, e, f, A, B, C, submit
> n4: list: d, e, f, A, B, C, submit

If I've missed something, please let me know.  My purpose in calling that routine is to
make sure that there's no leftovers from one request to another on KeepAlive (persistant)
connections.  If that's unnecessary in Apache2/ModPerl2/libapreq2 then I'll drop the
method call and we'll call it a day.  :)

Thanks again,

    Michael

This is what .htaccess in / says:

> PerlModule Test::HndlAdmin
> <Files "test.html">
>    PerlResponseHandler Test::HndlAdmin virtual
>    SetHandler  perl-script
> </Files>

Coupled with this package:

> package Test::HndlAdmin;
> 
> use Apache2::Request;
> use Apache2::Const;
> 
> sub handler 
> {
>    my ($request) = shift;
> 
>    my $self = bless({}, __PACKAGE__);
> 
>    $self->{'_request'} = $request;
>    $self->{'_query'} = Apache2::Request->new($self->{'_request'});
> 
>    $self->{'_query'}->discard_request_body;
>    $self->{'_request'}->content_type('text/html');
> 
>    my $sub = $self->{'_request'}->lookup_uri('/header.html');
> 
> print STDERR "n1: list: " . join(', ', keys(%{scalar $self->{'_query'}->param}))
. "\n";
> 
>    $sub->run;
> 
> print STDERR "n2: list: " . join(', ', keys(%{scalar $self->{'_query'}->param}))
. "\n";
> 
> print '<FORM METHOD=POST ACTION="/test.html?d=5&e=113&f=69">';
> print '<INPUT TYPE=HIDDEN NAME="A" VALUE=7>';
> 
> print '<INPUT TYPE=HIDDEN NAME="B" VALUE=-4>';
> print '<INPUT TYPE=HIDDEN NAME="C" VALUE=12>';
> print '<INPUT TYPE=SUBMIT NAME="submit" VALUE="submit">';
> print '</FORM>';
> 
>    my $sub = $self->{'_request'}->lookup_uri('/footer.html');
> 
> print STDERR "n3: list: " . join(', ', keys(%{scalar $self->{'_query'}->param}))
. "\n";
> 
>    $sub->run;
> 
> print STDERR "n4: list: " . join(', ', keys(%{scalar $self->{'_query'}->param}))
. "\n";
> 
>    return Apache2::Const::OK;
> }
> 
> 1;

The header.html and footer.html files contain only a <BODY> & </BODY> tag
respectively.
My tests here show it doesn't much matter what you put in those two files  I tried simple
SGML comment in each to our main site's rather extensive mod_including calling files.

Mime
View raw message