From: Jim Jagielski Date: Mon, 4 Nov 2013 21:31:27 +0000 (+0000) Subject: PR 55475: Detect incomplete body in HTTP input filter and return APR_INCOMPLETE X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6f16f2714099810812bc2b9ab796eda37c1dac41;p=thirdparty%2Fapache%2Fhttpd.git PR 55475: Detect incomplete body in HTTP input filter and return APR_INCOMPLETE git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1538776 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 43aae403687..6a586b8c28a 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,9 @@ -*- coding: utf-8 -*- Changes with Apache 2.5.0 + *) core: Detect incomplete body in HTTP input filter and return + APR_INCOMPLETE. PR 55475 [Yann Ylavic ] + *) mod_cgid: Use the servers Timeout for each read from a CGI script, allow override with new CGIDRequestTimeout directive. PR43494 [Eric Covener, Toshikuni Fukaya ] diff --git a/modules/http/chunk_filter.c b/modules/http/chunk_filter.c index 17fbabdb0a7..e8d34743570 100644 --- a/modules/http/chunk_filter.c +++ b/modules/http/chunk_filter.c @@ -72,9 +72,9 @@ apr_status_t ap_http_chunk_filter(ap_filter_t *f, apr_bucket_brigade *b) eos = e; break; } - if (AP_BUCKET_IS_ERROR(e) - && (((ap_bucket_error *)(e->data))->status - == HTTP_BAD_GATEWAY)) { + if (AP_BUCKET_IS_ERROR(e) && + (((ap_bucket_error *)(e->data))->status == HTTP_BAD_GATEWAY || + ((ap_bucket_error *)(e->data))->status == HTTP_GATEWAY_TIME_OUT)) { /* * We had a broken backend. Memorize this in the filter * context. diff --git a/modules/http/http_filters.c b/modules/http/http_filters.c index c92acf606db..37c277dc508 100644 --- a/modules/http/http_filters.c +++ b/modules/http/http_filters.c @@ -359,6 +359,10 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, return APR_EAGAIN; } + if (rv == APR_EOF) { + return APR_INCOMPLETE; + } + if (rv != APR_SUCCESS) { return rv; } @@ -384,8 +388,8 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, apr_bucket_delete(e); e = APR_BRIGADE_FIRST(b); - again = 1; /* come around again */ } + again = 1; /* come around again */ if (ctx->state == BODY_CHUNK_TRAILER) { ap_get_mime_headers(f->r); @@ -416,6 +420,11 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, return APR_EAGAIN; } + if (rv == APR_EOF && ctx->state != BODY_NONE + && ctx->remaining > 0) { + return APR_INCOMPLETE; + } + if (rv != APR_SUCCESS) { return rv; } @@ -432,7 +441,8 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, if (ctx->remaining > 0) { e = APR_BRIGADE_LAST(b); if (APR_BUCKET_IS_EOS(e)) { - return APR_EOF; + apr_bucket_delete(e); + return APR_INCOMPLETE; } } else if (ctx->state == BODY_CHUNK_DATA) { @@ -1631,7 +1641,8 @@ apr_status_t ap_http_outerror_filter(ap_filter_t *f, * Start of error handling state tree. Just one condition * right now :) */ - if (((ap_bucket_error *)(e->data))->status == HTTP_BAD_GATEWAY) { + if (((ap_bucket_error *)(e->data))->status == HTTP_BAD_GATEWAY || + ((ap_bucket_error *)(e->data))->status == HTTP_GATEWAY_TIME_OUT) { /* stream aborted and we have not ended it yet */ r->connection->keepalive = AP_CONN_CLOSE; }