From f5129aa30a31517b66dac3706430903c7b04a895 Mon Sep 17 00:00:00 2001 From: Bill Stoddard Date: Wed, 14 Feb 2001 21:05:36 +0000 Subject: [PATCH] Fix lingering close (and make it more efficient). We were blocking on apr_read() for 30 seconds for each lingering close. What we want to do is block for 2 seconds. If we do not read any bytes from the client in that time, close the connection. If we do read bytes, then wait 2 more seconds to see if more arrive, etc. Repeat for MAX_SECS_TO_LINGER if needed. This should clear the way to get 2.0 running on apache.org! git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@88167 13f79535-47bb-0310-9956-ffa450edef68 --- server/connection.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/server/connection.c b/server/connection.c index 6b69711822..703c600c3f 100644 --- a/server/connection.c +++ b/server/connection.c @@ -148,14 +148,14 @@ AP_CORE_DECLARE(void) ap_flush_conn(conn_rec *c) * TCP RST packets to be sent which can tear down a connection before * all the response data has been sent to the client. */ - +#define SECONDS_TO_LINGER 2 void ap_lingering_close(conn_rec *c) { char dummybuf[512]; - apr_time_t start; - apr_size_t nbytes; + apr_size_t nbytes = sizeof(dummybuf); apr_status_t rc; - int timeout; + apr_int32_t timeout; + apr_int32_t total_linger_time = 0; #ifdef NO_LINGCLOSE ap_flush_conn(c); /* just close it */ @@ -187,23 +187,21 @@ void ap_lingering_close(conn_rec *c) } /* Read all data from the peer until we reach "end-of-file" (FIN - * from peer) or we've exceeded our overall timeout. + * from peer) or we've exceeded our overall timeout. If the client does + * not send us bytes within 2 seconds (a value pulled from Apache 1.3 + * which seems to work well), close the connection. */ - - start = apr_time_now(); - timeout = MAX_SECS_TO_LINGER * APR_USEC_PER_SEC; + timeout = SECONDS_TO_LINGER * APR_USEC_PER_SEC; for (;;) { apr_setsocketopt(c->client_socket, APR_SO_TIMEOUT, timeout); nbytes = sizeof(dummybuf); rc = apr_recv(c->client_socket, dummybuf, &nbytes); if (rc != APR_SUCCESS || nbytes == 0) break; - /* how much time has elapsed? */ - timeout = (int)((apr_time_now() - start) / APR_USEC_PER_SEC); - if (timeout >= MAX_SECS_TO_LINGER) break; - - /* figure out the new timeout */ - timeout = (int)((MAX_SECS_TO_LINGER - timeout) * APR_USEC_PER_SEC); + total_linger_time += SECONDS_TO_LINGER; + if (total_linger_time >= MAX_SECS_TO_LINGER) { + break; + } } apr_socket_close(c->client_socket); -- 2.40.0