]> granicus.if.org Git - apache/commitdiff
PR 55475: Detect incomplete body in HTTP input filter and return APR_INCOMPLETE
authorJim Jagielski <jim@apache.org>
Mon, 4 Nov 2013 21:31:27 +0000 (21:31 +0000)
committerJim Jagielski <jim@apache.org>
Mon, 4 Nov 2013 21:31:27 +0000 (21:31 +0000)
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1538776 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
modules/http/chunk_filter.c
modules/http/http_filters.c

diff --git a/CHANGES b/CHANGES
index 43aae403687ec441207b1d3083751e8a6e51d96c..6a586b8c28a30b9df50f12506a07d7289c466171 100644 (file)
--- 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 <ylavic dev gmail com>]
+
   *) mod_cgid: Use the servers Timeout for each read from a CGI script,
      allow override with new CGIDRequestTimeout directive. PR43494
      [Eric Covener, Toshikuni Fukaya <toshikuni-fukaya cybozu co jp>]
index 17fbabdb0a70b1e15c7d4c738b265f5008bb68f2..e8d347435703519514873918fc700799f254fbcd 100644 (file)
@@ -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.
index c92acf606dbde35a525eb7e32dcdcadf858d939f..37c277dc50825632c8ed710b410ca3a03d0fdc8d 100644 (file)
@@ -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;
             }