]> granicus.if.org Git - apache/commitdiff
Merge r1587036, r1587040, r1587053, r1587654 from trunk:
authorJim Jagielski <jim@apache.org>
Fri, 18 Apr 2014 15:28:41 +0000 (15:28 +0000)
committerJim Jagielski <jim@apache.org>
Fri, 18 Apr 2014 15:28:41 +0000 (15:28 +0000)
  *) mod_proxy_wstunnel: Don't pool backend websockets connections,
     because we need to handshake every time. PR 55890.
     [Eric Covener]

actually remove mod_reqtimeout, since the util_filter functions involved
only manipulate c->input_filters no matter what we pass. We need to make
copies of c->input_filters after, not before, it skips over reqtimeout.

Note: reqtimeout doesn't really interfere today with normal operation,
but this is misleading/confusing when dealing with other
wstunnel issues.

cleanup wstunnel error handling

Submitted By: covener, ylavic, Edward Lu
Commited By: covener

followup to r1587036.

if backend->close is set too early, proxy_util.c will close it right
away and then blow away the field.

Submitted by: covener
Reviewed/backported by: jim

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1588495 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
STATUS
modules/proxy/mod_proxy_wstunnel.c

diff --git a/CHANGES b/CHANGES
index 48003f12128e9261c86c0eb876fa2e6d2d4be623..fa61a0e2055f1632a092cd9729f8cb360f3016f8 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -49,6 +49,14 @@ Changes with Apache 2.4.10
      when the thread/connection relationship changes.  (Should be implemented
      for any third-party async MPMs.)  [Jeff Trawick]
 
+  *) mod_proxy_wstunnel: Don't issue AH02447 and log a 500 on routine 
+     hangups from websockets origin servers. PR 56299
+     [Yann Ylavic, Edward Lu <Chaosed0 gmail com>, Eric Covener] 
+
+  *) mod_proxy_wstunnel: Don't pool backend websockets connections,
+     because we need to handshake every time. PR 55890.
+     [Eric Covener]
+
   *) mod_lua: Redesign how request record table access behaves,
      in order to utilize the request record from within these tables.
      [Daniel Gruno]
diff --git a/STATUS b/STATUS
index eec238a4e1e05b41272123d9c6e19a40be377e1c..f06743b1546bad50aca004ec78a4248b20b91ff5 100644 (file)
--- a/STATUS
+++ b/STATUS
@@ -100,14 +100,6 @@ RELEASE SHOWSTOPPERS:
 PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
   [ start all new proposals below, under PATCHES PROPOSED. ]
 
-   * mod_proxy_wstunnel: wstunnel rollup for connection handling
-     trunk patch: http://svn.apache.org/r1587036 (set backend->close)
-                  http://svn.apache.org/r1587040 (remove reqtimeout)
-                  http://svn.apache.org/r1587053 (poll fixes / frontend connection close)
-                  http://svn.apache.org/r1587654 (set backend->close)
-     2.4.x patch: http://people.apache.org/~covener/patches/httpd-2.4.x-wstunnel.diff 
-     +1: covener, ylavic, jim
-
    * mod_ssl: workaround for SSLCertificateFile in 2.4.8 or later,
      when used with OpenSSL prior to 0.9.8h and not specifying
      an SSLCertificateChainFile (PR 56410)
index d17eaff640f546afbf0a78f300b5dbaec8280e7e..aa008fa41b0f4b6b63cea77447c4e2bf740e2aa1 100644 (file)
@@ -103,10 +103,12 @@ static int proxy_wstunnel_transfer(request_rec *r, conn_rec *c_i, conn_rec *c_o,
         rv = ap_get_brigade(c_i->input_filters, bb, AP_MODE_READBYTES,
                             APR_NONBLOCK_READ, AP_IOBUFSIZE);
         if (rv == APR_SUCCESS) {
-            if (c_o->aborted)
+            if (c_o->aborted) {
                 return APR_EPIPE;
-            if (APR_BRIGADE_EMPTY(bb))
+            }
+            if (APR_BRIGADE_EMPTY(bb)) {
                 break;
+            }
 #ifdef DEBUGGING
             len = -1;
             apr_brigade_length(bb, 0, &len);
@@ -130,9 +132,12 @@ static int proxy_wstunnel_transfer(request_rec *r, conn_rec *c_i, conn_rec *c_o,
         }
     } while (rv == APR_SUCCESS);
 
+    ap_log_rerror(APLOG_MARK, APLOG_TRACE2, rv, r, "wstunnel_transfer complete");
+
     if (APR_STATUS_IS_EAGAIN(rv)) {
         rv = APR_SUCCESS;
     }
+   
     return rv;
 }
 
@@ -178,7 +183,6 @@ static int ap_proxy_wstunnel_request(apr_pool_t *p, request_rec *r,
     conn_rec *c = r->connection;
     apr_socket_t *sock = conn->sock;
     conn_rec *backconn = conn->connection;
-    int client_error = 0;
     char *buf;
     apr_bucket_brigade *header_brigade;
     apr_bucket *e;
@@ -224,7 +228,7 @@ static int ap_proxy_wstunnel_request(apr_pool_t *p, request_rec *r,
 
     pollfd.p = p;
     pollfd.desc_type = APR_POLL_SOCKET;
-    pollfd.reqevents = APR_POLLIN;
+    pollfd.reqevents = APR_POLLIN | APR_POLLHUP;
     pollfd.desc.s = sock;
     pollfd.client_data = NULL;
     apr_pollset_add(pollset, &pollfd);
@@ -232,13 +236,16 @@ static int ap_proxy_wstunnel_request(apr_pool_t *p, request_rec *r,
     pollfd.desc.s = client_socket;
     apr_pollset_add(pollset, &pollfd);
 
+    remove_reqtimeout(c->input_filters);
 
     r->output_filters = c->output_filters;
     r->proto_output_filters = c->output_filters;
     r->input_filters = c->input_filters;
     r->proto_input_filters = c->input_filters;
 
-    remove_reqtimeout(r->input_filters);
+    /* This handler should take care of the entire connection; make it so that
+     * 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))
@@ -257,38 +264,34 @@ static int ap_proxy_wstunnel_request(apr_pool_t *p, request_rec *r,
 
             if (cur->desc.s == sock) {
                 pollevent = cur->rtnevents;
-                if (pollevent & APR_POLLIN) {
+                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");
-                    }
-                else if ((pollevent & APR_POLLERR)
-                         || (pollevent & APR_POLLHUP)) {
-                         rv = APR_EPIPE;
-                         ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r, APLOGNO(02447)
-                                       "err/hup on backconn");
+                }
+                else if (pollevent & APR_POLLERR) {
+                    rv = APR_EPIPE;
+                    ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r, APLOGNO(02447)
+                            "error on backconn");
                 }
                 else { 
                     rv = APR_EGENERAL;
                     ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r, APLOGNO(02605)
                             "unknown event on backconn %d", pollevent);
                 }
-                if (rv != APR_SUCCESS)
-                    client_error = 1;
             }
             else if (cur->desc.s == client_socket) {
                 pollevent = cur->rtnevents;
-                if (pollevent & APR_POLLIN) {
+                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");
                 }
-                else if ((pollevent & APR_POLLERR)
-                        || (pollevent & APR_POLLHUP)) {
+                else if (pollevent & APR_POLLERR) {
                     rv = APR_EPIPE;
                     c->aborted = 1;
                     ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, APLOGNO(02607)
-                            "err/hup on client conn");
+                            "error on client conn");
                 }
                 else { 
                     rv = APR_EGENERAL;
@@ -311,9 +314,6 @@ static int ap_proxy_wstunnel_request(apr_pool_t *p, request_rec *r,
     ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
                   "finished with poll() - cleaning up");
 
-    if (client_error) {
-        return HTTP_INTERNAL_SERVER_ERROR;
-    }
     return OK;
 }
 
@@ -386,7 +386,10 @@ static int proxy_wstunnel_handler(request_rec *r, proxy_worker *worker,
             if ((status = ap_proxy_connection_create(scheme, backend,
                                                      c, r->server)) != OK)
                 break;
-         }
+        }
+
+        backend->close = 1; /* must be after ap_proxy_determine_connection */
+
 
         /* Step Three: Process the Request */
         status = ap_proxy_wstunnel_request(p, r, backend, worker, conf, uri, locurl,