]> granicus.if.org Git - apache/commitdiff
Merge r1657636, r1657638, r1669130 from trunk:
authorJim Jagielski <jim@apache.org>
Tue, 31 Mar 2015 12:53:00 +0000 (12:53 +0000)
committerJim Jagielski <jim@apache.org>
Tue, 31 Mar 2015 12:53:00 +0000 (12:53 +0000)
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

CHANGES
modules/proxy/mod_proxy_connect.c
modules/proxy/mod_proxy_wstunnel.c

diff --git a/CHANGES b/CHANGES
index dacac4c54925f24b00b856f229300bf0ac455db9..e2adc759e5b25dc688508d2af3639663dfb98ca9 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -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]
index 55079148f0e5286ff86c21e219473a1a13e42ee8..e958b4476c9b05265250a1c456bbe509d6180fbc 100644 (file)
@@ -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");
index 1eb6ac89ef05398e216a18d118c66dfbe091045a..1dd7e658e975c3d4a846a54a910ac5813a76dd2e 100644 (file)
@@ -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
@@ -137,7 +137,7 @@ static int proxy_wstunnel_transfer(request_rec *r, conn_rec *c_i, conn_rec *c_o,
     if (APR_STATUS_IS_EAGAIN(rv)) {
         rv = APR_SUCCESS;
     }
-   
+
     return rv;
 }
 
@@ -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");