mirror of
https://github.com/apache/httpd.git
synced 2025-08-08 15:02:10 +03:00
* Introduce ap_proxy_transfer_between_connections
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1728478 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
@@ -1175,6 +1175,39 @@ PROXY_DECLARE(apr_status_t) ap_proxy_buckets_lifetime_transform(request_rec *r,
|
|||||||
apr_bucket_brigade *from,
|
apr_bucket_brigade *from,
|
||||||
apr_bucket_brigade *to);
|
apr_bucket_brigade *to);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sends all data that can be read non blocking from the input filter chain of
|
||||||
|
* c_i and send it down the output filter chain of c_o. For reading it uses
|
||||||
|
* the bucket brigade bb_i which should be created from the bucket allocator
|
||||||
|
* associated with c_i. For sending through the output filter chain it uses
|
||||||
|
* the bucket brigade bb_o which should be created from the bucket allocator
|
||||||
|
* associated with c_o. In order to get the buckets from bb_i to bb_o
|
||||||
|
* ap_proxy_buckets_lifetime_transform is used.
|
||||||
|
*
|
||||||
|
* @param r request_rec of the actual request. Used for logging purposes
|
||||||
|
* @param c_i inbound connection conn_rec
|
||||||
|
* @param c_o outbound connection conn_rec
|
||||||
|
* @param bb_i bucket brigade for pulling data from the inbound connection
|
||||||
|
* @param bb_o bucket brigade for sending data through the outbound connection
|
||||||
|
* @param name string for logging from where data was pulled
|
||||||
|
* @param sent if not NULL will be set to 1 if data was sent through c_o
|
||||||
|
* @param bsize maximum amount of data pulled in one iteration from c_i
|
||||||
|
* @param after if set flush data on c_o only once after the loop
|
||||||
|
* @return apr_status_t of the operation. Could be any error returned from
|
||||||
|
* either the input filter chain of c_i or the output filter chain
|
||||||
|
* of c_o. APR_EPIPE if the outgoing connection was aborted.
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
|
||||||
extern module PROXY_DECLARE_DATA proxy_module;
|
extern module PROXY_DECLARE_DATA proxy_module;
|
||||||
|
|
||||||
#endif /*MOD_PROXY_H*/
|
#endif /*MOD_PROXY_H*/
|
||||||
|
@@ -3735,6 +3735,90 @@ PROXY_DECLARE(apr_status_t) ap_proxy_buckets_lifetime_transform(request_rec *r,
|
|||||||
return rv;
|
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)
|
void proxy_util_register_hooks(apr_pool_t *p)
|
||||||
{
|
{
|
||||||
APR_REGISTER_OPTIONAL_FN(ap_proxy_retry_worker);
|
APR_REGISTER_OPTIONAL_FN(ap_proxy_retry_worker);
|
||||||
|
Reference in New Issue
Block a user