Index: server/util_filter.c
===================================================================
--- server/util_filter.c	(revision 1533610)
+++ server/util_filter.c	(working copy)
@@ -556,6 +556,23 @@ AP_DECLARE(apr_status_t) ap_get_brigade(ap_filter_
     return AP_NOBODY_READ;
 }
 
+/*
+ * Was the previous call to :
+ *     rv = ap_get_brigade(., bb, .., block, ..)
+ * a non-blocking read which would have blocked?
+ */
+AP_DECLARE(int) ap_got_wouldblock_brigade(apr_status_t rv,
+                                          apr_bucket_brigade *bb,
+                                          apr_read_type_e block)
+{
+    /* ap_get_brigade may return success with an empty brigade
+     * for a non-blocking read which would block.
+     */
+    if (block == APR_NONBLOCK_READ
+            && ((rv == APR_SUCCESS && APR_BRIGADE_EMPTY(bb))
+                    || (APR_STATUS_IS_EAGAIN(rv))));
+}
+
 /* Pass the buckets to the next filter in the filter stack.  If the
  * current filter is a handler, we should get NULL passed in instead of
  * the current filter.  At that point, we can just call the first filter in
Index: modules/http/http_filters.c
===================================================================
--- modules/http/http_filters.c	(revision 1533610)
+++ modules/http/http_filters.c	(working copy)
@@ -353,9 +353,7 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bu
             rv = ap_get_brigade(f->next, b, AP_MODE_GETLINE, block, 0);
 
             /* for timeout */
-            if (block == APR_NONBLOCK_READ
-                    && ((rv == APR_SUCCESS && APR_BRIGADE_EMPTY(b))
-                            || (APR_STATUS_IS_EAGAIN(rv)))) {
+            if (ap_got_wouldblock_brigade(rv, b, block)) {
                 return APR_EAGAIN;
             }
 
@@ -410,9 +408,7 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bu
                 rv = ap_get_brigade(f->next, b, mode, block, readbytes);
 
                 /* for timeout */
-                if (block == APR_NONBLOCK_READ
-                        && ((rv == APR_SUCCESS && APR_BRIGADE_EMPTY(b))
-                                || (APR_STATUS_IS_EAGAIN(rv)))) {
+                if (ap_got_wouldblock_brigade(rv, b, block)) {
                     return APR_EAGAIN;
                 }
 
@@ -474,9 +470,7 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bu
             rv = ap_get_brigade(f->next, b, mode, block, readbytes);
 
             /* for timeout */
-            if (block == APR_NONBLOCK_READ
-                    && ((rv == APR_SUCCESS && APR_BRIGADE_EMPTY(b))
-                            || (APR_STATUS_IS_EAGAIN(rv)))) {
+            if (ap_got_wouldblock_brigade(rv, b, block)) {
                 return APR_EAGAIN;
             }
 
Index: modules/http/http_request.c
===================================================================
--- modules/http/http_request.c	(revision 1533610)
+++ modules/http/http_request.c	(working copy)
@@ -224,7 +224,8 @@ static void check_pipeline(conn_rec *c)
 
         rv = ap_get_brigade(c->input_filters, bb, AP_MODE_SPECULATIVE,
                             APR_NONBLOCK_READ, 1);
-        if (rv != APR_SUCCESS || APR_BRIGADE_EMPTY(bb)) {
+        if (rv != APR_SUCCESS
+               || ap_got_wouldblock_brigade(rv, bb, APR_NONBLOCK_READ)) {
             /*
              * Error or empty brigade: There is no data present in the input
              * filter
Index: modules/lua/mod_lua.c
===================================================================
--- modules/lua/mod_lua.c	(revision 1533610)
+++ modules/lua/mod_lua.c	(working copy)
@@ -577,8 +577,10 @@ static apr_status_t lua_input_filter_handle(ap_fil
     
     if (APR_BRIGADE_EMPTY(ctx->tmpBucket)) {
         ret = ap_get_brigade(f->next, ctx->tmpBucket, eMode, eBlock, nBytes);
-        if (eMode == AP_MODE_EATCRLF || ret != APR_SUCCESS)
+        if (eMode == AP_MODE_EATCRLF || ret != APR_SUCCESS
+                || ap_got_wouldblock_brigade(ret, ctx->tmpBucket, eBlock)) {
             return ret;
+        }
     }
     
     /* While the Lua function is still yielding, pass buckets to the coroutine */
Index: modules/proxy/mod_proxy_connect.c
===================================================================
--- modules/proxy/mod_proxy_connect.c	(revision 1533610)
+++ modules/proxy/mod_proxy_connect.c	(working copy)
@@ -156,11 +156,12 @@ static int proxy_connect_transfer(request_rec *r,
         apr_brigade_cleanup(bb);
         rv = ap_get_brigade(c_i->input_filters, bb, AP_MODE_READBYTES,
                             APR_NONBLOCK_READ, CONN_BLKSZ);
-        if (rv == APR_SUCCESS) {
+        if (ap_got_wouldblock_brigade(rv, bb, APR_NONBLOCK_READ)) {
+            rv = APR_EAGAIN;
+        }
+        else if (rv == APR_SUCCESS) {
             if (c_o->aborted)
                 return APR_EPIPE;
-            if (APR_BRIGADE_EMPTY(bb))
-                break;
 #ifdef DEBUGGING
             len = -1;
             apr_brigade_length(bb, 0, &len);
@@ -177,7 +178,7 @@ static int proxy_connect_transfer(request_rec *r,
                               "error on %s - ap_pass_brigade",
                               name);
             }
-        } else if (!APR_STATUS_IS_EAGAIN(rv)) {
+        } else {
             ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, APLOGNO(01018)
                           "error on %s - ap_get_brigade",
                           name);
Index: modules/proxy/proxy_util.c
===================================================================
--- modules/proxy/proxy_util.c	(revision 1533610)
+++ modules/proxy/proxy_util.c	(working copy)
@@ -1423,7 +1423,8 @@ PROXY_DECLARE(apr_status_t) ap_proxy_ssl_connectio
         rv = ap_get_brigade(conn->connection->input_filters, bb,
                             AP_MODE_READBYTES, APR_NONBLOCK_READ,
                             HUGE_STRING_LEN);
-        if ((rv != APR_SUCCESS) && !APR_STATUS_IS_EAGAIN(rv)) {
+        if ((rv != APR_SUCCESS)
+				&& !ap_got_wouldblock_brigade(rv, bb, APR_NONBLOCK_READ)) {
             socket_cleanup(conn);
         }
         if (!APR_BRIGADE_EMPTY(bb)) {
Index: modules/proxy/mod_proxy_http.c
===================================================================
--- modules/proxy/mod_proxy_http.c	(revision 1533610)
+++ modules/proxy/mod_proxy_http.c	(working copy)
@@ -1663,11 +1663,7 @@ int ap_proxy_http_process_response(apr_pool_t * p,
                                         AP_MODE_READBYTES, mode,
                                         conf->io_buffer_size);
 
-                    /* ap_get_brigade will return success with an empty brigade
-                     * for a non-blocking read which would block: */
-                    if (mode == APR_NONBLOCK_READ
-                        && (APR_STATUS_IS_EAGAIN(rv)
-                            || (rv == APR_SUCCESS && APR_BRIGADE_EMPTY(bb)))) {
+                    if (ap_got_wouldblock_brigade(rv, bb, mode)) {
                         /* flush to the client and switch to blocking mode */
                         e = apr_bucket_flush_create(c->bucket_alloc);
                         APR_BRIGADE_INSERT_TAIL(bb, e);
Index: modules/proxy/mod_proxy_wstunnel.c
===================================================================
--- modules/proxy/mod_proxy_wstunnel.c	(revision 1533610)
+++ modules/proxy/mod_proxy_wstunnel.c	(working copy)
@@ -221,11 +221,12 @@ static int proxy_wstunnel_transfer(request_rec *r,
         apr_brigade_cleanup(bb);
         rv = ap_get_brigade(c_i->input_filters, bb, AP_MODE_READBYTES,
                             APR_NONBLOCK_READ, AP_IOBUFSIZE);
-        if (rv == APR_SUCCESS) {
+        if (ap_got_wouldblock_brigade(rv, bb, APR_NONBLOCK_READ)) {
+            rv = APR_EAGAIN;
+        }
+        else if (rv == APR_SUCCESS) {
             if (c_o->aborted)
                 return APR_EPIPE;
-            if (APR_BRIGADE_EMPTY(bb))
-                break;
 #ifdef DEBUGGING
             len = -1;
             apr_brigade_length(bb, 0, &len);
@@ -242,7 +243,7 @@ static int proxy_wstunnel_transfer(request_rec *r,
                               "error on %s - ap_pass_brigade",
                               name);
             }
-        } else if (!APR_STATUS_IS_EAGAIN(rv) && !APR_STATUS_IS_EOF(rv)) {
+        } else if (!APR_STATUS_IS_EOF(rv)) { 
             ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, APLOGNO(02442)
                           "error on %s - ap_get_brigade",
                           name);
Index: modules/debugging/mod_firehose.c
===================================================================
--- modules/debugging/mod_firehose.c	(revision 1533610)
+++ modules/debugging/mod_firehose.c	(working copy)
@@ -285,7 +285,8 @@ static apr_status_t firehose_input_filter(ap_filte
      * this case, pass through the APR_SUCCESS and emulate the
      * underlying filter.
      */
-    if (rv != APR_SUCCESS || APR_BRIGADE_EMPTY(bb)) {
+    if (rv != APR_SUCCESS
+           || ap_got_wouldblock_brigade(rv, bb, block)) {
         return rv;
     }
 
Index: modules/ssl/ssl_engine_io.c
===================================================================
--- modules/ssl/ssl_engine_io.c	(revision 1533610)
+++ modules/ssl/ssl_engine_io.c	(working copy)
@@ -490,8 +490,8 @@ static int bio_filter_in_read(BIO *bio, char *in,
          * brigade, return an error after setting the retry flag;
          * SSL_read() will then return -1, and SSL_get_error() will
          * indicate SSL_ERROR_WANT_READ. */
-        if (APR_STATUS_IS_EAGAIN(inctx->rc) || APR_STATUS_IS_EINTR(inctx->rc)
-               || (inctx->rc == APR_SUCCESS && APR_BRIGADE_EMPTY(inctx->bb))) {
+        if (APR_STATUS_IS_EINTR(inctx->rc)
+               || ap_got_wouldblock_brigade(inctx->rc, inctx->bb, block)) {
             BIO_set_retry_read(bio);
             return -1;
         }
Index: modules/filters/mod_ext_filter.c
===================================================================
--- modules/filters/mod_ext_filter.c	(revision 1533610)
+++ modules/filters/mod_ext_filter.c	(working copy)
@@ -924,7 +924,8 @@ static apr_status_t ef_input_filter(ap_filter_t *f
     }
 
     rv = ap_get_brigade(f->next, bb, mode, block, readbytes);
-    if (rv != APR_SUCCESS) {
+    if (rv != APR_SUCCESS
+           || ap_got_wouldblock_brigade(rv, bb, block)) {
         return rv;
     }
 
Index: modules/filters/mod_sed.c
===================================================================
--- modules/filters/mod_sed.c	(revision 1533610)
+++ modules/filters/mod_sed.c	(working copy)
@@ -443,7 +443,8 @@ static apr_status_t sed_request_filter(ap_filter_t
         /* read the bytes from next level filter */
         apr_brigade_cleanup(bbinp);
         status = ap_get_brigade(f->next, bbinp, mode, block, readbytes);
-        if (status != APR_SUCCESS) {
+        if (status != APR_SUCCESS
+                || ap_got_wouldblock_brigade(status, bbinp, block)) {
             return status;
         }
         for (b = APR_BRIGADE_FIRST(bbinp); b != APR_BRIGADE_SENTINEL(bbinp);
Index: modules/filters/mod_reqtimeout.c
===================================================================
--- modules/filters/mod_reqtimeout.c	(revision 1533610)
+++ modules/filters/mod_reqtimeout.c	(working copy)
@@ -238,7 +238,8 @@ static apr_status_t reqtimeout_filter(ap_filter_t
 #endif
 
             rv = ap_get_brigade(f->next, bb, AP_MODE_GETLINE, APR_NONBLOCK_READ, remaining);
-            if (rv != APR_SUCCESS && !APR_STATUS_IS_EAGAIN(rv)) {
+            if (rv != APR_SUCCESS
+                   && !ap_got_wouldblock_brigade(rv, bb, APR_NONBLOCK_READ)) {
                 break;
             }
 
Index: modules/filters/mod_deflate.c
===================================================================
--- modules/filters/mod_deflate.c	(revision 1533610)
+++ modules/filters/mod_deflate.c	(working copy)
@@ -939,7 +939,8 @@ static apr_status_t deflate_in_filter(ap_filter_t
         ctx->buffer = apr_palloc(r->pool, c->bufferSize);
 
         rv = ap_get_brigade(f->next, ctx->bb, AP_MODE_READBYTES, block, 10);
-        if (rv != APR_SUCCESS) {
+        if (rv != APR_SUCCESS
+               || ap_got_wouldblock_brigade(rv, ctx->bb, block)) {
             return rv;
         }
 
@@ -996,7 +997,9 @@ static apr_status_t deflate_in_filter(ap_filter_t
 
     if (APR_BRIGADE_EMPTY(ctx->proc_bb)) {
         rv = ap_get_brigade(f->next, ctx->bb, mode, block, readbytes);
-
+        if (ap_got_wouldblock_brigade(rv, ctx->bb, block)) {
+            return rv;
+        }
         if (rv != APR_SUCCESS) {
             /* What about APR_EAGAIN errors? */
             inflateEnd(&ctx->stream);
Index: modules/filters/mod_charset_lite.c
===================================================================
--- modules/filters/mod_charset_lite.c	(revision 1533610)
+++ modules/filters/mod_charset_lite.c	(working copy)
@@ -1035,7 +1035,8 @@ static apr_status_t xlate_in_filter(ap_filter_t *f
 
     if (APR_BRIGADE_EMPTY(ctx->bb)) {
         if ((rv = ap_get_brigade(f->next, bb, mode, block,
-                                 readbytes)) != APR_SUCCESS) {
+                                 readbytes)) != APR_SUCCESS
+                || ap_got_wouldblock_brigade(rv, bb, block)) {
             return rv;
         }
     }
Index: modules/filters/mod_buffer.c
===================================================================
--- modules/filters/mod_buffer.c	(revision 1533610)
+++ modules/filters/mod_buffer.c	(working copy)
@@ -229,7 +229,8 @@ static apr_status_t buffer_in_filter(ap_filter_t *
              * this case, pass through the APR_SUCCESS and emulate the
              * underlying filter.
              */
-            if (rv != APR_SUCCESS || APR_BRIGADE_EMPTY(ctx->tmp)) {
+            if (rv != APR_SUCCESS
+                   || ap_got_wouldblock_brigade(rv, bb, block)) {
                 return rv;
             }
 
Index: modules/apreq/filter.c
===================================================================
--- modules/apreq/filter.c	(revision 1533610)
+++ modules/apreq/filter.c	(working copy)
@@ -380,7 +380,8 @@ apr_status_t apreq_filter(ap_filter_t *f,
 
 
     rv = ap_get_brigade(f->next, bb, mode, block, readbytes);
-    if (rv != APR_SUCCESS)
+    if (rv != APR_SUCCESS
+           || ap_got_wouldblock_brigade(rv, bb, block))
         return rv;
 
     apreq_brigade_copy(ctx->bb, bb);
Index: include/util_filter.h
===================================================================
--- include/util_filter.h	(revision 1533610)
+++ include/util_filter.h	(working copy)
@@ -300,6 +300,18 @@ AP_DECLARE(apr_status_t) ap_get_brigade(ap_filter_
                                         apr_off_t readbytes);
 
 /**
+ * Returns whether the previous call to ap_get_brigade(., bb, .., block, ..)
+ * was a non-blocking read which would have blocked.
+ * @param rv The status returned by the previous call to ap_get_brigade
+ * @param bb The bucket brigade got from the previous call to ap_get_brigade
+ * @param block  The operation performed on the previous call to ap_get_brigade
+ *               ::APR_BLOCK_READ, ::APR_NONBLOCK_READ
+ */
+AP_DECLARE(int) ap_got_wouldblock_brigade(apr_status_t rv,
+                                          apr_bucket_brigade *bb,
+                                          apr_read_type_e block);
+
+/**
  * Pass the current bucket brigade down to the next filter on the filter
  * stack.  The filter returns an apr_status_t value.  If the bottom-most
  * filter doesn't write to the network, then ::AP_NOBODY_WROTE is returned.
