diff --git a/modules/proxy/mod_proxy_connect.c b/modules/proxy/mod_proxy_connect.c index c78ff72..073d991 100644 --- a/modules/proxy/mod_proxy_connect.c +++ b/modules/proxy/mod_proxy_connect.c @@ -539,16 +539,25 @@ static int proxy_connect_handler(request_rec *r, proxy_worker *worker, if (revents & APR_POLLOUT) { ap_log_rerror(APLOG_MARK, APLOG_TRACE8, 0, r, "%s is writable", conn->name); - - rv = conn->core_output(conn->core_filter, NULL); - if (rv != APR_SUCCESS && !APR_STATUS_IS_EAGAIN(rv)) { + + if (other->c->data_in_input_filters && !conn->c->data_in_output_filters) { + rv = ap_proxy_transfer_between_connections(r, + other->c, conn->c, + other->bb, conn->bb, + other->name, + NULL, read_buf_size, + AP_PROXY_TRANSFER_CHECK_FULL); + } else { + rv = conn->core_output(conn->core_filter, NULL); + } + if (rv != APR_SUCCESS && !APR_STATUS_IS_EAGAIN(rv) && !APR_STATUS_IS_INCOMPLETE(rv)) { /* Real failure, bail out */ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO() "%s output", conn->name); failed = 1; break; } - if (!conn->c->data_in_output_filters) { + if (!conn->c->data_in_output_filters && ! other->c->data_in_input_filters) { /* Pending data now flushed, stop POLLOUT on this conn, and * restore POLLIN on the other one unless it's shut down * for read already (in which case we just forward the diff --git a/server/core_filters.c b/server/core_filters.c index 238b5d0..c2f658c 100644 --- a/server/core_filters.c +++ b/server/core_filters.c @@ -103,13 +103,16 @@ apr_status_t ap_core_input_filter(ap_filter_t *f, apr_bucket_brigade *b, ap_input_mode_t mode, apr_read_type_e block, apr_off_t readbytes) { + conn_rec *conn = f->c; apr_status_t rv; core_net_rec *net = f->ctx; core_ctx_t *ctx = net->in_ctx; const char *str; apr_size_t len; - if (mode == AP_MODE_INIT) { + conn->data_in_input_filters = 0; + + if (mode == AP_MODE_INIT) { /* * this mode is for filters that might need to 'initialize' * a connection before reading request data from a client. @@ -333,6 +336,10 @@ apr_status_t ap_core_input_filter(ap_filter_t *f, apr_bucket_brigade *b, /* Take what was originally there and place it back on ctx->b */ APR_BRIGADE_CONCAT(ctx->b, ctx->tmpbb); + + if ( !APR_BRIGADE_EMPTY(ctx->b) ) { + conn->data_in_input_filters = 1; + } } return APR_SUCCESS; }