You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by yl...@apache.org on 2022/03/01 13:26:03 UTC

svn commit: r1898509 - in /httpd/httpd/trunk: changes-entries/rewrite_vs_proxy_mapping.txt modules/mappers/mod_rewrite.c

Author: ylavic
Date: Tue Mar  1 13:26:03 2022
New Revision: 1898509

URL: http://svn.apache.org/viewvc?rev=1898509&view=rev
Log:
mod_rewrite: URI-to-filename rewrites to transparently handle proxy mappings.

Since mod_rewrite works on r->filename and mod_proxy's mapping=servlet|decoded
sets its "proxy:" URL there at pre_translate_name stage (i.e. before
mod_rewrite's translate_name hook), users have to match the full proxy URL in
their RewriteRules to handle proxy mappings, which is not very friendly nor
consistent with how proxy non-mapping requests have to be matched.

Let's use r->filename = r->uri in hook_uri2file() for pre_trans'ed reverse
proxy requests, and restore r->filename to its original value if the request
was finally DECLINED (like in hook_fixup).

But if a proxy mapping gets rewritten to a non-proxy request, clear any
proxy specific r->proxyreq or r->handler so that processing continues
accordingly.


Added:
    httpd/httpd/trunk/changes-entries/rewrite_vs_proxy_mapping.txt
Modified:
    httpd/httpd/trunk/modules/mappers/mod_rewrite.c

Added: httpd/httpd/trunk/changes-entries/rewrite_vs_proxy_mapping.txt
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/changes-entries/rewrite_vs_proxy_mapping.txt?rev=1898509&view=auto
==============================================================================
--- httpd/httpd/trunk/changes-entries/rewrite_vs_proxy_mapping.txt (added)
+++ httpd/httpd/trunk/changes-entries/rewrite_vs_proxy_mapping.txt Tue Mar  1 13:26:03 2022
@@ -0,0 +1,2 @@
+  *) mod_rewrite: Make URI-to-filename rewrites work transparently with
+     proxy early mappings (mapping=servlet/decoded).  [Yann Ylavic]
\ No newline at end of file

Modified: httpd/httpd/trunk/modules/mappers/mod_rewrite.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/mappers/mod_rewrite.c?rev=1898509&r1=1898508&r2=1898509&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/mappers/mod_rewrite.c (original)
+++ httpd/httpd/trunk/modules/mappers/mod_rewrite.c Tue Mar  1 13:26:03 2022
@@ -4660,6 +4660,7 @@ static int hook_uri2file(request_rec *r)
     unsigned int port;
     int rulestatus;
     void *skipdata;
+    char *ofilename;
     const char *oargs;
 
     /*
@@ -4713,7 +4714,10 @@ static int hook_uri2file(request_rec *r)
     /*
      *  remember the original query string for later check, since we don't
      *  want to apply URL-escaping when no substitution has changed it.
+     *  also, we'll restore original r->filename if we decline this
+     *  request.
      */
+    ofilename = r->filename;
     oargs = r->args;
 
     /*
@@ -4756,13 +4760,15 @@ static int hook_uri2file(request_rec *r)
     apr_table_setn(r->subprocess_env, ENVVAR_SCRIPT_URI, var);
 
     if (!(saved_rulestatus = apr_table_get(r->notes,"mod_rewrite_rewritten"))) {
-        /* if filename was not initially set,
-         * we start with the requested URI
+        /* If r->filename was not initially set or if it's a pre_trans reverse
+         * "proxy:" scheme, we start with the requested URI.
          */
-        if (r->filename == NULL) {
+        if (r->filename == NULL || (r->proxyreq == PROXYREQ_REVERSE &&
+                                    strncmp(r->filename, "proxy:", 6) == 0)) {
             r->filename = apr_pstrdup(r->pool, r->uri);
-            rewritelog(r, 2, NULL, "init rewrite engine with requested uri %s",
-                       r->filename);
+            rewritelog(r, 2, NULL, "init rewrite engine with requested uri "
+                       "%s. Original filename = %s", r->filename,
+                       (ofilename) ? ofilename : "n/a");
         }
         else {
             rewritelog(r, 2, NULL, "init rewrite engine with passed filename "
@@ -4786,6 +4792,7 @@ static int hook_uri2file(request_rec *r)
     if (rulestatus) {
         unsigned skip;
         apr_size_t flen;
+        int to_proxyreq;
 
         if (ACTION_STATUS == rulestatus) {
             int n = r->status;
@@ -4795,7 +4802,19 @@ static int hook_uri2file(request_rec *r)
         }
 
         flen = r->filename ? strlen(r->filename) : 0;
-        if (flen > 6 && strncmp(r->filename, "proxy:", 6) == 0) {
+        to_proxyreq = (flen > 6 && strncmp(r->filename, "proxy:", 6) == 0);
+
+        /* If a pre_trans reverse "proxy:" filename gets rewritten to
+         * a non-proxy one this is not a proxy request anymore.
+         */
+        if (r->proxyreq == PROXYREQ_REVERSE && !to_proxyreq) {
+            if (r->handler && strcmp(r->handler, "proxy-server") == 0) {
+                r->handler = NULL;
+            }
+            r->proxyreq = PROXYREQ_NONE;
+        }
+
+        if (to_proxyreq) {
             /* it should be go on as an internal proxy request */
 
             /* check if the proxy module is enabled, so
@@ -4962,7 +4981,9 @@ static int hook_uri2file(request_rec *r)
         }
     }
     else {
-        rewritelog(r, 1, NULL, "pass through %s", r->filename);
+        rewritelog(r, 1, NULL, "pass through %s, filename %s",
+                   r->filename, (ofilename) ? ofilename : "n/a");
+        r->filename = ofilename;
         return DECLINED;
     }
 }
@@ -5309,7 +5330,8 @@ static int hook_fixup(request_rec *r)
         }
     }
     else {
-        rewritelog(r, 1, dconf->directory, "pass through %s", r->filename);
+        rewritelog(r, 1, dconf->directory, "pass through %s, filename %s",
+                   r->filename, (ofilename) ? ofilename : "n/a");
         r->filename = ofilename;
         return DECLINED;
     }