| 5570 | } |
| 5571 | |
| 5572 | static int proxy_tunnel_forward(proxy_tunnel_rec *tunnel, |
| 5573 | struct proxy_tunnel_conn *in) |
| 5574 | { |
| 5575 | struct proxy_tunnel_conn *out = in->other; |
| 5576 | apr_status_t rv; |
| 5577 | int sent = 0; |
| 5578 | |
| 5579 | ap_log_rerror(APLOG_MARK, APLOG_TRACE8, 0, tunnel->r, |
| 5580 | "proxy: %s: %s input ready", |
| 5581 | tunnel->scheme, in->name); |
| 5582 | |
| 5583 | rv = ap_proxy_transfer_between_connections(tunnel->r, |
| 5584 | in->c, out->c, |
| 5585 | in->bb, out->bb, |
| 5586 | in->name, &sent, |
| 5587 | tunnel->read_buf_size, |
| 5588 | AP_PROXY_TRANSFER_YIELD_PENDING | |
| 5589 | AP_PROXY_TRANSFER_YIELD_MAX_READS); |
| 5590 | if (sent && out == tunnel->client) { |
| 5591 | tunnel->replied = 1; |
| 5592 | } |
| 5593 | if (rv != APR_SUCCESS) { |
| 5594 | if (APR_STATUS_IS_INCOMPLETE(rv)) { |
| 5595 | /* Pause POLLIN while waiting for POLLOUT on the other |
| 5596 | * side, hence avoid filling the output filters even |
| 5597 | * more to avoid blocking there. |
| 5598 | */ |
| 5599 | ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, tunnel->r, |
| 5600 | "proxy: %s: %s wait writable", |
| 5601 | tunnel->scheme, out->name); |
| 5602 | } |
| 5603 | else if (APR_STATUS_IS_EOF(rv)) { |
| 5604 | /* Stop POLLIN and wait for POLLOUT (flush) on the |
| 5605 | * other side to shut it down. |
| 5606 | */ |
| 5607 | ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, tunnel->r, |
| 5608 | "proxy: %s: %s read shutdown", |
| 5609 | tunnel->scheme, in->name); |
| 5610 | if (tunnel->nohalfclose) { |
| 5611 | /* No half-close forwarding, we are done both ways as |
| 5612 | * soon as one side shuts down. |
| 5613 | */ |
| 5614 | return DONE; |
| 5615 | } |
| 5616 | in->down_in = 1; |
| 5617 | } |
| 5618 | else { |
| 5619 | /* Real failure, bail out */ |
| 5620 | return HTTP_INTERNAL_SERVER_ERROR; |
| 5621 | } |
| 5622 | |
| 5623 | del_pollset(tunnel->pollset, in->pfd, APR_POLLIN); |
| 5624 | if (out->pfd->desc_type == APR_POLL_SOCKET) { |
| 5625 | /* if the output is a SOCKET, we can stop polling the input |
| 5626 | * until the output signals POLLOUT again. */ |
| 5627 | add_pollset(tunnel->pollset, out->pfd, APR_POLLOUT); |
| 5628 | } |
| 5629 | else { |
no test coverage detected