]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
Merge r480135, r480193, r504559, r602349, r602657, r503863 from trunk:
authorRuediger Pluem <rpluem@apache.org>
Sun, 9 Dec 2007 14:54:23 +0000 (14:54 +0000)
committerRuediger Pluem <rpluem@apache.org>
Sun, 9 Dec 2007 14:54:23 +0000 (14:54 +0000)
* Apply patch for PR 41056 (19954) to fix chunk
  filter. Now flushes work better.

* Protect against any sort of non-block read that
  would block. If ap_get_brigade() shows that, return
  EAGAIN.

* Further refinement for PR41056 / PR 19954 (mostly-fixed in r480135.)
  We assume that a successful read but an empty brigade
  is NOT cause for EAGAIN. Testing may or may not
  confirm this assumption, in which case that test
  may be required as well.

* If no data is available at this point of time we need to switch into the
  BODY_CHUNK_PART state like we do several lines later in the code in the
  same situation.

* Case statements should go on their own line.  (No functional change.)

* modules/http/http_filters.c
  (ap_http_filter): Put case on its own line.

* Add missing Changelog entry for PR41056 / PR 19954. This was fixed in r480135.

PR: 41056 / 19954
Submitted by: jfclere, jim
Reviewed by: rpluem, jim, jerenkrantz

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@602679 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
STATUS
modules/http/http_filters.c

diff --git a/CHANGES b/CHANGES
index b20565437f3e88dfe69909d0e18662f17f73d78e..d6c85713e96b2b9217e929ab43558e3045a23c43 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,8 +1,12 @@
                                                         -*- coding: utf-8 -*-
 Changes with Apache 2.2.7
 
+  *) core: Fix broken chunk filtering that causes all non blocking reads to be
+     converted into blocking reads.  PR 19954, 41056.
+    [Jean-Frederic Clere, Jim Jagielski]
+
   *) mod_rewrite: Add the novary flag to RewriteCond.
-     [Ruediger Pluem] 
+     [Ruediger Pluem]
 
   *) core: Change etag generation to produce identical results on
      32-bit and 64-bit platforms.  PR 40064.  [Joe Orton]
diff --git a/STATUS b/STATUS
index 47fd23fc3a149a441602395eaf362b7a94003d0d..ad49828094490322b1a4a6495b69fa0bf778e17d 100644 (file)
--- a/STATUS
+++ b/STATUS
@@ -89,21 +89,6 @@ PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
        (NWGNUsubstitute need also be copied over from trunk, is missing in your patch)
     +1: jim, rpluem, fuankg
 
-  * core: Fix broken chunk filtering that causes all non blocking reads to be
-          converted into blocking reads
-    PR 19954 / 41056
-    Trunk version of patch:
-       http://svn.apache.org/viewcvs.cgi?rev=480135&view=rev
-       http://svn.apache.org/viewcvs.cgi?rev=480193&view=rev
-       http://svn.apache.org/viewcvs.cgi?rev=504559&view=rev
-       http://svn.apache.org/viewcvs.cgi?rev=602349&view=rev
-       http://svn.apache.org/viewcvs.cgi?rev=503863&view=rev (CHANGES)
-       http://svn.apache.org/viewcvs.cgi?rev=602657&view=rev (style chg)
-    Backport version for 2.2.x of patch:
-       Trunk version of patch works
-    +1: rpluem, jim, jerenkrantz
-    jerenkrantz says: Feel free to apply with or withour r602657.  =)
-
 PATCHES PROPOSED TO BACKPORT FROM TRUNK:
   [ New proposals should be added at the end of the list ]
 
index 5e6316fdce86ee891e1eeabfe76f0217f08ce64c..e5d821cc250c3d1950a9e172009e947bdbdd0ff7 100644 (file)
@@ -64,7 +64,8 @@ typedef struct http_filter_ctx {
     enum {
         BODY_NONE,
         BODY_LENGTH,
-        BODY_CHUNK
+        BODY_CHUNK,
+        BODY_CHUNK_PART
     } state;
     int eos_sent;
 } http_ctx_t;
@@ -234,7 +235,15 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b,
             bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
 
             rv = ap_get_brigade(f->next, bb, AP_MODE_GETLINE,
-                                APR_BLOCK_READ, 0);
+                                block, 0);
+
+            /* for timeout */
+            if (block == APR_NONBLOCK_READ &&
+                ( (rv == APR_SUCCESS && APR_BRIGADE_EMPTY(bb)) ||
+                  (APR_STATUS_IS_EAGAIN(rv)) )) {
+                ctx->state = BODY_CHUNK_PART;
+                return APR_EAGAIN;
+            }
 
             if (rv == APR_SUCCESS) {
                 /* We have to check the length of the brigade we got back.
@@ -297,6 +306,7 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b,
             ctx->eos_sent = 1;
             return APR_SUCCESS;
         case BODY_CHUNK:
+        case BODY_CHUNK_PART:
             {
                 char line[30];
                 apr_bucket_brigade *bb;
@@ -306,14 +316,30 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b,
                 bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
 
                 /* We need to read the CRLF after the chunk.  */
-                rv = ap_get_brigade(f->next, bb, AP_MODE_GETLINE,
-                                    APR_BLOCK_READ, 0);
-                apr_brigade_cleanup(bb);
+                if (ctx->state == BODY_CHUNK) {
+                    rv = ap_get_brigade(f->next, bb, AP_MODE_GETLINE,
+                                        block, 0);
+                    apr_brigade_cleanup(bb);
+                    if (block == APR_NONBLOCK_READ &&
+                        (APR_STATUS_IS_EAGAIN(rv))) {
+                        return APR_EAGAIN;
+                    }
+                } else {
+                    rv = APR_SUCCESS;
+                }
 
                 if (rv == APR_SUCCESS) {
                     /* Read the real chunk line. */
                     rv = ap_get_brigade(f->next, bb, AP_MODE_GETLINE,
-                                        APR_BLOCK_READ, 0);
+                                        block, 0);
+                    /* Test timeout */
+                    if (block == APR_NONBLOCK_READ &&
+                        ( (rv == APR_SUCCESS && APR_BRIGADE_EMPTY(bb)) ||
+                          (APR_STATUS_IS_EAGAIN(rv)) )) {
+                        ctx->state = BODY_CHUNK_PART;
+                        return APR_EAGAIN;
+                    }
+                    ctx->state = BODY_CHUNK;
                     if (rv == APR_SUCCESS) {
                         rv = apr_brigade_flatten(bb, line, &len);
                         if (rv == APR_SUCCESS) {