httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Graham Dumpleton" <graham.dumple...@gmail.com>
Subject Where is Timeout configuration directive value stored?
Date Sat, 17 Nov 2007 05:02:32 GMT
The function in server/core.c called for the Timeout directive is:

static const char *set_timeout(cmd_parms *cmd, void *dummy, const char *arg)
{
    const char *err = ap_check_cmd_context(cmd,
NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT);

    if (err != NULL) {
        return err;
    }

    cmd->server->timeout = apr_time_from_sec(atoi(arg));
    return NULL;
}

Ie., the Timeout directive value is stored in 'timeout' parameter of
the 'server_rec' for host context that directive appears in.

Presumably, the Timeout directive in global part of Apache
configuration would result in that being put in server_rec for main
server context.

When ap_fixup_virtual_hosts() is later run, presumably that is then
copied into vhost server_rec presuming that a vhost didn't contain its
own Timeout directive setting. Ie., that function contains:

        if (virt->timeout == 0)
            virt->timeout = main_server->timeout;

Based on that I am presuming that if either r->server-timeout or
r->connection->base_server->timeout is accessed, they should have a
non zero value corresponding to what the Timeout directive was being
set to, or the default of 300 seconds if not set, but that isn't want
I am seeing in my own handler code and instead 'timeout' is 0.

I am a bit confused at this point as mod_cgi uses:

                apr_file_pipe_timeout_set(*script_out, r->server->timeout);

but if r->server->timeout is 0, then a write would return straight
away if it blocked instead of waiting default of 300 seconds.

What am I missing? I have seen this on Apache 2.2.4 and 2.2.6 on two
different Mac OS X systems.

BTW, a long time ago, either here on modules-dev, I queried about code
in mod_cgid and whether it was correct, namely it says:

            /* Keep writing data to the child until done or too much time
             * elapses with no progress or an error occurs.
             */
            rv = apr_file_write_full(tempsock, data, len, NULL);

My concern was that this wouldn't actually ever timeout as tempsock
never had a timeout value set for it. I never got an answer at the
time

In some code I modeled on how mod_cgid was working, am now seeing
problems which suggests that not only is mod_cgid possibly broken in
not having a timeout, but one can actually deadlock the whole CGI
process and the thread in the Apache child.

I'll admit that my own code doesn't exactly mirror how the cgid
process launcher works, but the issue I see is that if a request has
POST content which is greater in size than the socket buffers can
hold, and a CGI script doesn't consume the POST content before sending
a response, also greater than the socket buffer sizes, then
cgid_handler() can block indefinitely in apr_file_write_full().

This will occur because the CGI process will in turn be blocked in
trying to send its response. It can't return until some data is read
by cgid_handler() in Apache child process, that can't happen as
reading response is only done after the POST content is sent by calls
to apr_file_write_full(). Because a 'timeout' wasn't set on tempsock
though, it will also never actually return, even after default 300
seconds, and will just deadlock.

Now, in comparing mod_cgi to mod_cgid, in mod_cgi it does make call to
set timeout on the pipe for forked process, but as shown above it uses
r->server->timeout, which keeps showing as 0 for me in my own handler
code.

Anyone like to comment on whether my analysis is correct so as to help
me understand the code and determine if mod_cgi and/or mod_cgid is
broken?

BTW, using a simple test CGI script which returns 16Kb response
without consuming POST content, and using POST with 16Kb of data
against it, I have now duplicated with CGI module what I was seeing in
my own code. Namely, the CGI script and Apache child process thread
both block indefinitely, not even recovering after timeout specified
by Timeout directive. My server for this test was configured with
static mod_cgid module.

Graham

Mime
View raw message