Commit 2d5c6f78 authored by Jim Jagielski's avatar Jim Jagielski
Browse files

Merge r1657636, r1657638, r1669130 from trunk:

mod_proxy_connect/wstunnel: If both client and backend sides get readable
at the same time, don't lose errors occuring while forwarding on the first
side when none occurs next on the other side, and abort.


CHANGES: Follow up to r1657636, clarify message.


mod_proxy_{connect,wstunnel}: follow up to r1657636.
Since rv is not used as an apr_status_t in the loop (it's logging is done by
proxy_{connect,wstunnel}_transfer() when necessary/relevent), use a boolean
instead to avoid the ugly ORs between APR error codes.

Submitted by: ylavic
Reviewed/backported by: jim


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1670324 13f79535-47bb-0310-9956-ffa450edef68
parent 90cdbfff
Loading
Loading
Loading
Loading
+4 −0
Changes for CHANGES: 4 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -30,6 +30,10 @@ Changes with Apache 2.4.13
     a ProxyRemote forward-proxy.  PR 55892.  [Hendrik Harms <hendrik.harms
     gmail com>, William Rowe, Yann Ylavic]

  *) mod_proxy_connect/wstunnel: If both client and backend sides get readable
     at the same time, don't lose errors occuring while forwarding on the first
     side when none occurs next on the other side, and abort.  [Yann Ylavic]

  *) mod_rewrite: Improve relative substitutions in per-directory/htaccess
     context for directories found by mod_userdir and mod_alias.  These no
     longer require RewriteBase to be specified. [Eric Covener]
+14 −14
Changes for modules/proxy/mod_proxy_connect.c: 14 added lines, 14 removed lines.
Original line number Diff line number Diff line
@@ -203,6 +203,7 @@ static int proxy_connect_handler(request_rec *r, proxy_worker *worker,
    apr_socket_t *sock;
    conn_rec *c = r->connection;
    conn_rec *backconn;
    int done = 0;

    apr_bucket_brigade *bb = apr_brigade_create(p, c->bucket_alloc);
    apr_status_t rv;
@@ -413,9 +414,9 @@ static int proxy_connect_handler(request_rec *r, proxy_worker *worker,
    r->proto_input_filters = c->input_filters;
/*    r->sent_bodyct = 1;*/

    while (1) { /* Infinite loop until error (one side closes the connection) */
        if ((rv = apr_pollset_poll(pollset, -1, &pollcnt, &signalled))
            != APR_SUCCESS) {
    do { /* Loop until done (one side closes the connection, or an error) */
        rv = apr_pollset_poll(pollset, -1, &pollcnt, &signalled);
        if (rv != APR_SUCCESS) {
            if (APR_STATUS_IS_EINTR(rv)) {
                continue;
            }
@@ -438,13 +439,14 @@ static int proxy_connect_handler(request_rec *r, proxy_worker *worker,
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01025)
                                  "sock was readable");
#endif
                    rv = proxy_connect_transfer(r, backconn, c, bb, "sock");
                    done |= proxy_connect_transfer(r, backconn, c, bb,
                                                   "sock") != APR_SUCCESS;
                }
                else if (pollevent & APR_POLLERR) {
                    rv = APR_EPIPE;
                    backconn->aborted = 1;
                    ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r, APLOGNO(01026)
                                  "err on backconn");
                    backconn->aborted = 1;
                    done = 1;
                }
            }
            else if (cur->desc.s == client_socket) {
@@ -454,26 +456,24 @@ static int proxy_connect_handler(request_rec *r, proxy_worker *worker,
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01027)
                                  "client was readable");
#endif
                    rv = proxy_connect_transfer(r, c, backconn, bb, "client");
                    done |= proxy_connect_transfer(r, c, backconn, bb,
                                                   "client") != APR_SUCCESS;
                }
                else if (pollevent & APR_POLLERR) {
                    rv = APR_EPIPE;
                    c->aborted = 1;
                    ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r, APLOGNO(02827)
                                  "err on client");
                    c->aborted = 1;
                    done = 1;
                }
            }
            else {
                rv = APR_EBADF;
                ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(01028)
                              "unknown socket in pollset");
                done = 1;
            }

        }
        if (rv != APR_SUCCESS) {
            break;
        }
    }
    } while (!done);

    ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
                  "finished with poll() - cleaning up");
+18 −18
Changes for modules/proxy/mod_proxy_wstunnel.c: 18 added lines, 18 removed lines.
Original line number Diff line number Diff line
@@ -90,10 +90,10 @@ static int proxy_wstunnel_canon(request_rec *r, char *url)
}


static int proxy_wstunnel_transfer(request_rec *r, conn_rec *c_i, conn_rec *c_o,
static apr_status_t proxy_wstunnel_transfer(request_rec *r, conn_rec *c_i, conn_rec *c_o,
                                     apr_bucket_brigade *bb, char *name)
{
    int rv;
    apr_status_t rv;
#ifdef DEBUGGING
    apr_off_t len;
#endif
@@ -167,6 +167,7 @@ static int proxy_wstunnel_request(apr_pool_t *p, request_rec *r,
    char *old_te_val = NULL;
    apr_bucket_brigade *bb = apr_brigade_create(p, c->bucket_alloc);
    apr_socket_t *client_socket = ap_get_conn_socket(c);
    int done = 0;

    header_brigade = apr_brigade_create(p, backconn->bucket_alloc);

@@ -224,9 +225,9 @@ static int proxy_wstunnel_request(apr_pool_t *p, request_rec *r,
     * nothing else is attempted on the connection after returning. */
    c->keepalive = AP_CONN_CLOSE;

    while (1) { /* Infinite loop until error (one side closes the connection) */
        if ((rv = apr_pollset_poll(pollset, -1, &pollcnt, &signalled))
            != APR_SUCCESS) {
    do { /* Loop until done (one side closes the connection, or an error) */
        rv = apr_pollset_poll(pollset, -1, &pollcnt, &signalled);
        if (rv != APR_SUCCESS) {
            if (APR_STATUS_IS_EINTR(rv)) {
                continue;
            }
@@ -244,18 +245,19 @@ static int proxy_wstunnel_request(apr_pool_t *p, request_rec *r,
                if (pollevent & (APR_POLLIN | APR_POLLHUP)) {
                    ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, APLOGNO(02446)
                                  "sock was readable");
                    rv = proxy_wstunnel_transfer(r, backconn, c, bb, "sock");
                    done |= proxy_wstunnel_transfer(r, backconn, c, bb,
                                                    "sock") != APR_SUCCESS;
                }
                else if (pollevent & APR_POLLERR) {
                    rv = APR_EPIPE;
                    backconn->aborted = 1;
                    ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r, APLOGNO(02447)
                            "error on backconn");
                    backconn->aborted = 1;
                    done = 1;
                }
                else { 
                    rv = APR_EGENERAL;
                    ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r, APLOGNO(02605)
                            "unknown event on backconn %d", pollevent);
                    done = 1;
                }
            }
            else if (cur->desc.s == client_socket) {
@@ -263,31 +265,29 @@ static int proxy_wstunnel_request(apr_pool_t *p, request_rec *r,
                if (pollevent & (APR_POLLIN | APR_POLLHUP)) {
                    ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, APLOGNO(02448)
                                  "client was readable");
                    rv = proxy_wstunnel_transfer(r, c, backconn, bb, "client");
                    done |= proxy_wstunnel_transfer(r, c, backconn, bb,
                                                    "client") != APR_SUCCESS;
                }
                else if (pollevent & APR_POLLERR) {
                    rv = APR_EPIPE;
                    c->aborted = 1;
                    ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, APLOGNO(02607)
                            "error on client conn");
                    c->aborted = 1;
                    done = 1;
                }
                else { 
                    rv = APR_EGENERAL;
                    ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r, APLOGNO(02606)
                            "unknown event on client conn %d", pollevent);
                    done = 1;
                }
            }
            else {
                rv = APR_EBADF;
                ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02449)
                              "unknown socket in pollset");
                done = 1;
            }

        }
        if (rv != APR_SUCCESS) {
            break;
        }
    }
    } while (!done);

    ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
                  "finished with poll() - cleaning up");