httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Aaron Bannert <aa...@clove.org>
Subject mod_proxy_http ignores errors from ap_pass_brigade(r->output_filters)
Date Wed, 10 Feb 2010 23:04:16 GMT
mod_proxy_http appears to be ignoring errors returned from ap_pass_brigade
(when passing down the output_filter stack). This is a problem for any
output filter that has a fatal error and wishes to signal that error
to the client (eg. HTTP_INTERNAL_SERVER_ERROR). I'm not familiar enough
with the current mod_proxy code to know if I did this correctly, but
this patch works for me. I also went ahead and marked the places where
we (kind of hackishly) ignore the return values intentionally.

Could someone review this and let me know if I'm on the right track
(against 2.2.x branch)?

Thanks,
-aaron


Index: modules/proxy/mod_proxy_http.c
===================================================================
--- modules/proxy/mod_proxy_http.c	(revision 908672)
+++ modules/proxy/mod_proxy_http.c	(working copy)
@@ -1444,7 +1444,7 @@
                 else {
                     APR_BUCKET_INSERT_BEFORE(eos, e);
                 }
-                ap_pass_brigade(r->output_filters, bb);
+                (void)ap_pass_brigade(r->output_filters, bb);
                 /* Need to return OK to avoid sending an error message */
                 return OK;
             }
@@ -1767,7 +1767,7 @@
                         ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c,
                                       "proxy: error reading response");
                         ap_proxy_backend_broke(r, bb);
-                        ap_pass_brigade(r->output_filters, bb);
+                        (void)ap_pass_brigade(r->output_filters, bb);
                         backend_broke = 1;
                         backend->close = 1;
                         break;
@@ -1800,36 +1800,40 @@
                     }
 
                     /* try send what we read */
-                    if (ap_pass_brigade(r->output_filters, pass_bb) != APR_SUCCESS
-                        || c->aborted) {
-                        /* Ack! Phbtt! Die! User aborted! */
-                        backend->close = 1;  /* this causes socket close below */
-                        finish = TRUE;
-                    }
+                    rv = ap_pass_brigade(r->output_filters, pass_bb);
 
                     /* make sure we always clean up after ourselves */
                     apr_brigade_cleanup(bb);
                     apr_brigade_cleanup(pass_bb);
 
+                    /* check if output filter failed or user aborted */
+                    if (rv != APR_SUCCESS || c->aborted) {
+                        backend->close = 1; /* this causes socket close below */
+                        if (!rv) return DONE; /* return DONE for aborts */
+                        return rv;
+                    }
+
                 } while (!finish);
             }
             ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
                          "proxy: end body send");
         }
         else if (!interim_response) {
+            apr_status_t rv;
             ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
                          "proxy: header only");
 
             /* Pass EOS bucket down the filter chain. */
             e = apr_bucket_eos_create(c->bucket_alloc);
             APR_BRIGADE_INSERT_TAIL(bb, e);
-            if (ap_pass_brigade(r->output_filters, bb) != APR_SUCCESS
-                || c->aborted) {
-                /* Ack! Phbtt! Die! User aborted! */
+            rv = ap_pass_brigade(r->output_filters, bb);
+            apr_brigade_cleanup(bb);
+            /* check if output filter failed or user aborted */
+            if (rv != APR_SUCCESS || c->aborted) {
                 backend->close = 1;  /* this causes socket close below */
+                if (!rv) return DONE; /* return DONE for aborts */
+                return rv;
             }
-
-            apr_brigade_cleanup(bb);
         }
     } while (interim_response && (interim_response < AP_MAX_INTERIM_RESPONSES));
 

Mime
View raw message