From: Jim Jagielski Date: Thu, 20 Feb 2014 19:37:09 +0000 (+0000) Subject: * core: Detect incomplete body in HTTP input filter and return X-Git-Tag: 2.4.8~85 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9e688b7b8d303fe9f7004d1a77fca810471986b3;p=apache * core: Detect incomplete body in HTTP input filter and return APR_INCOMPLETE. PR 55475. trunk patch: http://svn.apache.org/r1538776 2.4.x patch: https://people.apache.org/~ylavic/2.4.x-http_filter_incomplete.patch git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1570324 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/modules/http/http_filters.c b/modules/http/http_filters.c index c727419453..564303c1c3 100644 --- a/modules/http/http_filters.c +++ b/modules/http/http_filters.c @@ -87,6 +87,23 @@ static apr_status_t bail_out_on_error(http_ctx_t *ctx, apr_bucket_brigade *bb = ctx->bb; apr_brigade_cleanup(bb); + + if (f->r->proxyreq == PROXYREQ_RESPONSE) { + switch (http_error) { + case HTTP_REQUEST_ENTITY_TOO_LARGE: + return APR_ENOSPC; + + case HTTP_REQUEST_TIME_OUT: + return APR_INCOMPLETE; + + case HTTP_NOT_IMPLEMENTED: + return APR_ENOTIMPL; + + default: + return APR_EGENERAL; + } + } + e = ap_bucket_error_create(http_error, NULL, f->r->pool, f->c->bucket_alloc); @@ -394,11 +411,11 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, if (rv != APR_SUCCESS || ctx->remaining < 0) { ap_log_rerror(APLOG_MARK, APLOG_INFO, rv, f->r, APLOGNO(01589) "Error reading first chunk %s ", (ctx->remaining < 0) ? "(overflow)" : ""); - ctx->remaining = 0; /* Reset it in case we have to - * come back here later */ - if (APR_STATUS_IS_TIMEUP(rv)) { + if (APR_STATUS_IS_TIMEUP(rv) || ctx->remaining > 0) { http_error = HTTP_REQUEST_TIME_OUT; } + ctx->remaining = 0; /* Reset it in case we have to + * come back here later */ return bail_out_on_error(ctx, f, http_error); } @@ -447,6 +464,9 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, return APR_EAGAIN; } /* If we get an error, then leave */ + if (rv == APR_EOF) { + return APR_INCOMPLETE; + } if (rv != APR_SUCCESS) { return rv; } @@ -500,11 +520,11 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, if (rv != APR_SUCCESS || ctx->remaining < 0) { ap_log_rerror(APLOG_MARK, APLOG_INFO, rv, f->r, APLOGNO(01590) "Error reading chunk %s ", (ctx->remaining < 0) ? "(overflow)" : ""); - ctx->remaining = 0; /* Reset it in case we have to - * come back here later */ - if (APR_STATUS_IS_TIMEUP(rv)) { + if (APR_STATUS_IS_TIMEUP(rv) || ctx->remaining > 0) { http_error = HTTP_REQUEST_TIME_OUT; } + ctx->remaining = 0; /* Reset it in case we have to + * come back here later */ return bail_out_on_error(ctx, f, http_error); } @@ -532,6 +552,10 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, rv = ap_get_brigade(f->next, b, mode, block, readbytes); + if (rv == APR_EOF && ctx->state != BODY_NONE && + ctx->remaining > 0) { + return APR_INCOMPLETE; + } if (rv != APR_SUCCESS) { return rv; } @@ -547,8 +571,10 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, ctx->remaining -= totalread; if (ctx->remaining > 0) { e = APR_BRIGADE_LAST(b); - if (APR_BUCKET_IS_EOS(e)) - return APR_EOF; + if (APR_BUCKET_IS_EOS(e)) { + apr_bucket_delete(e); + return APR_INCOMPLETE; + } } }