On Fri, May 13, 2016 at 7:25 PM, Yann Ylavic <[email protected]> wrote:
> On Fri, May 13, 2016 at 6:57 PM, Yann Ylavic <[email protected]> wrote:
>>
>> But for the above cases or an error while reading/validating the
>> headers or running post_read_request(), we finally call ap_die() or
>> ap_send_error_response().
>> I think we should report SERVER_BUSY_WRITE with r before those calls,
>> and use NULL for SERVER_BUSY_LOG.
>
> For the REQUEST_TIME_OUT case, we may need something like the below too.
> The goal would be to answer something to the client (408) if the
> timeout occurs with some request line byte(s) received (that an
> invalid request but still a request), and report the r (even "NULL"
> for the first empty request on the connection).

Just to be clear, full proposed patch (including yours) attached.
Index: modules/http/http_core.c
===================================================================
--- modules/http/http_core.c	(revision 1743265)
+++ modules/http/http_core.c	(working copy)
@@ -148,10 +148,9 @@ static int ap_process_http_async_connection(conn_r
             c->keepalive = AP_CONN_UNKNOWN;
             /* process the request if it was read without error */
 
-            ap_update_child_status(c->sbh, SERVER_BUSY_WRITE,
-                                   r->the_request ? r : NULL);
             if (r->status == HTTP_OK) {
                 cs->state = CONN_STATE_HANDLER;
+                ap_update_child_status(c->sbh, SERVER_BUSY_WRITE, r);
                 ap_process_async_request(r);
                 /* After the call to ap_process_request, the
                  * request pool may have been deleted.  We set
@@ -204,11 +203,10 @@ static int ap_process_http_sync_connection(conn_re
         c->keepalive = AP_CONN_UNKNOWN;
         /* process the request if it was read without error */
 
-        ap_update_child_status(c->sbh, SERVER_BUSY_WRITE,
-                               r->the_request ? r : NULL);
         if (r->status == HTTP_OK) {
             if (cs)
                 cs->state = CONN_STATE_HANDLER;
+            ap_update_child_status(c->sbh, SERVER_BUSY_WRITE, r);
             ap_process_request(r);
             /* After the call to ap_process_request, the
              * request pool will have been deleted.  We set
Index: server/protocol.c
===================================================================
--- server/protocol.c	(revision 1743265)
+++ server/protocol.c	(working copy)
@@ -1090,20 +1090,34 @@ request_rec *ap_read_request(conn_rec *conn)
                 ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(00566)
                               "request failed: invalid characters in URI");
             }
+            ap_update_child_status(conn->sbh, SERVER_BUSY_WRITE, r);
             access_status = r->status;
             r->status = HTTP_OK;
             ap_die(access_status, r);
-            ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r);
+            ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, NULL);
             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, NULL);
-            if (!r->connection->keepalives)
+            if (r->the_request || !r->connection->keepalives) {
+                request_rec *log_r = r;
+                ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO()
+                              "request failed: client's request-line timed out");
+                if (r->the_request) {
+                    ap_update_child_status(conn->sbh, SERVER_BUSY_WRITE, r);
+                    access_status = r->status;
+                    r->status = HTTP_OK;
+                    ap_die(access_status, r);
+                    log_r = NULL;
+                }
+                ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, log_r);
                 ap_run_log_transaction(r);
-            apr_brigade_destroy(tmp_bb);
-            goto traceout;
+                r = NULL;
+                apr_brigade_destroy(tmp_bb);
+                goto traceout;
+            }
+            /* fall through */
         default:
             apr_brigade_destroy(tmp_bb);
             r = NULL;
@@ -1129,8 +1143,9 @@ request_rec *ap_read_request(conn_rec *conn)
         if (r->status != HTTP_OK) {
             ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(00567)
                           "request failed: error reading the headers");
+            ap_update_child_status(conn->sbh, SERVER_BUSY_WRITE, r);
             ap_send_error_response(r, 0);
-            ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r);
+            ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, NULL);
             ap_run_log_transaction(r);
             apr_brigade_destroy(tmp_bb);
             goto traceout;
@@ -1151,8 +1166,9 @@ request_rec *ap_read_request(conn_rec *conn)
                               "(%s): %s", tenc, r->uri);
                 r->status = HTTP_BAD_REQUEST;
                 conn->keepalive = AP_CONN_CLOSE;
+                ap_update_child_status(conn->sbh, SERVER_BUSY_WRITE, r);
                 ap_send_error_response(r, 0);
-                ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r);
+                ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, NULL);
                 ap_run_log_transaction(r);
                 apr_brigade_destroy(tmp_bb);
                 goto traceout;
@@ -1179,8 +1195,9 @@ request_rec *ap_read_request(conn_rec *conn)
                           r->uri);
             r->header_only = 0;
             r->status = HTTP_BAD_REQUEST;
+            ap_update_child_status(conn->sbh, SERVER_BUSY_WRITE, r);
             ap_send_error_response(r, 0);
-            ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r);
+            ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, NULL);
             ap_run_log_transaction(r);
             apr_brigade_destroy(tmp_bb);
             goto traceout;
@@ -1234,8 +1251,9 @@ request_rec *ap_read_request(conn_rec *conn)
 
     if (access_status != HTTP_OK
         || (access_status = ap_run_post_read_request(r))) {
+        ap_update_child_status(conn->sbh, SERVER_BUSY_WRITE, r);
         ap_die(access_status, r);
-        ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r);
+        ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, NULL);
         ap_run_log_transaction(r);
         r = NULL;
         goto traceout;
@@ -1261,8 +1279,9 @@ request_rec *ap_read_request(conn_rec *conn)
                 ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(00570)
                               "client sent an unrecognized expectation value "
                               "of Expect: %s", expect);
+                ap_update_child_status(conn->sbh, SERVER_BUSY_WRITE, r);
                 ap_send_error_response(r, 0);
-                ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r);
+                ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, NULL);
                 ap_run_log_transaction(r);
                 goto traceout;
             } else {

Reply via email to