]> granicus.if.org Git - apache/commitdiff
Add upgrade parameter to mod_proxy_wstunnel.
authorJean-Frederic Clere <jfclere@apache.org>
Thu, 20 Apr 2017 17:07:32 +0000 (17:07 +0000)
committerJean-Frederic Clere <jfclere@apache.org>
Thu, 20 Apr 2017 17:07:32 +0000 (17:07 +0000)
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

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1792092 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
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 7df69b0934872919f0acc527e214a28558d3b9f5..2d9f5367c356153ddc50a109f3540ff5c603a9c7 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,9 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.5.0
 
+  *) mod_proxy_wstunnel: Add "upgrade" parameter to allow upgrade to other
+     protocols.  [Jean-Frederic Clere]
+
   *) mod_substitute: Fix spurious AH01328 (Line too long) errors on EBCDIC
      systems.  [Eric Covener]
 
index 02ae4869462d33c92e2f1cfa2d88761f0332b5ad..d9b894cf447f25fa58ee4eea2fa3c1f308538450 100644 (file)
@@ -1208,6 +1208,16 @@ ProxyPass "/example" "http://backend.example.com" max=20 ttl=120 retry=300
         <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 903f65589c02770a6dd1fb421b1282f68b1fd1eb..354b0bb2ad58baae3c9bbd01792148aa20566cfe 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 8004650e6c89ff2c98287d5e0983c5d6bad33e05..a0b08788cf094b9133b328d6423702fed1092be7 100644 (file)
@@ -317,6 +317,12 @@ static const char *set_worker_param(apr_pool_t *p,
                                 (int)sizeof(worker->s->secret));
         }
     }
+    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 ba78317bbe6d247575d99ef71f241f37ba595694..0ea7b3fc3d31856c236ce5bac339ec8e63c03f0c 100644 (file)
@@ -450,6 +450,7 @@ typedef struct {
     unsigned int     was_malloced:1;
     unsigned int     is_name_matchable:1;
     char      secret[PROXY_WORKER_MAX_SECRET_SIZE]; /* authentication secret (e.g. AJP13) */
+    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 c94c082d61566bc0b699e4c9f2eeea0ff86a84e8..31398d5fc9b9550572c2643b2a5ade834138c75f 100644 (file)
@@ -313,6 +313,7 @@ static int proxy_wstunnel_request(apr_pool_t *p, request_rec *r,
     ws_baton_t *baton = apr_pcalloc(r->pool, sizeof(ws_baton_t));
     int status;
     proxyws_dir_conf *dconf = ap_get_module_config(r->per_dir_config, &proxy_wstunnel_module);
+    const char *upgrade_method = *worker->s->upgrade ? worker->s->upgrade : "WebSocket";
 
     header_brigade = apr_brigade_create(p, backconn->bucket_alloc);
 
@@ -325,7 +326,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);
@@ -445,12 +450,12 @@ 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;
     apr_pool_t *p = r->pool;
     char *locurl = url;
     apr_uri_t *uri;
     int is_ssl = 0;
+    const char *upgrade_method = *worker->s->upgrade ? worker->s->upgrade : "WebSocket";
 
     if (ap_cstr_casecmpn(url, "wss:", 4) == 0) {
         scheme = "WSS";
@@ -464,12 +469,15 @@ static int proxy_wstunnel_handler(request_rec *r, proxy_worker *worker,
         return DECLINED;
     }
 
-    upgrade = apr_table_get(r->headers_in, "Upgrade");
-    if (!upgrade || ap_cstr_casecmp(upgrade, "WebSocket") != 0) {
-        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02900)
-                      "declining URL %s  (not WebSocket, Upgrade: header is %s)", 
-                      url, upgrade ? upgrade : "missing");
-        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));