]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
Merge r291452, r291454 from trunk:
authorJoe Orton <jorton@apache.org>
Sun, 25 Sep 2005 20:16:00 +0000 (20:16 +0000)
committerJoe Orton <jorton@apache.org>
Sun, 25 Sep 2005 20:16:00 +0000 (20:16 +0000)
* 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.

* server/connection.c (ap_lingering_close): Cleanup; no functional change.

PR: 35292

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@291469 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
server/connection.c

diff --git a/CHANGES b/CHANGES
index 4fcdcfee5a09f07afa4606fcc87c16d824401a02..42eccb371af2c4ed4a049a1e672c10c0ff6a3e86 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,9 @@
                                                         -*- coding: utf-8 -*-
 Changes with Apache 2.1.8
 
+  *) Fix lingering close implementation to match 1.3.x behaviour.
+     PR 35292.  [Joe Orton]
+
   *) mod_ssl: Support limited buffering of request bodies to allow 
      per-location renegotiation to proceed.  PR 12355.  [Joe Orton]
 
index 9f5949791005dea5a7019e668a641e838fbac3e0..751892f486be1e097c6a2ba132eb3d698d5458e6 100644 (file)
@@ -98,10 +98,8 @@ AP_CORE_DECLARE(void) ap_flush_conn(conn_rec *c)
 AP_DECLARE(void) ap_lingering_close(conn_rec *c)
 {
     char dummybuf[512];
-    apr_size_t nbytes = sizeof(dummybuf);
-    apr_status_t rc;
-    apr_int32_t timeout;
-    apr_int32_t total_linger_time = 0;
+    apr_size_t nbytes;
+    apr_time_t timeup = 0;
     apr_socket_t *csd = ap_get_module_config(c->conn_config, &core_module);
 
     if (!csd) {
@@ -138,25 +136,29 @@ 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_timeout_set(csd, apr_time_from_sec(SECONDS_TO_LINGER));
     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)
+        if (apr_socket_recv(csd, dummybuf, &nbytes) || 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;