]> granicus.if.org Git - apache/commitdiff
Merge from trunk:
authorEric Covener <covener@apache.org>
Mon, 5 Jun 2017 12:07:43 +0000 (12:07 +0000)
committerEric Covener <covener@apache.org>
Mon, 5 Jun 2017 12:07:43 +0000 (12:07 +0000)
Add upgrade parameter to mod_proxy_wstunnel.
That allows to upgrade to jboss-remoting for example
or to run an HTTP/1.1 backend that needs to upgrade to
WebSocket.
See also:
 https://issues.jboss.org/browse/JBCS-254
 https://issues.jboss.org/browse/JBCS-291

whitespace only

Submitted By: jfclere
Reviewed By: covener, jim, ylavic

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

CHANGES
STATUS
docs/manual/mod/mod_proxy.xml
docs/manual/mod/mod_proxy_wstunnel.xml
modules/proxy/mod_proxy.c
modules/proxy/mod_proxy.h
modules/proxy/mod_proxy_wstunnel.c

diff --git a/CHANGES b/CHANGES
index a817ae0f209aaea6bafc6038fae9545445d024b2..301cb7061c95ae3fbfd11a0b1697336052b8a5eb 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -2,6 +2,9 @@
 
 Changes with Apache 2.4.26
 
+  *) mod_proxy_wstunnel: Add "upgrade" parameter to allow upgrade to other
+     protocols.  [Jean-Frederic Clere]
+
   *) MPMs unix: Place signals handlers and helpers out of DSOs to avoid
      a possible crash if a signal is caught during (graceful) restart.
      PR 60487.  [Yann Ylavic]
diff --git a/STATUS b/STATUS
index 8c740c44995ba9b472afae670e5de7c085051142..7d9f5ed301c5b76bac0677f4200766991967e419 100644 (file)
--- a/STATUS
+++ b/STATUS
@@ -120,13 +120,6 @@ RELEASE SHOWSTOPPERS:
 PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
   [ start all new proposals below, under PATCHES PROPOSED. ]
 
-  *) proxy_wstunnel: Restore ability to process other Upgrade: protocols which was
-     blocked in r1674632/r1674661.
-     trunk patch: http://svn.apache.org/r1792092
-                  http://svn.apache.org/r1796864
-     2.4.x patch: svn merge -c  1792092,1796864 ^/httpd/httpd/trunk .
-     +1: covener, jim, ylavic
-
   *) worker, prefork: save some cycles by not copying the listener's pollfds
                       for each pollset operation
      trunk patch: http://svn.apache.org/r1662437
index b0e0b560f8d2984bd12f86f0affcb84523c87c9e..094f1de1134bfd0151fe91efa2bbdbdba491a7f3 100644 (file)
@@ -1189,6 +1189,16 @@ ProxyPass "/mirror/foo" "http://backend.example.com"
         <td><p>Name of the provider used by <module>mod_proxy_fdpass</module>.
         See the documentation of this module for more details.</p>
     </td></tr>
+    <tr><td>secret</td>
+        <td>-</td>
+        <td><p>Value of secret used by <module>mod_proxy_ajp</module>.
+        See the documentation of this module for more details.</p>
+    </td></tr>
+    <tr><td>upgrade</td>
+        <td>WebSocket</td>
+        <td><p>Protocol accepted in the Upgrade header by <module>mod_proxy_wstunnel</module>.
+        See the documentation of this module for more details.</p>
+    </td></tr>
 
     </table>
 
index 907576766db757317cf2c23faa41547b2a483580..639131ba2d7ae86529038f176ef12893b4f511c0 100644 (file)
@@ -51,6 +51,11 @@ ProxyPass "/wss2/" "wss://echo.websocket.org/"
     </highlight>
 
 <p>Load balancing for multiple backends can be achieved using <module>mod_proxy_balancer</module>.</p>
+
+<p>In fact the module can be used to upgrade to other protocols, you can set the <code>upgrade</code>
+parameter in the <directive type="ProxyPass" module="mod_proxy">ProxyPass</directive>
+directive to allow the module to accept other protocol.
+NONE means you bypass the check for the header but still upgrade to WebSocket.</p>
 </summary>
 
 <seealso><module>mod_proxy</module></seealso>
index 69778350048eefcf843ac443fdd544102921530c..f6fb473ed14523fc645bb10ab2eb049623988ddb 100644 (file)
@@ -308,6 +308,12 @@ static const char *set_worker_param(apr_pool_t *p,
                     (int)sizeof(worker->s->flusher));
         PROXY_STRNCPY(worker->s->flusher, val);
     }
+    else if (!strcasecmp(key, "upgrade")) {
+        if (PROXY_STRNCPY(worker->s->upgrade, val) != APR_SUCCESS) {
+            return apr_psprintf(p, "upgrade protocol length must be < %d characters",
+                                (int)sizeof(worker->s->upgrade));
+        }
+    }
     else {
         if (set_worker_hc_param_f) {
             return set_worker_hc_param_f(p, s, worker, key, val, NULL);
index 281a77650c9bc32e68d25c841632f59e1a1a7266..8a0ad10259bbacefd1f4d09835f605c0fbf9c76c 100644 (file)
@@ -442,6 +442,7 @@ typedef struct {
     int             fcount;     /* current count of failures */
     hcmethod_t      method;     /* method to use for health check */
     apr_interval_time_t interval;
+    char      upgrade[PROXY_WORKER_MAX_SCHEME_SIZE];/* upgrade protocol used by mod_proxy_wstunnel */
 } proxy_worker_shared;
 
 #define ALIGNED_PROXY_WORKER_SHARED_SIZE (APR_ALIGN_DEFAULT(sizeof(proxy_worker_shared)))
index 597cf1186200de7377bab7f6e34ebdc0b342739d..01306990053af4d2c5f1be10b4dc317d13160459 100644 (file)
@@ -116,6 +116,7 @@ static int proxy_wstunnel_request(apr_pool_t *p, request_rec *r,
     apr_bucket_brigade *bb = apr_brigade_create(p, c->bucket_alloc);
     apr_socket_t *client_socket = ap_get_conn_socket(c);
     int done = 0, replied = 0;
+    const char *upgrade_method = *worker->s->upgrade ? worker->s->upgrade : "WebSocket";
 
     header_brigade = apr_brigade_create(p, backconn->bucket_alloc);
 
@@ -128,7 +129,11 @@ static int proxy_wstunnel_request(apr_pool_t *p, request_rec *r,
         return rv;
     }
 
-    buf = apr_pstrdup(p, "Upgrade: WebSocket" CRLF "Connection: Upgrade" CRLF CRLF);
+    if (ap_cstr_casecmp(upgrade_method, "NONE") == 0) {
+        buf = apr_pstrdup(p, "Upgrade: WebSocket" CRLF "Connection: Upgrade" CRLF CRLF);
+    } else {
+        buf = apr_pstrcat(p, "Upgrade: ", upgrade_method, CRLF "Connection: Upgrade" CRLF CRLF, NULL);
+    }
     ap_xlate_proto_to_ascii(buf, strlen(buf));
     e = apr_bucket_pool_create(buf, strlen(buf), p, c->bucket_alloc);
     APR_BRIGADE_INSERT_TAIL(header_brigade, e);
@@ -274,13 +279,13 @@ static int proxy_wstunnel_handler(request_rec *r, proxy_worker *worker,
     int status;
     char server_portstr[32];
     proxy_conn_rec *backend = NULL;
-    const char *upgrade;
     char *scheme;
     int retry;
     conn_rec *c = r->connection;
     apr_pool_t *p = r->pool;
     apr_uri_t *uri;
     int is_ssl = 0;
+    const char *upgrade_method = *worker->s->upgrade ? worker->s->upgrade : "WebSocket";
 
     if (strncasecmp(url, "wss:", 4) == 0) {
         scheme = "WSS";
@@ -294,11 +299,15 @@ static int proxy_wstunnel_handler(request_rec *r, proxy_worker *worker,
         return DECLINED;
     }
 
-    upgrade = apr_table_get(r->headers_in, "Upgrade");
-    if (!upgrade || strcasecmp(upgrade, "WebSocket") != 0) {
-        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02900)
-                      "declining URL %s  (not WebSocket)", url);
-        return DECLINED;
+    if (ap_cstr_casecmp(upgrade_method, "NONE") != 0) {
+        const char *upgrade;
+        upgrade = apr_table_get(r->headers_in, "Upgrade");
+        if (!upgrade || ap_cstr_casecmp(upgrade, upgrade_method) != 0) {
+            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02900)
+                          "declining URL %s  (not %s, Upgrade: header is %s)", 
+                          url, upgrade_method, upgrade ? upgrade : "missing");
+            return DECLINED;
+        }
     }
 
     uri = apr_palloc(p, sizeof(*uri));