You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by yl...@apache.org on 2015/10/22 23:19:52 UTC

svn commit: r1710105 - in /httpd/httpd/trunk: docs/log-message-tags/next-number modules/http/http_request.c

Author: ylavic
Date: Thu Oct 22 21:19:52 2015
New Revision: 1710105

URL: http://svn.apache.org/viewvc?rev=1710105&view=rev
Log:
core: follow up to r1710095.
Simplify logic in check_pipeline(), and log unexpected errors.

Modified:
    httpd/httpd/trunk/docs/log-message-tags/next-number
    httpd/httpd/trunk/modules/http/http_request.c

Modified: httpd/httpd/trunk/docs/log-message-tags/next-number
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/log-message-tags/next-number?rev=1710105&r1=1710104&r2=1710105&view=diff
==============================================================================
--- httpd/httpd/trunk/docs/log-message-tags/next-number (original)
+++ httpd/httpd/trunk/docs/log-message-tags/next-number Thu Oct 22 21:19:52 2015
@@ -1 +1 @@
-2967
+2969

Modified: httpd/httpd/trunk/modules/http/http_request.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http/http_request.c?rev=1710105&r1=1710104&r2=1710105&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http/http_request.c (original)
+++ httpd/httpd/trunk/modules/http/http_request.c Thu Oct 22 21:19:52 2015
@@ -234,20 +234,25 @@ static void check_pipeline(conn_rec *c,
     if (c->keepalive != AP_CONN_CLOSE && !c->aborted) {
         apr_status_t rv;
         int num_blank_lines = DEFAULT_LIMIT_BLANK_LINES;
-        char buf[2], cr = 0;
-        apr_size_t len;
+        ap_input_mode_t mode = AP_MODE_SPECULATIVE;
+        apr_size_t len, cr = 0;
+        char buf[2];
 
         do {
-            const apr_size_t n = (cr) ? 2 : 1;
-
             apr_brigade_cleanup(bb);
-            rv = ap_get_brigade(c->input_filters, bb, AP_MODE_SPECULATIVE,
-                                APR_NONBLOCK_READ, n);
+            rv = ap_get_brigade(c->input_filters, bb, mode,
+                                APR_NONBLOCK_READ, cr + 1);
             if (rv != APR_SUCCESS || APR_BRIGADE_EMPTY(bb)) {
                 /*
                  * Error or empty brigade: There is no data present in the input
                  * filter
                  */
+                if (mode == AP_MODE_READBYTES) {
+                    /* Unexpected error, stop with this connection */
+                    ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c, APLOGNO(02967)
+                                  "Can't consume pipelined empty lines");
+                    c->keepalive = AP_CONN_CLOSE;
+                }
                 return;
             }
 
@@ -257,52 +262,54 @@ static void check_pipeline(conn_rec *c,
              * pending response(s) until the next/real request comes in or the
              * keepalive timeout expires.
              */
-            len = n;
+            len = cr + 1;
             rv = apr_brigade_flatten(bb, buf, &len);
-            if (rv != APR_SUCCESS || len != n) {
-                ap_log_cerror(APLOG_MARK, APLOG_DEBUG, rv, c,
-                              "check pipeline can't fetch CRLF "
-                              "(%" APR_SIZE_T_FMT "/%" APR_SIZE_T_FMT ")",
-                              len, n);
-                c->data_in_input_filters = 1;
+            if (rv != APR_SUCCESS || len != cr + 1) {
+                int level;
+                if (mode == AP_MODE_READBYTES) {
+                    /* Unexpected error, stop with this connection */
+                    c->keepalive = AP_CONN_CLOSE;
+                    level = APLOG_ERR;
+                }
+                else {
+                    /* Let outside (non-speculative/blocking) read determine
+                     * where this possible failure comes from (metadata,
+                     * morphed EOF socket => empty bucket? debug only here).
+                     */
+                    c->data_in_input_filters = 1;
+                    level = APLOG_DEBUG;
+                }
+                ap_log_cerror(APLOG_MARK, level, rv, c, APLOGNO(02968)
+                              "Can't check pipelined data");
                 return;
             }
+
+            if (mode == AP_MODE_READBYTES) {
+                mode = AP_MODE_SPECULATIVE;
+                cr = 0;
+                continue;
+            }
+
             if (cr) {
                 AP_DEBUG_ASSERT(len == 2 && buf[0] == APR_ASCII_CR);
                 if (buf[1] != APR_ASCII_LF) {
                     return;
                 }
+                mode = AP_MODE_READBYTES;
                 num_blank_lines--;
-                cr = 0;
             }
             else {
                 if (buf[0] == APR_ASCII_CR) {
                     cr = 1;
                 }
                 else if (buf[0] == APR_ASCII_LF) {
+                    mode = AP_MODE_READBYTES;
                     num_blank_lines--;
                 }
                 else {
                     c->data_in_input_filters = 1;
                     return;
                 }
-            }
-            if (!cr) {
-                /* Consume this [CR]LF, then next */
-                apr_brigade_cleanup(bb);
-                rv = ap_get_brigade(c->input_filters, bb, AP_MODE_READBYTES,
-                                    APR_NONBLOCK_READ, n);
-                if (rv == APR_SUCCESS) {
-                    rv = apr_brigade_flatten(bb, buf, &len);
-                }
-                if (rv != APR_SUCCESS || len != n) {
-                    ap_log_cerror(APLOG_MARK, APLOG_DEBUG, rv, c,
-                                  "check pipeline can't read CRLF "
-                                  "(%" APR_SIZE_T_FMT "/%" APR_SIZE_T_FMT ")",
-                                  len, n);
-                    c->data_in_input_filters = 1;
-                    return;
-                }
             }
         } while (num_blank_lines >= 0);