From 18c24c857dcc7bb54bde154f4711530299c162f4 Mon Sep 17 00:00:00 2001 From: Joe Orton Date: Sun, 25 Sep 2005 18:00:43 +0000 Subject: [PATCH] * server/connection.c (ap_lingering_close): Fix lingering close to really match the 1.3 behaviour: read from the client for up to ~30 seconds in total. Current behaviour will attempt only 15 read() calls then give up. PR: 35292 git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@291452 13f79535-47bb-0310-9956-ffa450edef68 --- server/connection.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/server/connection.c b/server/connection.c index 9f59497910..11b499d69f 100644 --- a/server/connection.c +++ b/server/connection.c @@ -101,7 +101,7 @@ AP_DECLARE(void) ap_lingering_close(conn_rec *c) apr_size_t nbytes = sizeof(dummybuf); apr_status_t rc; apr_int32_t timeout; - apr_int32_t total_linger_time = 0; + apr_time_t timeup = 0; apr_socket_t *csd = ap_get_module_config(c->conn_config, &core_module); if (!csd) { @@ -138,25 +138,31 @@ AP_DECLARE(void) ap_lingering_close(conn_rec *c) return; } - /* Read all data from the peer until we reach "end-of-file" (FIN - * 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. + /* Read available data from the client whilst it continues sending + * it, for a maximum time of MAX_SECS_TO_LINGER. If the client + * does not send any data within 2 seconds (a value pulled from + * Apache 1.3 which seems to work well), give up. */ timeout = apr_time_from_sec(SECONDS_TO_LINGER); apr_socket_timeout_set(csd, timeout); apr_socket_opt_set(csd, APR_INCOMPLETE_READ, 1); - while (1) { + + /* The common path here is that the initial apr_socket_recv() call + * will return 0 bytes read; so that case must avoid the expensive + * apr_time_now() call and time arithmetic. */ + + do { nbytes = sizeof(dummybuf); rc = apr_socket_recv(csd, dummybuf, &nbytes); if (rc != APR_SUCCESS || nbytes == 0) break; - total_linger_time += SECONDS_TO_LINGER; - if (total_linger_time >= MAX_SECS_TO_LINGER) { - break; + if (timeup == 0) { + /* First time through; calculate now + 30 seconds. */ + timeup = apr_time_now() + apr_time_from_sec(MAX_SECS_TO_LINGER); + continue; } - } + } while (apr_time_now() < timeup); apr_socket_close(csd); return; -- 2.40.0