summaryrefslogtreecommitdiffstats
path: root/modules/http
diff options
context:
space:
mode:
authorYann Ylavic <ylavic@apache.org>2016-08-12 01:37:45 +0200
committerYann Ylavic <ylavic@apache.org>2016-08-12 01:37:45 +0200
commit104ef73c959702fa80c7d7a2f1f23e92b3f8c351 (patch)
tree5de52fcca8b9fd2d3026267781ec3a4ba55d1d7e /modules/http
parenthttp: follow up to r1750392. (diff)
downloadapache2-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.c74
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;