diff --git a/modules/proxy/mod_proxy_connect.c b/modules/proxy/mod_proxy_connect.c index d21f616..f2039c3 100644 --- a/modules/proxy/mod_proxy_connect.c +++ b/modules/proxy/mod_proxy_connect.c @@ -22,7 +22,7 @@ #define CONN_BLKSZ AP_IOBUFSIZE module AP_MODULE_DECLARE_DATA proxy_connect_module; - +#define DEBUGGING 1 /* * This handles Netscape CONNECT method secure proxy requests. * A connection is opened to the specified host and data is @@ -442,7 +442,9 @@ static int proxy_connect_handler(request_rec *r, proxy_worker *worker, backend->core_filter = backend->core_filter->next; } backend->core_output = backend->core_filter->frec->filter_func.out_func; - + ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "core_output: name(%s)", backend->core_filter->frec->name); + ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "core_output: name(%s)", + client->core_filter->frec->name); apr_socket_timeout_get(client->pfd.desc.s, &client->timeout); apr_socket_timeout_get(backend->pfd.desc.s, &backend->timeout); timeout = client->timeout < backend->timeout ? client->timeout @@ -537,16 +539,29 @@ 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); + if (APR_STATUS_IS_EOF(rv)) { + other->shutdown |= PROXY_SHUTDOWN_READ; + rv = APR_SUCCESS; + } + } 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..074d826 100644 --- a/server/core_filters.c +++ b/server/core_filters.c @@ -103,12 +103,13 @@ 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; - + conn->data_in_input_filters = 0; if (mode == AP_MODE_INIT) { /* * this mode is for filters that might need to 'initialize' @@ -180,8 +181,9 @@ apr_status_t ap_core_input_filter(ap_filter_t *f, apr_bucket_brigade *b, * mean that there is another request, just a blank line. */ while (1) { - if (APR_BRIGADE_EMPTY(ctx->b)) + if (APR_BRIGADE_EMPTY(ctx->b)) { return APR_EOF; + } e = APR_BRIGADE_FIRST(ctx->b); @@ -333,6 +335,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; }