]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
mod_proxy: Add proxy check_trans hook.
authorYann Ylavic <ylavic@apache.org>
Tue, 5 Nov 2019 12:43:29 +0000 (12:43 +0000)
committerYann Ylavic <ylavic@apache.org>
Tue, 5 Nov 2019 12:43:29 +0000 (12:43 +0000)
This allows proxy modules to decline request handling at early stage.
Then mod_proxy_wstunnel can implement that hook to verify that an Upgrade
is requested, and otherwise hand over to mod_proxy_http.

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

CHANGES
include/ap_mmn.h
modules/proxy/mod_proxy.c
modules/proxy/mod_proxy.h
modules/proxy/mod_proxy_wstunnel.c

diff --git a/CHANGES b/CHANGES
index b28b00a432d7458456438c1f6f10a3176da5ec4c..c311e82ba8c108e11662fb3beb3361071a21db75 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,9 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.5.1
    
+  *) mod_proxy: Add proxy check_trans hook for proxy modules to possibly
+     decline request handling at early stage.  [Yann Ylavic]
+
   *) mod_proxy: Put mod_proxy_{connect,wstunnel} tunneling code in common in
      proxy_util.  [Yann Ylavic]
 
index c36e4866ef97a768c80bec51ce4fbd4dd6a86806..2a8a7eef278cb397260281267d2ad80a70bc0cbf 100644 (file)
  *                         AP_VOLATILIZE_T.
  * 20190312.5 (2.5.1-dev)  Add proxy_tunnel_rec, ap_proxy_tunnel_create()
  *                         and ap_proxy_tunnel_run() to proxy_util.
+ * 20190312.6 (2.5.1-dev)  Add proxy check_trans hook
  */
 
 #define MODULE_MAGIC_COOKIE 0x41503235UL /* "AP25" */
 #ifndef MODULE_MAGIC_NUMBER_MAJOR
 #define MODULE_MAGIC_NUMBER_MAJOR 20190312
 #endif
-#define MODULE_MAGIC_NUMBER_MINOR 5                 /* 0...n */
+#define MODULE_MAGIC_NUMBER_MINOR 6                 /* 0...n */
 
 /**
  * Determine if the server's current MODULE_MAGIC_NUMBER is at least a
index 93b0a868590d3625c2da0047b8b8cfeb0a32a169..9799e2884a55020cf0a9e6999c1298987d085317 100644 (file)
@@ -764,6 +764,15 @@ PROXY_DECLARE(int) ap_proxy_trans_match(request_rec *r, struct proxy_alias *ent,
     }
 
     if (found) {
+        /* A proxy module is assigned this URL, check whether it's interested
+         * in the request itself (e.g. proxy_wstunnel cares about Upgrade
+         * requests only, and could hand over to proxy_http otherwise).
+         */
+        int rc = proxy_run_check_trans(r, found + 6);
+        if (rc != OK && rc != DECLINED) {
+            return DONE;
+        }
+
         r->filename = found;
         r->handler = "proxy-server";
         r->proxyreq = PROXYREQ_REVERSE;
@@ -3120,6 +3129,7 @@ APR_HOOK_STRUCT(
     APR_HOOK_LINK(pre_request)
     APR_HOOK_LINK(post_request)
     APR_HOOK_LINK(request_status)
+    APR_HOOK_LINK(check_trans)
 )
 
 APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(proxy, PROXY, int, scheme_handler,
@@ -3128,6 +3138,9 @@ APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(proxy, PROXY, int, scheme_handler,
                                       char *url, const char *proxyhost,
                                       apr_port_t proxyport),(r,worker,conf,
                                       url,proxyhost,proxyport),DECLINED)
+APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(proxy, PROXY, int, check_trans,
+                                      (request_rec *r, const char *url),
+                                      (r, url), DECLINED)
 APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(proxy, PROXY, int, canon_handler,
                                       (request_rec *r, char *url),(r,
                                       url),DECLINED)
index 3769b306195ad3ccfe8f7409779eb82efd022d61..c75992a60b3c902c139986a3f3cd57b89ce4fcce 100644 (file)
@@ -623,6 +623,8 @@ APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, scheme_handler,
                           (request_rec *r, proxy_worker *worker,
                            proxy_server_conf *conf, char *url,
                            const char *proxyhost, apr_port_t proxyport))
+APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, check_trans,
+                          (request_rec *r, const char *url))
 APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, canon_handler,
                           (request_rec *r, char *url))
 
index 9c66ef8c739345f587fce6558c14d53ad56b7b67..794397b30d70b1a3e7aefe7722c24b9d32b90106 100644 (file)
@@ -92,6 +92,23 @@ static void proxy_wstunnel_callback(void *b)
     }
 }
 
+static int proxy_wstunnel_check_trans(request_rec *r, const char *url)
+{
+    if (ap_cstr_casecmpn(url, "ws:", 3) != 0
+            && ap_cstr_casecmpn(url, "wss:", 4) != 0) {
+        return DECLINED;
+    }
+
+    if (!apr_table_get(r->headers_in, "Upgrade")) {
+        /* No Upgrade, let mod_proxy_http handle it (for instance).
+         * Note: anything but OK/DECLINED will do (i.e. bypass wstunnel w/o
+         * aborting the request), HTTP_UPGRADE_REQUIRED is documentary...
+         */
+        return HTTP_UPGRADE_REQUIRED;
+    }
+
+    return OK;
+}
 
 /*
  * Canonicalise http-like URLs.
@@ -414,6 +431,7 @@ static void ap_proxy_http_register_hook(apr_pool_t *p)
 {
     static const char * const aszSucc[] = { "mod_proxy_http.c", NULL};
     proxy_hook_scheme_handler(proxy_wstunnel_handler, NULL, aszSucc, APR_HOOK_FIRST);
+    proxy_hook_check_trans(proxy_wstunnel_check_trans, NULL, aszSucc, APR_HOOK_MIDDLE);
     proxy_hook_canon_handler(proxy_wstunnel_canon, NULL, aszSucc, APR_HOOK_FIRST);
 }