summaryrefslogtreecommitdiffstats
path: root/modules/proxy/proxy_util.c
diff options
context:
space:
mode:
authorRuediger Pluem <rpluem@apache.org>2016-02-04 14:41:19 +0100
committerRuediger Pluem <rpluem@apache.org>2016-02-04 14:41:19 +0100
commitfbf68524d3f4e3bfa4e707b853fef89c8c6ca827 (patch)
treeb714e7bd40f771593512821085a2e0b774d2ffb0 /modules/proxy/proxy_util.c
parentEnabling a worker via health-check also moves them out of (diff)
downloadapache2-fbf68524d3f4e3bfa4e707b853fef89c8c6ca827.tar.xz
apache2-fbf68524d3f4e3bfa4e707b853fef89c8c6ca827.zip
* Introduce ap_proxy_transfer_between_connections
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1728478 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to '')
-rw-r--r--modules/proxy/proxy_util.c84
1 files changed, 84 insertions, 0 deletions
diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c
index 35e67f40d0..92e0c9cd7a 100644
--- a/modules/proxy/proxy_util.c
+++ b/modules/proxy/proxy_util.c
@@ -3735,6 +3735,90 @@ PROXY_DECLARE(apr_status_t) ap_proxy_buckets_lifetime_transform(request_rec *r,
return rv;
}
+PROXY_DECLARE(apr_status_t) ap_proxy_transfer_between_connections(
+ request_rec *r,
+ conn_rec *c_i,
+ conn_rec *c_o,
+ apr_bucket_brigade *bb_i,
+ apr_bucket_brigade *bb_o,
+ const char *name,
+ int *sent,
+ apr_off_t bsize,
+ int after)
+{
+ apr_status_t rv;
+#ifdef DEBUGGING
+ apr_off_t len;
+#endif
+
+ do {
+ apr_brigade_cleanup(bb_i);
+ rv = ap_get_brigade(c_i->input_filters, bb_i, AP_MODE_READBYTES,
+ APR_NONBLOCK_READ, bsize);
+ if (rv == APR_SUCCESS) {
+ if (c_o->aborted) {
+ return APR_EPIPE;
+ }
+ if (APR_BRIGADE_EMPTY(bb_i)) {
+ break;
+ }
+#ifdef DEBUGGING
+ len = -1;
+ apr_brigade_length(bb_i, 0, &len);
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO()
+ "ap_proxy_transfer_between_connections: "
+ "read %" APR_OFF_T_FMT
+ " bytes from %s", len, name);
+#endif
+ if (sent) {
+ *sent = 1;
+ }
+ ap_proxy_buckets_lifetime_transform(r, bb_i, bb_o);
+ if (!after) {
+ apr_bucket *b;
+
+ /*
+ * Do not use ap_fflush here since this would cause the flush
+ * bucket to be sent in a separate brigade afterwards which
+ * causes some filters to set aside the buckets from the first
+ * brigade and process them when the flush arrives in the second
+ * brigade. As set asides of our transformed buckets involve
+ * memory copying we try to avoid this. If we have the flush
+ * bucket in the first brigade they directly process the
+ * buckets without setting them aside.
+ */
+ b = apr_bucket_flush_create(bb_o->bucket_alloc);
+ APR_BRIGADE_INSERT_TAIL(bb_o, b);
+ }
+ rv = ap_pass_brigade(c_o->output_filters, bb_o);
+ if (rv != APR_SUCCESS) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO()
+ "ap_proxy_transfer_between_connections: "
+ "error on %s - ap_pass_brigade",
+ name);
+ }
+ } else if (!APR_STATUS_IS_EAGAIN(rv) && !APR_STATUS_IS_EOF(rv)) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, APLOGNO()
+ "ap_proxy_transfer_between_connections: "
+ "error on %s - ap_get_brigade",
+ name);
+ }
+ } while (rv == APR_SUCCESS);
+
+ if (after) {
+ ap_fflush(c_o->output_filters, bb_o);
+ }
+
+ ap_log_rerror(APLOG_MARK, APLOG_TRACE2, rv, r,
+ "ap_proxy_transfer_between_connections complete");
+
+ if (APR_STATUS_IS_EAGAIN(rv)) {
+ rv = APR_SUCCESS;
+ }
+
+ return rv;
+}
+
void proxy_util_register_hooks(apr_pool_t *p)
{
APR_REGISTER_OPTIONAL_FN(ap_proxy_retry_worker);