httpd-modules-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Frank Meier <frank_me...@datacomm.ch>
Subject handling client abort instantly?
Date Mon, 02 Mar 2009 08:19:27 GMT
Hi
I'm working with a proprietary apache module which communicates (through
a socket) with another backend application (I have the C source code of
the module). I've now found out, when the client closes the http
connection during a request, the module does not "see" that the client
has disconnected. In some cases the request is just finished, but with
larger requests (larger amount of data from backend), the module keeps 
hanging in the ap_rwrite() or ap_rflush() function. This is only 
resolved if a timeout (default 300s, timeout directive in httpd.conf) 
occurs. I think the tx-buffer of the socket is filled and then the
write/flush function blocks.

I've read in "the Apache Modules Book" (p.138) that we can detect the
disconnection by checking r->connection->aborted. The problem is, this
is only set when the timeout occurs.

What is the nice/right way to go, if I like to abort
instantly my request when the client has closed the connection? I'm
reluctant to decrease the apache timeout directive to very low value,
because I don't know about side effects and It would be not a nice solution.

ApacheVersion: 2.2.9
OS: Solaris10

pseudocode:
while (notFinished)
{
        do
        {
            int received=readDataFromBackend(buf);

            result = ap_rwrite(buf, received, r);
            if (result <= 0 || r->connection->aborted)
            {
                ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0,  r,
                        "PID %d: Cannot write data to client, returning
%d (errno = %d), aborted:%d", getpid(), result, errno,
r->connection->aborted);
                return HTTP_INTERNAL_SERVER_ERROR;
            }

        } while (moreDataFromBackend);

        int result = ap_rflush(r);
        if (result < 0 || r->connection->aborted)
        {
            ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0,  r,
                    "PID %d: Response chunk flush failed, returning %d
(errno = %d), aborted:%d", getpid(), result, errno, r->connection->aborted);
            return HTTP_INTERNAL_SERVER_ERROR;
        }
    }


thanks for help, Frank



Mime
View raw message