From: Graham Leggett Date: Sat, 26 Aug 2023 18:19:50 +0000 (+0000) Subject: Backport to v2.4: X-Git-Tag: 2.4.58-rc1-candidate~40 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1b9fcfeeb63b3ebb31aa99c5526c51610cfc5f1a;p=thirdparty%2Fapache%2Fhttpd.git Backport to v2.4: *) 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 --- diff --git a/CHANGES b/CHANGES index 744aaf14f80..a14346d45ed 100644 --- 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 f831b841b71..a09acbaf061 100644 --- 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: diff --git a/docs/manual/mod/mod_alias.xml b/docs/manual/mod/mod_alias.xml index fc1040f15a5..7d6767033a3 100644 --- a/docs/manual/mod/mod_alias.xml +++ b/docs/manual/mod/mod_alias.xml @@ -618,4 +618,25 @@ ScriptAliasMatch "(?i)^/cgi-bin(.*)" "/usr/local/apache/cgi-bin$1" + +RedirectRelative +Allows relative redirect targets. +RedirectRelative OFF|ON +RedirectRelative OFF +server configvirtual host +directory +2.5.1 and later + + + +

By default, if the target URL of a Redirect + 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 RedirectRelative to the value "ON", + the relative URL is presented to the client directly.

+ +
+
+ + diff --git a/modules/mappers/mod_alias.c b/modules/mappers/mod_alias.c index 5ff937b1ab4..569d331e7f4 100644 --- a/modules/mappers/mod_alias.c +++ b/modules/mappers/mod_alias.c @@ -37,6 +37,10 @@ #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} };