diff options
author | Yann Ylavic <ylavic@apache.org> | 2016-08-12 01:37:45 +0200 |
---|---|---|
committer | Yann Ylavic <ylavic@apache.org> | 2016-08-12 01:37:45 +0200 |
commit | 104ef73c959702fa80c7d7a2f1f23e92b3f8c351 (patch) | |
tree | 5de52fcca8b9fd2d3026267781ec3a4ba55d1d7e /modules/http | |
parent | http: follow up to r1750392. (diff) | |
download | apache2-104ef73c959702fa80c7d7a2f1f23e92b3f8c351.tar.xz apache2-104ef73c959702fa80c7d7a2f1f23e92b3f8c351.zip |
Revert r1756064 and r1756060 until fixed (tests framework passes).
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1756065 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'modules/http')
-rw-r--r-- | modules/http/http_request.c | 74 |
1 files changed, 25 insertions, 49 deletions
diff --git a/modules/http/http_request.c b/modules/http/http_request.c index 720eb0010c..ee50b4232a 100644 --- a/modules/http/http_request.c +++ b/modules/http/http_request.c @@ -229,45 +229,41 @@ AP_DECLARE(void) ap_die(int type, request_rec *r) ap_die_r(type, r, r->status); } -AP_DECLARE(apr_status_t) ap_check_pipeline(conn_rec *c, apr_bucket_brigade *bb, - unsigned int max_blank_lines) +static void check_pipeline(conn_rec *c, apr_bucket_brigade *bb) { - apr_status_t rv = APR_EOF; + apr_status_t rv; + int num_blank_lines = DEFAULT_LIMIT_BLANK_LINES; ap_input_mode_t mode = AP_MODE_SPECULATIVE; - unsigned int num_blank_lines = 0; apr_size_t cr = 0; char buf[2]; + c->data_in_input_filters = 0; while (c->keepalive != AP_CONN_CLOSE && !c->aborted) { apr_size_t len = cr + 1; apr_brigade_cleanup(bb); rv = ap_get_brigade(c->input_filters, bb, mode, APR_NONBLOCK_READ, len); - if (rv != APR_SUCCESS || APR_BRIGADE_EMPTY(bb) || !max_blank_lines) { + 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; - rv = APR_EGENERAL; - } - else if (rv == APR_SUCCESS && !APR_BRIGADE_EMPTY(bb)) { - /* Single read asked, data available */ - rv = APR_ENOTEMPTY; - } - else if (APR_STATUS_IS_EAGAIN(rv)) { - /* Pipe is empty and ready */ - rv = APR_SUCCESS; - } - else { - /* Pipe is dead, rv up to date */ - c->keepalive = AP_CONN_CLOSE; } break; } - /* Lookup and consume blank lines */ + /* Ignore trailing blank lines (which must not be interpreted as + * pipelined requests) up to the limit, otherwise we would block + * on the next read without flushing data, and hence possibly delay + * pending response(s) until the next/real request comes in or the + * keepalive timeout expires. + */ rv = apr_brigade_flatten(bb, buf, &len); if (rv != APR_SUCCESS || len != cr + 1) { int log_level; @@ -275,17 +271,14 @@ AP_DECLARE(apr_status_t) ap_check_pipeline(conn_rec *c, apr_bucket_brigade *bb, /* Unexpected error, stop with this connection */ c->keepalive = AP_CONN_CLOSE; log_level = APLOG_ERR; - if (rv == APR_SUCCESS) { - rv = APR_EGENERAL; - } } 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; log_level = APLOG_DEBUG; - rv = APR_ENOTEMPTY; } ap_log_cerror(APLOG_MARK, log_level, rv, c, APLOGNO(02968) "Can't check pipelined data"); @@ -293,49 +286,40 @@ AP_DECLARE(apr_status_t) ap_check_pipeline(conn_rec *c, apr_bucket_brigade *bb, } if (mode == AP_MODE_READBYTES) { - /* [CR]LF consumed, try next */ mode = AP_MODE_SPECULATIVE; cr = 0; } else if (cr) { AP_DEBUG_ASSERT(len == 2 && buf[0] == APR_ASCII_CR); if (buf[1] == APR_ASCII_LF) { - /* consume this CRLF */ mode = AP_MODE_READBYTES; - num_blank_lines++; + num_blank_lines--; } else { - /* CR(?!LF) is data */ - rv = APR_ENOTEMPTY; + c->data_in_input_filters = 1; break; } } else { if (buf[0] == APR_ASCII_LF) { - /* consume this LF */ mode = AP_MODE_READBYTES; - num_blank_lines++; + num_blank_lines--; } else if (buf[0] == APR_ASCII_CR) { cr = 1; } else { - /* Not [CR]LF, some data */ - rv = APR_ENOTEMPTY; + c->data_in_input_filters = 1; break; } } - if (num_blank_lines > max_blank_lines) { - /* Enough blank lines with this connection, - * stop and don't recycle it. - */ + /* Enough blank lines with this connection? + * Stop and don't recycle it. + */ + if (num_blank_lines < 0) { c->keepalive = AP_CONN_CLOSE; - rv = APR_NOTFOUND; - break; } } - - return rv; } @@ -344,7 +328,6 @@ AP_DECLARE(void) ap_process_request_after_handler(request_rec *r) apr_bucket_brigade *bb; apr_bucket *b; conn_rec *c = r->connection; - apr_status_t rv; /* Send an EOR bucket through the output filter chain. When * this bucket is destroyed, the request will be logged and @@ -377,15 +360,8 @@ AP_DECLARE(void) ap_process_request_after_handler(request_rec *r) * already by the EOR bucket's cleanup function. */ - /* Check pipeline consuming blank lines, they must not be interpreted as - * the next pipelined request, otherwise we would block on the next read - * without flushing data, and hence possibly delay pending response(s) - * until the next/real request comes in or the keepalive timeout expires. - */ - rv = ap_check_pipeline(c, bb, DEFAULT_LIMIT_BLANK_LINES); - c->data_in_input_filters = (rv == APR_ENOTEMPTY); + check_pipeline(c, bb); apr_brigade_destroy(bb); - if (c->cs) c->cs->state = (c->aborted) ? CONN_STATE_LINGER : CONN_STATE_WRITE_COMPLETION; |