]> granicus.if.org Git - apache/commitdiff
mpm_event: close connections not reported as handled by any module.
authorYann Ylavic <ylavic@apache.org>
Wed, 20 Dec 2017 14:49:17 +0000 (14:49 +0000)
committerYann Ylavic <ylavic@apache.org>
Wed, 20 Dec 2017 14:49:17 +0000 (14:49 +0000)
This avoids losing track of them and leaking scoreboard entries.
PR 61551.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1818804 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
server/mpm/event/event.c

diff --git a/CHANGES b/CHANGES
index cf1d8c665092c731523a14938f79898bd709855e..b2bf5ab623fb03d059db0a0bbd3b9c005acc87b8 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,10 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.5.1
 
+  *) mpm_event: close connections not reported as handled by any module to
+     avoid losing track of them and leaking scoreboard entries.  PR 61551.
+     [Yann Ylavic]
+
   *) mod_dumpio: do nothing below log level TRACE7.  [Yann Ylavic]
 
   *) mod_md: reverses most of v1.0.5 optimization of post_config init, so that
index d57e771c7e7a72aec6d2c6901a09df4e24a8df58..cb730a3762834012dff525558fe34de9b08f67f7 100644 (file)
@@ -1049,20 +1049,30 @@ static void process_socket(apr_thread_t *thd, apr_pool_t * p, apr_socket_t * soc
          * otherwise write, should set the sense appropriately.
          */
         apr_atomic_inc32(&clogged_count);
-        ap_run_process_connection(c);
-        if (cs->pub.state != CONN_STATE_SUSPENDED) {
+        rc = ap_run_process_connection(c);
+        if (rc || cs->pub.state != CONN_STATE_SUSPENDED) {
             cs->pub.state = CONN_STATE_LINGER;
         }
         apr_atomic_dec32(&clogged_count);
     }
     else if (cs->pub.state == CONN_STATE_READ_REQUEST_LINE) {
 read_request:
-        ap_run_process_connection(c);
-
-        /* state will be updated upon return
-         * fall thru to either wait for readability/timeout or
-         * do lingering close
+        rc = ap_run_process_connection(c);
+
+        /* State will be updated upon successful return: fall thru to either
+         * wait for readability/timeout, do write completion or lingering
+         * close. But forcibly close the connection if the run failed (handler
+         * raised an error for it) or the state is something unexpected at the
+         * MPM level (meaning that no module handled it and we can't do much
+         * here; note that if a handler wants mpm_event to keep POLLIN for the
+         * rest of the request line it should use CHECK_REQUEST_LINE_READABLE
+         * and not simply return OK with the initial READ_REQUEST_LINE state).
          */
+        if (rc || (cs->pub.state != CONN_STATE_CHECK_REQUEST_LINE_READABLE
+                   && cs->pub.state != CONN_STATE_WRITE_COMPLETION
+                   && cs->pub.state != CONN_STATE_SUSPENDED)) {
+            cs->pub.state = CONN_STATE_LINGER;
+        }
     }
 
     if (cs->pub.state == CONN_STATE_WRITE_COMPLETION) {