httpd-apreq-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Gavin <>
Subject hard_timeout in $apr->parse
Date Tue, 23 Feb 2010 00:25:50 GMT
We work with mobile phone networks, and sometimes the providers networks can
be very slow. A user does a post (simple, or file upload) which hits out
timeout length and fails. When this happens, because APR does a
hard_timeout, it jumps(longjmp) back to apache and not clearing the perl
callstack. ( for
reference from the mod_perl lists from back in august 2000)

This isn't entirely an issue, except perl eventually detects this as
infinite recursion in much later requests and dies.

I'm providing a test case and a possible solution, but I'm not really
familiar with the internals of apreq, so I don't know if there is a better
way to handle this, or implement it, but so far from our initial tests it
all works properly.

Sample Script: (
Essentially our apache servers have a "Timeout 30" set, and the networks are
taking more than 30 seconds to come in.

This script is setup to take a 5 second pause (we updated the timeout for
testing) before finishing the request.

When running this script on a very basic handler:
213  sub handler {
214     my $r = Apache::Request->new(shift);
215     print STDERR Carp::longmess("before parse")
216     my $status = $r->parse;
218     if ($status)
219     {
220         my $errmsg = $r->notes("error-notes");
221         print STDERR "Error parsing request: $errmsg && $status\n";
222         die("Error parsing request: $errmsg");
223     }

Leads to:
        eval {...} called at /home/main/ line 216
        WAP::Platform::handler('Apache=SCALAR(0x11b485a0)') called at
/home/main/ line 216
        eval {...} called at /home/main/ line 216
        WAP::Platform::handler('Apache=SCALAR(0x11b48330)') called at
/home/main/ line 216
        eval {...} called at /home/main/ line 216
        WAP::Platform::handler('Apache=SCALAR(0x11b4821c)') called at
/home/main/ line 216

and so on.

My Solution:
1) Search and replace any hard_timeout with soft_timeout
2) Recompile and install
3) Update code to check $r->connection->aborted, ie:
    my $status = $r->parse;
    unless ($status == OK) {
        $r->custom_response($status, $r->notes("error-notes"));
        die $r->notes("error-notes");
        return $status;

    if ($r->connection->aborted)
        $r->status(408); # Timeout error message
        return Apache::Constants::OK;

View raw message