summaryrefslogtreecommitdiffstats
path: root/modules/mappers/mod_alias.c
diff options
context:
space:
mode:
authorEric Covener <covener@apache.org>2019-06-17 20:35:24 +0200
committerEric Covener <covener@apache.org>2019-06-17 20:35:24 +0200
commitbc290e00b7ea931965db6d0dfa101d813a2fe323 (patch)
tree0c78100f81161bfd5846b396c8bc5fdba818e6a1 /modules/mappers/mod_alias.c
parentstyle: cmd_rec at the bottom (diff)
downloadapache2-bc290e00b7ea931965db6d0dfa101d813a2fe323.tar.xz
apache2-bc290e00b7ea931965db6d0dfa101d813a2fe323.zip
add RedirectRelative directive to allow relative Redirect targets
2616 forbade relative redirect URLs, but 7231 allows them Early 2.2 maintenance levels did not fix them up, but later 2.2 and all 2.4 fixed them up with ap_construct_url(). Allow opt-in to not fixing up relative URLs with RedirectRelative git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1861542 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to '')
-rw-r--r--modules/mappers/mod_alias.c108
1 files changed, 61 insertions, 47 deletions
diff --git a/modules/mappers/mod_alias.c b/modules/mappers/mod_alias.c
index 5ff937b1ab..3297a975f6 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)) {
+ 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);
+ }
+ }
+ /* 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)) {
+ 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);
}
- 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}
};