On Thu, Apr 28, 2016 at 11:37 AM, Yann Ylavic <[email protected]> wrote:
>
> OK, so the worker scoreboard entry is up to date with the latest
> connection/request handled.
> Now let's consider the case in KEEAPALIVE state where a new request
> arrives (possibly on another connection for mpm_event), or in
> READY/closed state (for any MPM) where a new connection+request is
> handled by the same worker.
>
> When we transition to READ just before calling ap_read_request(), we
> update the client IP in the scoreboard, but keep the request line
> (from the previous request) untouched, mixed data...
> For mpm_event this is a very transient state since the worker was
> scheduled only because the connection is POLLIN ready, so
> ap_read_request() won't block.
> For mpm_worker though, this may last KeepAliveTimeout.
> Moreover for both MPMs, if the connection is closed by the client the
> worker score will stay as is until next (real) request is read on
> another connection, or for mpm worker if keepalive expires the request
> line will be set to the value NULL (unless patch below is applied).
> That's what is observed in PR 59333, and I don't see where your commit
> change this.
> We need to either accept/document mixing, or blank the request line
> (but it will be very noticeable by users as it is already in 2.4.20),
> or restore the latest request line (and vhost) on the connection
> (hence also store it by connection, in conn_rec).

So maybe for 2.4.x we could add the following to you commit:

Index: modules/http/http_core.c
===================================================================
--- modules/http/http_core.c    (revision 1741396)
+++ modules/http/http_core.c    (working copy)
@@ -141,8 +141,15 @@ static int ap_process_http_async_connection(conn_r
     AP_DEBUG_ASSERT(cs->state == CONN_STATE_READ_REQUEST_LINE);

     while (cs->state == CONN_STATE_READ_REQUEST_LINE) {
-        ap_update_child_status_from_conn(c->sbh, SERVER_BUSY_READ, c);
+        worker_score *ws = ap_get_scoreboard_worker(c->sbh);

+        if (ws->client[0]) {
+            ap_update_child_status(c->sbh, SERVER_BUSY_READ, NULL);
+        }
+        else {
+            ap_update_child_status_from_conn(c->sbh, SERVER_BUSY_READ, c);
+        }
+
         if ((r = ap_read_request(c))) {

             c->keepalive = AP_CONN_UNKNOWN;
@@ -182,13 +189,20 @@ static int ap_process_http_sync_connection(conn_re
     conn_state_t *cs = c->cs;
     apr_socket_t *csd = NULL;
     int mpm_state = 0;
+    worker_score *ws = ap_get_scoreboard_worker(c->sbh);

+    if (ws->client[0]) {
+        ap_update_child_status(c->sbh, SERVER_BUSY_READ, NULL);
+    }
+    else {
+        ap_update_child_status_from_conn(c->sbh, SERVER_BUSY_READ, c);
+    }
+
     /*
      * Read and process each request found on our connection
      * until no requests are left or we decide to close.
      */

-    ap_update_child_status_from_conn(c->sbh, SERVER_BUSY_READ, c);
     while ((r = ap_read_request(c)) != NULL) {
         apr_interval_time_t keep_alive_timeout = r->server->keep_alive_timeout;

Index: server/protocol.c
===================================================================
--- server/protocol.c    (revision 1741396)
+++ server/protocol.c    (working copy)
@@ -1093,13 +1093,14 @@ request_rec *ap_read_request(conn_rec *conn)
             access_status = r->status;
             r->status = HTTP_OK;
             ap_die(access_status, r);
-            ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r);
+            if (r->the_request && r->the_request[0]) {
+                ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r);
+            }
             ap_run_log_transaction(r);
             r = NULL;
             apr_brigade_destroy(tmp_bb);
             goto traceout;
         case HTTP_REQUEST_TIME_OUT:
-            ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r);
             if (!r->connection->keepalives)
                 ap_run_log_transaction(r);
             apr_brigade_destroy(tmp_bb);
_

Such that we don't update the client IP until a request line is read.
So we'd report WRITE + new-request for a request being handled, and
READ + old-request when waiting for a new request.

Reply via email to