]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
Backport to v2.4:
authorGraham Leggett <minfrin@apache.org>
Sat, 26 Aug 2023 18:19:50 +0000 (18:19 +0000)
committerGraham Leggett <minfrin@apache.org>
Sat, 26 Aug 2023 18:19:50 +0000 (18:19 +0000)
  *) mod_alias: Add RedirectRelative to allow relative redirect targets to be
     issued as-is.
     Trunk version of patch:
        https://svn.apache.org/r1861542
        https://svn.apache.org/r1861569
     Backport version for 2.4.x of patch:
      Trunk version of patch works
       svn merge -c 1861542,r1861569 ^/httpd/httpd/trunk .
     +1: minfrin, covener, icing

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

CHANGES
STATUS
docs/manual/mod/mod_alias.xml
modules/mappers/mod_alias.c

diff --git a/CHANGES b/CHANGES
index 744aaf14f8026ec84336812b057127fe08d2fbd5..a14346d45ed2501c4c583146380f1b862ba23a35 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,9 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.4.58
 
+  *) mod_alias: Add RedirectRelative to allow relative redirect targets to be
+     issued as-is. [Graham Leggett]
+
   *) core: Add formats %{z} and %{strftime-format} to ErrorLogFormat, and make
      sure that if the format is configured early enough it applies to every log
      line.  PR 62161.  [Yann Ylavic]
diff --git a/STATUS b/STATUS
index f831b841b712e1b3fb014a81ed9395188af9fc18..a09acbaf0614f22fe59bcbeb4d4d6ae81c20fee9 100644 (file)
--- a/STATUS
+++ b/STATUS
@@ -152,15 +152,6 @@ RELEASE SHOWSTOPPERS:
 PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
   [ start all new proposals below, under PATCHES PROPOSED. ]
 
-  *) mod_alias: Add RedirectRelative to allow relative redirect targets to be
-     issued as-is.
-     Trunk version of patch:
-        https://svn.apache.org/r1861542
-        https://svn.apache.org/r1861569
-     Backport version for 2.4.x of patch:
-      Trunk version of patch works
-       svn merge -c 1861542,r1861569 ^/httpd/httpd/trunk .
-     +1: minfrin, covener, icing
 
 
 PATCHES PROPOSED TO BACKPORT FROM TRUNK:
index fc1040f15a56e4dd09b1df0935f7895f3c08ee77..7d6767033a39e383d3a01638020e69b46c0b38f5 100644 (file)
@@ -618,4 +618,25 @@ ScriptAliasMatch "(?i)^/cgi-bin(.*)" "/usr/local/apache/cgi-bin$1"
 </usage>
 </directivesynopsis>
 
+<directivesynopsis>
+<name>RedirectRelative</name>
+<description>Allows relative redirect targets.</description>
+<syntax>RedirectRelative OFF|ON</syntax>
+<default>RedirectRelative OFF</default>
+<contextlist><context>server config</context><context>virtual host</context>
+<context>directory</context>
+<compatibility>2.5.1 and later</compatibility>
+</contextlist>
+
+<usage>
+    <p>By default, if the target URL of a <directive>Redirect</directive>
+    directive is a relative URL beginning with a '/' character, the server 
+    converts it to a an absolute URL before responding to the client. By
+    setting <directive>RedirectRelative</directive> to the value "ON",
+    the relative URL is presented to the client directly.</p>
+
+</usage>
+</directivesynopsis>
+
+
 </modulesynopsis>
index 5ff937b1ab46b8ad56a1c559a60781c0bbda847c..569d331e7f4f0cc7205395892e50b001ccdca84e 100644 (file)
 #include "ap_expr.h"
 
 
+#define ALIAS_FLAG_DEFAULT -1
+#define ALIAS_FLAG_OFF 0
+#define ALIAS_FLAG_ON  1
+
 typedef struct {
     const char *real;
     const char *fake;
@@ -58,6 +62,7 @@ typedef struct {
     char *handler;
     const ap_expr_info_t *redirect;
     int redirect_status;                /* 301, 302, 303, 410, etc */
+    int allow_relative;                 /* skip ap_construct_url() */
 } alias_dir_conf;
 
 module AP_MODULE_DECLARE_DATA alias_module;
@@ -80,6 +85,7 @@ static void *create_alias_dir_config(apr_pool_t *p, char *d)
     alias_dir_conf *a =
     (alias_dir_conf *) apr_pcalloc(p, sizeof(alias_dir_conf));
     a->redirects = apr_array_make(p, 2, sizeof(alias_entry));
+    a->allow_relative = ALIAS_FLAG_DEFAULT;
     return a;
 }
 
@@ -111,7 +117,9 @@ static void *merge_alias_dir_config(apr_pool_t *p, void *basev, void *overridesv
     a->redirect = (overrides->redirect_set == 0) ? base->redirect : overrides->redirect;
     a->redirect_status = (overrides->redirect_set == 0) ? base->redirect_status : overrides->redirect_status;
     a->redirect_set = overrides->redirect_set || base->redirect_set;
-
+    a->allow_relative = (overrides->allow_relative != ALIAS_FLAG_DEFAULT)
+                                  ? overrides->allow_relative 
+                                  : base->allow_relative;
     return a;
 }
 
@@ -591,31 +599,33 @@ static int translate_alias_redir(request_rec *r)
         if (ret == PREGSUB_ERROR)
             return HTTP_INTERNAL_SERVER_ERROR;
         if (ap_is_HTTP_REDIRECT(status)) {
-            if (ret[0] == '/') {
-                char *orig_target = ret;
-
-                ret = ap_construct_url(r->pool, ret, r);
-                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00673)
-                              "incomplete redirection target of '%s' for "
-                              "URI '%s' modified to '%s'",
-                              orig_target, r->uri, ret);
-            }
-            if (!ap_is_url(ret)) {
-                status = HTTP_INTERNAL_SERVER_ERROR;
-                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00674)
-                              "cannot redirect '%s' to '%s'; "
-                              "target is not a valid absoluteURI or abs_path",
-                              r->uri, ret);
-            }
-            else {
-                /* append requested query only, if the config didn't
-                 * supply its own.
-                 */
-                if (r->args && !ap_strchr(ret, '?')) {
-                    ret = apr_pstrcat(r->pool, ret, "?", r->args, NULL);
+            alias_dir_conf *dirconf = (alias_dir_conf *) 
+                ap_get_module_config(r->per_dir_config, &alias_module);
+            if (dirconf->allow_relative != ALIAS_FLAG_ON || ret[0] != '/') {
+                if (ret[0] == '/') {
+                    char *orig_target = ret;
+
+                    ret = ap_construct_url(r->pool, ret, r);
+                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00673)
+                                  "incomplete redirection target of '%s' for "
+                                  "URI '%s' modified to '%s'",
+                                  orig_target, r->uri, ret);
                 }
-                apr_table_setn(r->headers_out, "Location", ret);
+                if (!ap_is_url(ret)) {
+                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00674)
+                                  "cannot redirect '%s' to '%s'; "
+                                  "target is not a valid absoluteURI or abs_path",
+                                  r->uri, ret);
+                    return HTTP_INTERNAL_SERVER_ERROR;
+                }
+            }
+            /* append requested query only, if the config didn't
+             * supply its own.
+             */
+            if (r->args && !ap_strchr(ret, '?')) {
+                ret = apr_pstrcat(r->pool, ret, "?", r->args, NULL);
             }
+            apr_table_setn(r->headers_out, "Location", ret);
         }
         return status;
     }
@@ -646,31 +656,31 @@ static int fixup_redir(request_rec *r)
         if (ret == PREGSUB_ERROR)
             return HTTP_INTERNAL_SERVER_ERROR;
         if (ap_is_HTTP_REDIRECT(status)) {
-            if (ret[0] == '/') {
-                char *orig_target = ret;
-
-                ret = ap_construct_url(r->pool, ret, r);
-                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00675)
-                              "incomplete redirection target of '%s' for "
-                              "URI '%s' modified to '%s'",
-                              orig_target, r->uri, ret);
-            }
-            if (!ap_is_url(ret)) {
-                status = HTTP_INTERNAL_SERVER_ERROR;
-                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00676)
-                              "cannot redirect '%s' to '%s'; "
-                              "target is not a valid absoluteURI or abs_path",
-                              r->uri, ret);
-            }
-            else {
-                /* append requested query only, if the config didn't
-                 * supply its own.
-                 */
-                if (r->args && !ap_strchr(ret, '?')) {
-                    ret = apr_pstrcat(r->pool, ret, "?", r->args, NULL);
+            if (dirconf->allow_relative != ALIAS_FLAG_ON || ret[0] != '/') {
+                if (ret[0] == '/') {
+                    char *orig_target = ret;
+
+                    ret = ap_construct_url(r->pool, ret, r);
+                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00675)
+                                  "incomplete redirection target of '%s' for "
+                                  "URI '%s' modified to '%s'",
+                                  orig_target, r->uri, ret);
+                }
+                if (!ap_is_url(ret)) {
+                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00676)
+                                  "cannot redirect '%s' to '%s'; "
+                                  "target is not a valid absoluteURI or abs_path",
+                                  r->uri, ret);
+                    return HTTP_INTERNAL_SERVER_ERROR;
                 }
-                apr_table_setn(r->headers_out, "Location", ret);
             }
+            /* append requested query only, if the config didn't
+             * supply its own.
+             */
+            if (r->args && !ap_strchr(ret, '?')) {
+                ret = apr_pstrcat(r->pool, ret, "?", r->args, NULL);
+            }
+            apr_table_setn(r->headers_out, "Location", ret);
         }
         return status;
     }
@@ -702,6 +712,10 @@ static const command_rec alias_cmds[] =
     AP_INIT_TAKE2("RedirectPermanent", add_redirect2,
                   (void *) HTTP_MOVED_PERMANENTLY, OR_FILEINFO,
                   "a document to be redirected, then the destination URL"),
+    AP_INIT_FLAG("RedirectRelative", ap_set_flag_slot,
+                  (void*)APR_OFFSETOF(alias_dir_conf, allow_relative), OR_FILEINFO,
+                  "Set to ON to allow relative redirect targets to be issued as-is"),
+
     {NULL}
 };