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 Re: handling client abort instantly?
Date Thu, 05 Mar 2009 12:58:39 GMT
Saju Pillai wrote:
> Frank Meier wrote:
>> 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 think if the client has gone away while httpd is trying to write() 
> to it, httpd will immediately error out - probably with a "Broken 
> Pipe" error.
>
> Even if your socket write buffer is filled, the actual attempt to 
> write() by your tcp stack must raise an error.
>
> Maybe I am not understanding the problem properly. If the tcp 
> connection is broken, attempts to read() or write() on that connection 
> should flag a detectable error. It maybe possible that httpd is 
> waiting too long to perform a write() and doesn't figure out fast 
> enough that the remote end has gone away.
>
> I can think of a *hack* to determine if the client has really gone away.
> In your module you can possibly do
>
> client = ap_filter_t->ctx->client_socket /* ap_filter_t is either the 
> input or output filter stack */
>
> to get the apr client socket. You can try do a 0-byte read() on this 
> socket to see if you get an error. An error means the remote side has 
> gone away. I have not tested this, I don't know if this will work for 
> you.
>
>
>
> srp

thanks for your replies, I tried the use of bucketbrigades as Chris 
Kukuchka suggested. Unfortunately this lead  to the same behaviour.

I also tried the *hack* approach (accessing the socket directly), where 
I had the problem of getting to the socket itself. I didn't understand 
how I could use ap_filter_t->ctx since I don't know what is stored 
there, but I used "ap_get_module_config" which should also get me to the 
socket. right?

struct apr_socket_t *client_socket = 
ap_get_module_config(r->connection->conn_config, &core_module);
int rv = read(client_socket->socketdes, dummyBuf, len);

but rv is always 0 (if len is 0) / -1 (if len > 0) and errno is 2 (No 
such file or directory)

 > I think if the client has gone away while httpd is trying to write() 
to it, httpd will immediately error out - probably with a "Broken Pipe" 
error.
that IS what I ought to think too :-)

I think my next step is to implement a test module myself to verify this 
strange behaviour and also test it on another OS (linux) since Solaris 
sometimes does strange things.

thanks anyway, Frank


Mime
View raw message