]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
Merge r1889792, r1889795 from trunk:
authorYann Ylavic <ylavic@apache.org>
Fri, 14 May 2021 19:18:52 +0000 (19:18 +0000)
committerYann Ylavic <ylavic@apache.org>
Fri, 14 May 2021 19:18:52 +0000 (19:18 +0000)
mod_proxy_wstunnel: Add ProxyWebsocketFallbackToProxyHttp.

Allows to opt-out the fallback to mod_proxy_http to handle WebSocket upgrade,
and let mod_proxy_wstunnel handle the requests as in 2.4.46 and earlier.

Update docs.

Follow up to r1889792: CHANGES entry.

Submitted by: ylavic
Reviewed by: ylavic, covener, rpluem

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

CHANGES
docs/manual/mod/mod_proxy_wstunnel.xml
modules/proxy/mod_proxy_wstunnel.c

diff --git a/CHANGES b/CHANGES
index adea3c83857da4f226f7a8f196dd25879e7d44f9..ccdc021a613f19dbb71a507bef207d2815fe73a4 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,10 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.4.48
 
+  *) mod_proxy_wstunnel: Add ProxyWebsocketFallbackToProxyHttp to opt-out the
+     fallback to mod_proxy_http for WebSocket upgrade and tunneling.
+     [Yann Ylavic]
+
   *) mod_proxy: Fix flushing of THRESHOLD_MIN_WRITE data while tunneling.
      BZ 65294.  [Yann Ylavic]
 
index ff9d8a8526e8cbe2b2480acf8ab2e46ee7012913..51c91eed13daf9d4606ab6a0b441d898ba6c10fc 100644 (file)
@@ -83,4 +83,25 @@ in the response <code>Upgrade</code></p>
 </summary>
 
 <seealso><module>mod_proxy</module></seealso>
+
+<directivesynopsis>
+<name>ProxyWebsocketFallbackToProxyHttp</name>
+<description>Instructs this module to let <module>mod_proxy_http</module> handle the request</description>
+<syntax>ProxyWebsocketFallbackToProxyHttp On|Off</syntax>
+<default>ProxyWebsocketFallbackToProxyHttp On</default>
+<compatibility>Available in httpd 2.4.48 and later</compatibility>
+<contextlist><context>server config</context>
+<context>virtual host</context>
+</contextlist>
+
+<usage>
+    <p>Since httpd 2.4.47, <module>mod_proxy_http</module> can handle WebSocket
+    upgrading and tunneling in accordance to RFC 7230, this directive controls
+    whether <module>mod_proxy_wstunnel</module> should hand over to
+    <module>mod_proxy_http</module> to this, which is the case by default.</p>
+    <p>Setting to <em>Off</em> lets <module>mod_proxy_wstunnel</module> handle
+    WebSocket requests as in httpd 2.4.46 and earlier.</p>
+</usage>
+</directivesynopsis>
+
 </modulesynopsis>
index 830417c802b19fe056849fb8c7297cb082b0c642..bcbba42f9a49c5f9bf2fa8af53f6939f0d241560 100644 (file)
 
 module AP_MODULE_DECLARE_DATA proxy_wstunnel_module;
 
-static int fallback_to_mod_proxy_http;
+typedef struct {
+    unsigned int fallback_to_proxy_http     :1,
+                 fallback_to_proxy_http_set :1;
+} proxyws_dir_conf;
+
+static int can_fallback_to_proxy_http;
 
 static int proxy_wstunnel_check_trans(request_rec *r, const char *url)
 {
-    if (fallback_to_mod_proxy_http) {
+    proxyws_dir_conf *dconf = ap_get_module_config(r->per_dir_config,
+                                                   &proxy_wstunnel_module);
+
+    if (can_fallback_to_proxy_http && dconf->fallback_to_proxy_http) {
         ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, "check_trans fallback");
         return DECLINED;
     }
@@ -52,13 +60,15 @@ static int proxy_wstunnel_check_trans(request_rec *r, const char *url)
  */
 static int proxy_wstunnel_canon(request_rec *r, char *url)
 {
+    proxyws_dir_conf *dconf = ap_get_module_config(r->per_dir_config,
+                                                   &proxy_wstunnel_module);
     char *host, *path, sport[7];
     char *search = NULL;
     const char *err;
     char *scheme;
     apr_port_t port, def_port;
 
-    if (fallback_to_mod_proxy_http) {
+    if (can_fallback_to_proxy_http && dconf->fallback_to_proxy_http) {
         ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, "canon fallback");
         return DECLINED;
     }
@@ -314,6 +324,8 @@ static int proxy_wstunnel_handler(request_rec *r, proxy_worker *worker,
                              char *url, const char *proxyname,
                              apr_port_t proxyport)
 {
+    proxyws_dir_conf *dconf = ap_get_module_config(r->per_dir_config,
+                                                   &proxy_wstunnel_module);
     int status;
     char server_portstr[32];
     proxy_conn_rec *backend = NULL;
@@ -324,7 +336,7 @@ static int proxy_wstunnel_handler(request_rec *r, proxy_worker *worker,
     apr_uri_t *uri;
     int is_ssl = 0;
 
-    if (fallback_to_mod_proxy_http) {
+    if (can_fallback_to_proxy_http && dconf->fallback_to_proxy_http) {
         ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, "handler fallback");
         return DECLINED;
     }
@@ -406,15 +418,57 @@ cleanup:
     return status;
 }
 
+static void *create_proxyws_dir_config(apr_pool_t *p, char *dummy)
+{
+    proxyws_dir_conf *new =
+        (proxyws_dir_conf *) apr_pcalloc(p, sizeof(proxyws_dir_conf));
+
+    new->fallback_to_proxy_http = 1;
+
+    return (void *) new;
+}
+
+static void *merge_proxyws_dir_config(apr_pool_t *p, void *vbase, void *vadd)
+{
+    proxyws_dir_conf *new = apr_pcalloc(p, sizeof(proxyws_dir_conf)),
+                     *add = vadd, *base = vbase;
+
+    new->fallback_to_proxy_http = (add->fallback_to_proxy_http_set)
+                                  ? add->fallback_to_proxy_http
+                                  : base->fallback_to_proxy_http;
+    new->fallback_to_proxy_http_set = (add->fallback_to_proxy_http_set
+                                       || base->fallback_to_proxy_http_set);
+
+    return new;
+}
+
+static const char * proxyws_fallback_to_proxy_http(cmd_parms *cmd, void *conf, int arg)
+{
+    proxyws_dir_conf *dconf = conf;
+    dconf->fallback_to_proxy_http = !!arg;
+    dconf->fallback_to_proxy_http_set = 1;
+    return NULL;
+}
+
 static int proxy_wstunnel_post_config(apr_pool_t *pconf, apr_pool_t *plog,
                                       apr_pool_t *ptemp, server_rec *s)
 {
-    fallback_to_mod_proxy_http =
+    can_fallback_to_proxy_http =
         (ap_find_linked_module("mod_proxy_http.c") != NULL);
 
     return OK;
 }
 
+static const command_rec ws_proxy_cmds[] =
+{
+    AP_INIT_FLAG("ProxyWebsocketFallbackToProxyHttp",
+                 proxyws_fallback_to_proxy_http, NULL, RSRC_CONF|ACCESS_CONF,
+                 "whether to let mod_proxy_http handle the upgrade and tunneling, "
+                 "On by default"),
+
+    {NULL}
+};
+
 static void ws_proxy_hooks(apr_pool_t *p)
 {
     static const char * const aszSucc[] = { "mod_proxy_http.c", NULL};
@@ -426,10 +480,10 @@ static void ws_proxy_hooks(apr_pool_t *p)
 
 AP_DECLARE_MODULE(proxy_wstunnel) = {
     STANDARD20_MODULE_STUFF,
-    NULL,                       /* create per-directory config structure */
-    NULL,                       /* merge per-directory config structures */
+    create_proxyws_dir_config,  /* create per-directory config structure */
+    merge_proxyws_dir_config,   /* merge per-directory config structures */
     NULL,                       /* create per-server config structure */
     NULL,                       /* merge per-server config structures */
-    NULL,                       /* command apr_table_t */
+    ws_proxy_cmds,              /* command apr_table_t */
     ws_proxy_hooks              /* register hooks */
 };