On 12/13/2005 05:55 PM, Jim Jagielski wrote:
> Eyes please... The coffee is VERY week this morning :)

Yes, I guess it was very weAk ;-). Just teasing. :)
Patch looks good to me. As it is only half of the way I assembled it with the 
other
pieces we had and I had sent. The attached patch passed the test with my jsp I 
described
earlier (and it really closes the connection to the client :-)).

So some eyes on this one please.

Regards

Rüdiger

P.S: Ignore the garbage signs in the mail version of the patch. Its just a copy 
and paste
from my vi.

Index: server/core_filters.c
===================================================================
--- server/core_filters.c»······(Revision 356370)
+++ server/core_filters.c»······(Arbeitskopie)
@@ -315,8 +315,10 @@
                                              apr_size_t *bytes_written,
                                              conn_rec *c);
·
-static void remove_empty_buckets(apr_bucket_brigade *bb);
+static void detect_error_bucket(apr_bucket *bucket, conn_rec *c);
·
+static void remove_empty_buckets(apr_bucket_brigade *bb, conn_rec *c);
+
 static apr_status_t send_brigade_blocking(apr_socket_t *s,
                                           apr_bucket_brigade *bb,
                                           apr_size_t *bytes_written,
@@ -487,7 +489,7 @@
     if (bb == NULL) {
         return;
     }
-    remove_empty_buckets(bb);
+    remove_empty_buckets(bb, c);
     if (!APR_BRIGADE_EMPTY(bb)) {
         c->data_in_output_filters = 1;
         if (make_a_copy) {
@@ -526,7 +528,7 @@
     struct iovec vec[MAX_IOVEC_TO_WRITE];
     apr_size_t nvec = 0;
·
-    remove_empty_buckets(bb);
+    remove_empty_buckets(bb, c);
·
     for (bucket = APR_BRIGADE_FIRST(bb);
          bucket != APR_BRIGADE_SENTINEL(bb);
@@ -596,16 +598,25 @@
         }
     }
·
-    remove_empty_buckets(bb);
+    remove_empty_buckets(bb, c);
·
     return APR_SUCCESS;
 }
·
-static void remove_empty_buckets(apr_bucket_brigade *bb)
+static void detect_error_bucket(apr_bucket *bucket, conn_rec *c)
 {
+    if ((bucket->type == &ap_bucket_type_error) && (((ap_bucket_error 
*)(bucket->data))->status == HTTP_BAD_GATEWAY)) {
+        /* stream aborted and we have not ended it yet */
+        c->keepalive = AP_CONN_CLOSE;
+    }
+}
+
+static void remove_empty_buckets(apr_bucket_brigade *bb, conn_rec *c)
+{
     apr_bucket *bucket;
     while (((bucket = APR_BRIGADE_FIRST(bb)) != APR_BRIGADE_SENTINEL(bb)) &&
            (APR_BUCKET_IS_METADATA(bucket) || (bucket->length == 0))) {
+        detect_error_bucket(bucket, c);
         APR_BUCKET_REMOVE(bucket);
         apr_bucket_destroy(bucket);
     }
@@ -678,6 +689,7 @@
             for (i = offset; i < nvec; ) {
                 apr_bucket *bucket = APR_BRIGADE_FIRST(bb);
                 if (APR_BUCKET_IS_METADATA(bucket)) {
+                    detect_error_bucket(bucket, c);
                     APR_BUCKET_REMOVE(bucket);
                     apr_bucket_destroy(bucket);
                 }
Index: modules/proxy/mod_proxy_http.c
===================================================================
--- modules/proxy/mod_proxy_http.c»·····(Revision 356370)
+++ modules/proxy/mod_proxy_http.c»·····(Arbeitskopie)
@@ -1481,12 +1481,18 @@
                     }
                     else if (rv != APR_SUCCESS) {
                         /* In this case, we are in real trouble because
-                         * our backend bailed on us, so abort our
-                         * connection to our user too.
+                         * our backend bailed on us.
                          */
                         ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c,
                                       "proxy: error reading response");
-                        c->aborted = 1;
+                        r->no_cache = 1;
+                        e = ap_bucket_error_create(HTTP_BAD_GATEWAY,  NULL,
+                                                   c->pool, c->bucket_alloc);
+                        APR_BRIGADE_INSERT_TAIL(bb, e);
+                        e = apr_bucket_eos_create(c->bucket_alloc);
+                        APR_BRIGADE_INSERT_TAIL(bb, e);
+                        ap_pass_brigade(r->output_filters, bb);
+                        backend->close = 1;
                         break;
                     }
                     /* next time try a non-blocking read */
Index: modules/cache/mod_disk_cache.c
===================================================================
--- modules/cache/mod_disk_cache.c»·····(Revision 356370)
+++ modules/cache/mod_disk_cache.c»·····(Arbeitskopie)
@@ -1010,7 +1010,7 @@
      * sanity checks.
      */
     if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(bb))) {
-        if (r->connection->aborted) {
+        if (r->connection->aborted || r->no_cache) {
             ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
                          "disk_cache: Discarding body for URL %s "
                          "because connection has been aborted.",
Index: server/core_filters.c
===================================================================
--- server/core_filters.c       (Revision 356370)
+++ server/core_filters.c       (Arbeitskopie)
@@ -315,8 +315,10 @@
                                              apr_size_t *bytes_written,
                                              conn_rec *c);
 
-static void remove_empty_buckets(apr_bucket_brigade *bb);
+static void detect_error_bucket(apr_bucket *bucket, conn_rec *c);
 
+static void remove_empty_buckets(apr_bucket_brigade *bb, conn_rec *c);
+
 static apr_status_t send_brigade_blocking(apr_socket_t *s,
                                           apr_bucket_brigade *bb,
                                           apr_size_t *bytes_written,
@@ -487,7 +489,7 @@
     if (bb == NULL) {
         return;
     }
-    remove_empty_buckets(bb);
+    remove_empty_buckets(bb, c);
     if (!APR_BRIGADE_EMPTY(bb)) {
         c->data_in_output_filters = 1;
         if (make_a_copy) {
@@ -526,7 +528,7 @@
     struct iovec vec[MAX_IOVEC_TO_WRITE];
     apr_size_t nvec = 0;
 
-    remove_empty_buckets(bb);
+    remove_empty_buckets(bb, c);
 
     for (bucket = APR_BRIGADE_FIRST(bb);
          bucket != APR_BRIGADE_SENTINEL(bb);
@@ -596,16 +598,25 @@
         }
     }
 
-    remove_empty_buckets(bb);
+    remove_empty_buckets(bb, c);
 
     return APR_SUCCESS;
 }
 
-static void remove_empty_buckets(apr_bucket_brigade *bb)
+static void detect_error_bucket(apr_bucket *bucket, conn_rec *c)
 {
+    if ((bucket->type == &ap_bucket_type_error) && (((ap_bucket_error 
*)(bucket->data))->status == HTTP_BAD_GATEWAY)) {
+        /* stream aborted and we have not ended it yet */
+        c->keepalive = AP_CONN_CLOSE;
+    }
+}
+
+static void remove_empty_buckets(apr_bucket_brigade *bb, conn_rec *c)
+{
     apr_bucket *bucket;
     while (((bucket = APR_BRIGADE_FIRST(bb)) != APR_BRIGADE_SENTINEL(bb)) &&
            (APR_BUCKET_IS_METADATA(bucket) || (bucket->length == 0))) {
+        detect_error_bucket(bucket, c);
         APR_BUCKET_REMOVE(bucket);
         apr_bucket_destroy(bucket);
     }
@@ -678,6 +689,7 @@
             for (i = offset; i < nvec; ) {
                 apr_bucket *bucket = APR_BRIGADE_FIRST(bb);
                 if (APR_BUCKET_IS_METADATA(bucket)) {
+                    detect_error_bucket(bucket, c);
                     APR_BUCKET_REMOVE(bucket);
                     apr_bucket_destroy(bucket);
                 }
Index: modules/proxy/mod_proxy_http.c
===================================================================
--- modules/proxy/mod_proxy_http.c      (Revision 356370)
+++ modules/proxy/mod_proxy_http.c      (Arbeitskopie)
@@ -1481,12 +1481,18 @@
                     }
                     else if (rv != APR_SUCCESS) {
                         /* In this case, we are in real trouble because
-                         * our backend bailed on us, so abort our
-                         * connection to our user too.
+                         * our backend bailed on us.
                          */
                         ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c,
                                       "proxy: error reading response");
-                        c->aborted = 1;
+                        r->no_cache = 1;
+                        e = ap_bucket_error_create(HTTP_BAD_GATEWAY,  NULL,
+                                                   c->pool, c->bucket_alloc);
+                        APR_BRIGADE_INSERT_TAIL(bb, e);
+                        e = apr_bucket_eos_create(c->bucket_alloc);
+                        APR_BRIGADE_INSERT_TAIL(bb, e);
+                        ap_pass_brigade(r->output_filters, bb);
+                        backend->close = 1;
                         break;
                     }
                     /* next time try a non-blocking read */
Index: modules/cache/mod_disk_cache.c
===================================================================
--- modules/cache/mod_disk_cache.c      (Revision 356370)
+++ modules/cache/mod_disk_cache.c      (Arbeitskopie)
@@ -1010,7 +1010,7 @@
      * sanity checks.
      */
     if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(bb))) {
-        if (r->connection->aborted) {
+        if (r->connection->aborted || r->no_cache) {
             ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
                          "disk_cache: Discarding body for URL %s "
                          "because connection has been aborted.",

Reply via email to