You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by rp...@apache.org on 2006/01/02 17:39:27 UTC
svn commit: r365374 - in /httpd/httpd/trunk/modules/proxy: mod_proxy.h
mod_proxy_ajp.c mod_proxy_http.c proxy_util.c
Author: rpluem
Date: Mon Jan 2 08:39:22 2006
New Revision: 365374
URL: http://svn.apache.org/viewcvs?rev=365374&view=rev
Log:
* Correctly signal broken backend connections up the chain also for the ajp
backend (see also r357461). Furthermore move common code in mod_proxy_http.c
and mod_proxy_ajp.c into a new function (ap_proxy_backend_broke) in
proxy_util.c.
modules/proxy/mod_proxy_ajp.c : Signal broken backend connection for ajp backend
modules/proxy/proxy_util.c : Add ap_proxy_backend_broke
modules/proxy/mod_proxy_http.c: - Use ap_proxy_backend_broke
- Return DONE also if backend broke
modules/proxy/mod_proxy.h : Add declaration of ap_proxy_backend_broke
Modified:
httpd/httpd/trunk/modules/proxy/mod_proxy.h
httpd/httpd/trunk/modules/proxy/mod_proxy_ajp.c
httpd/httpd/trunk/modules/proxy/mod_proxy_http.c
httpd/httpd/trunk/modules/proxy/proxy_util.c
Modified: httpd/httpd/trunk/modules/proxy/mod_proxy.h
URL: http://svn.apache.org/viewcvs/httpd/httpd/trunk/modules/proxy/mod_proxy.h?rev=365374&r1=365373&r2=365374&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/proxy/mod_proxy.h (original)
+++ httpd/httpd/trunk/modules/proxy/mod_proxy.h Mon Jan 2 08:39:22 2006
@@ -669,6 +669,15 @@
PROXY_DECLARE(int) ap_proxy_connection_create(const char *proxy_function,
proxy_conn_rec *conn,
conn_rec *c, server_rec *s);
+/**
+ * Signal the upstream chain that the connection to the backend broke in the
+ * middle of the response. This is done by sending an error bucket with
+ * status HTTP_BAD_GATEWAY and an EOS bucket up the filter chain.
+ * @param r current request record of client request
+ * @param brigade The brigade that is sent through the output filter chain
+ */
+PROXY_DECLARE(void) ap_proxy_backend_broke(request_rec *r,
+ apr_bucket_brigade *brigade);
/* Scoreboard */
#if MODULE_MAGIC_NUMBER_MAJOR > 20020903
Modified: httpd/httpd/trunk/modules/proxy/mod_proxy_ajp.c
URL: http://svn.apache.org/viewcvs/httpd/httpd/trunk/modules/proxy/mod_proxy_ajp.c?rev=365374&r1=365373&r2=365374&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/proxy/mod_proxy_ajp.c (original)
+++ httpd/httpd/trunk/modules/proxy/mod_proxy_ajp.c Mon Jan 2 08:39:22 2006
@@ -138,6 +138,8 @@
int havebody = 1;
int isok = 1;
apr_off_t bb_len;
+ int data_sent = 0;
+ int rv = 0;
#ifdef FLUSHING_BANDAID
apr_int32_t conn_poll_fd;
apr_pollfd_t *conn_poll;
@@ -348,6 +350,7 @@
"proxy: error processing body");
isok = 0;
}
+ data_sent = 1;
apr_brigade_cleanup(output_brigade);
}
else {
@@ -363,6 +366,7 @@
"proxy: error processing body");
isok = 0;
}
+ data_sent = 1;
break;
default:
isok = 0;
@@ -400,7 +404,11 @@
}
apr_brigade_destroy(input_brigade);
- apr_brigade_destroy(output_brigade);
+ /*
+ * Clear output_brigade to remove possible buckets that remained there
+ * after an error.
+ */
+ apr_brigade_cleanup(output_brigade);
if (status != APR_SUCCESS) {
/* We had a failure: Close connection to backend */
@@ -409,8 +417,36 @@
"proxy: send body failed to %pI (%s)",
conn->worker->cp->addr,
conn->worker->hostname);
- return HTTP_SERVICE_UNAVAILABLE;
+ /*
+ * If we already send data, signal a broken backend connection
+ * upwards in the chain.
+ */
+ if (data_sent) {
+ ap_proxy_backend_broke(r, output_brigade);
+ /* Return DONE to avoid error messages being added to the stream */
+ rv = DONE;
+ } else
+ rv = HTTP_SERVICE_UNAVAILABLE;
+ }
+
+ /*
+ * Ensure that we sent an EOS bucket thru the filter chain, if we already
+ * have sent some data. Maybe ap_proxy_backend_broke was called and added
+ * one to the brigade already. So we should not do this in this case.
+ */
+ if (data_sent && !r->eos_sent && APR_BRIGADE_EMPTY(output_brigade)) {
+ e = apr_bucket_eos_create(r->connection->bucket_alloc);
+ APR_BRIGADE_INSERT_TAIL(output_brigade, e);
}
+
+ /* If we have added something to the brigade above, sent it */
+ if (!APR_BRIGADE_EMPTY(output_brigade))
+ ap_pass_brigade(r->output_filters, output_brigade);
+
+ apr_brigade_destroy(output_brigade);
+
+ if (rv)
+ return rv;
/* Nice we have answer to send to the client */
if (result == CMD_AJP13_END_RESPONSE && isok) {
Modified: httpd/httpd/trunk/modules/proxy/mod_proxy_http.c
URL: http://svn.apache.org/viewcvs/httpd/httpd/trunk/modules/proxy/mod_proxy_http.c?rev=365374&r1=365373&r2=365374&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/proxy/mod_proxy_http.c (original)
+++ httpd/httpd/trunk/modules/proxy/mod_proxy_http.c Mon Jan 2 08:39:22 2006
@@ -1199,6 +1199,7 @@
* are being read. */
int pread_len = 0;
apr_table_t *save_table;
+ int backend_broke = 0;
bb = apr_brigade_create(p, c->bucket_alloc);
@@ -1486,13 +1487,9 @@
*/
ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c,
"proxy: error reading response");
- 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_proxy_backend_broke(r, bb);
ap_pass_brigade(r->output_filters, bb);
+ backend_broke = 1;
backend->close = 1;
break;
}
@@ -1560,7 +1557,7 @@
} while (interim_response);
/* If our connection with the client is to be aborted, return DONE. */
- if (c->aborted) {
+ if (c->aborted || backend_broke) {
return DONE;
}
Modified: httpd/httpd/trunk/modules/proxy/proxy_util.c
URL: http://svn.apache.org/viewcvs/httpd/httpd/trunk/modules/proxy/proxy_util.c?rev=365374&r1=365373&r2=365374&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/proxy/proxy_util.c (original)
+++ httpd/httpd/trunk/modules/proxy/proxy_util.c Mon Jan 2 08:39:22 2006
@@ -2129,3 +2129,17 @@
lb_workers_limit = proxy_lb_workers + PROXY_DYNAMIC_BALANCER_LIMIT;
return lb_workers_limit;
}
+
+PROXY_DECLARE(void) ap_proxy_backend_broke(request_rec *r,
+ apr_bucket_brigade *brigade)
+{
+ apr_bucket *e;
+ conn_rec *c = r->connection;
+
+ r->no_cache = 1;
+ e = ap_bucket_error_create(HTTP_BAD_GATEWAY, NULL, c->pool,
+ c->bucket_alloc);
+ APR_BRIGADE_INSERT_TAIL(brigade, e);
+ e = apr_bucket_eos_create(c->bucket_alloc);
+ APR_BRIGADE_INSERT_TAIL(brigade, e);
+}