summaryrefslogtreecommitdiffstats
path: root/modules/mappers/mod_alias.c
diff options
context:
space:
mode:
Diffstat (limited to 'modules/mappers/mod_alias.c')
-rw-r--r--modules/mappers/mod_alias.c186
1 files changed, 113 insertions, 73 deletions
diff --git a/modules/mappers/mod_alias.c b/modules/mappers/mod_alias.c
index 79d58d8..35eca74 100644
--- a/modules/mappers/mod_alias.c
+++ b/modules/mappers/mod_alias.c
@@ -37,6 +37,12 @@
#include "ap_expr.h"
+#define ALIAS_FLAG_DEFAULT -1
+#define ALIAS_FLAG_OFF 0
+#define ALIAS_FLAG_ON 1
+
+#define ALIAS_PRESERVE_PATH_DEFAULT 0
+
typedef struct {
const char *real;
const char *fake;
@@ -55,9 +61,12 @@ typedef struct {
unsigned int redirect_set:1;
apr_array_header_t *redirects;
const ap_expr_info_t *alias;
+ const char *alias_fake;
char *handler;
const ap_expr_info_t *redirect;
int redirect_status; /* 301, 302, 303, 410, etc */
+ int allow_relative; /* skip ap_construct_url() */
+ int alias_preserve_path; /* map full path */
} alias_dir_conf;
module AP_MODULE_DECLARE_DATA alias_module;
@@ -80,6 +89,8 @@ 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;
+ a->alias_preserve_path = ALIAS_FLAG_DEFAULT;
return a;
}
@@ -105,12 +116,19 @@ static void *merge_alias_dir_config(apr_pool_t *p, void *basev, void *overridesv
a->redirects = apr_array_append(p, overrides->redirects, base->redirects);
a->alias = (overrides->alias_set == 0) ? base->alias : overrides->alias;
+ a->alias_fake = (overrides->alias_set == 0) ? base->alias_fake : overrides->alias_fake;
a->handler = (overrides->alias_set == 0) ? base->handler : overrides->handler;
a->alias_set = overrides->alias_set || base->alias_set;
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;
+ a->alias_preserve_path = (overrides->alias_preserve_path != ALIAS_FLAG_DEFAULT)
+ ? overrides->alias_preserve_path
+ : base->alias_preserve_path;
return a;
}
@@ -210,6 +228,7 @@ static const char *add_alias(cmd_parms *cmd, void *dummy, const char *fake,
NULL);
}
+ dirconf->alias_fake = cmd->path;
dirconf->handler = cmd->info;
dirconf->alias_set = 1;
@@ -373,33 +392,6 @@ static const char *add_redirect_regex(cmd_parms *cmd, void *dirconf,
return add_redirect_internal(cmd, dirconf, arg1, arg2, arg3, 1);
}
-static const command_rec alias_cmds[] =
-{
- AP_INIT_TAKE12("Alias", add_alias, NULL, RSRC_CONF | ACCESS_CONF,
- "a fakename and a realname, or a realname in a Location"),
- AP_INIT_TAKE12("ScriptAlias", add_alias, "cgi-script", RSRC_CONF | ACCESS_CONF,
- "a fakename and a realname, or a realname in a Location"),
- AP_INIT_TAKE123("Redirect", add_redirect, (void *) HTTP_MOVED_TEMPORARILY,
- OR_FILEINFO,
- "an optional status, then document to be redirected and "
- "destination URL"),
- AP_INIT_TAKE2("AliasMatch", add_alias_regex, NULL, RSRC_CONF,
- "a regular expression and a filename"),
- AP_INIT_TAKE2("ScriptAliasMatch", add_alias_regex, "cgi-script", RSRC_CONF,
- "a regular expression and a filename"),
- AP_INIT_TAKE23("RedirectMatch", add_redirect_regex,
- (void *) HTTP_MOVED_TEMPORARILY, OR_FILEINFO,
- "an optional status, then a regular expression and "
- "destination URL"),
- AP_INIT_TAKE2("RedirectTemp", add_redirect2,
- (void *) HTTP_MOVED_TEMPORARILY, OR_FILEINFO,
- "a document to be redirected, then the destination URL"),
- AP_INIT_TAKE2("RedirectPermanent", add_redirect2,
- (void *) HTTP_MOVED_PERMANENTLY, OR_FILEINFO,
- "a document to be redirected, then the destination URL"),
- {NULL}
-};
-
static int alias_matches(const char *uri, const char *alias_fakename)
{
const char *aliasp = alias_fakename, *urip = uri;
@@ -455,6 +447,17 @@ static char *try_alias(request_rec *r)
return PREGSUB_ERROR;
}
+ if (dirconf->alias_fake && dirconf->alias_preserve_path == ALIAS_FLAG_ON) {
+ int l;
+
+ l = alias_matches(r->uri, dirconf->alias_fake);
+
+ if (l > 0) {
+ ap_set_context_info(r, dirconf->alias_fake, found);
+ found = apr_pstrcat(r->pool, found, r->uri + l, NULL);
+ }
+ }
+
if (dirconf->handler) { /* Set handler, and leave a note for mod_cgi */
r->handler = dirconf->handler;
apr_table_setn(r->notes, "alias-forced-type", r->handler);
@@ -618,31 +621,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;
}
@@ -673,31 +678,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);
}
- apr_table_setn(r->headers_out, "Location", 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;
+ }
+ }
+ /* 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;
}
@@ -705,6 +710,41 @@ static int fixup_redir(request_rec *r)
return DECLINED;
}
+static const command_rec alias_cmds[] =
+{
+ AP_INIT_TAKE12("Alias", add_alias, NULL, RSRC_CONF | ACCESS_CONF,
+ "a fakename and a realname, or a realname in a Location"),
+ AP_INIT_TAKE12("ScriptAlias", add_alias, "cgi-script", RSRC_CONF | ACCESS_CONF,
+ "a fakename and a realname, or a realname in a Location"),
+ AP_INIT_TAKE123("Redirect", add_redirect, (void *) HTTP_MOVED_TEMPORARILY,
+ OR_FILEINFO,
+ "an optional status, then document to be redirected and "
+ "destination URL"),
+ AP_INIT_TAKE2("AliasMatch", add_alias_regex, NULL, RSRC_CONF,
+ "a regular expression and a filename"),
+ AP_INIT_TAKE2("ScriptAliasMatch", add_alias_regex, "cgi-script", RSRC_CONF,
+ "a regular expression and a filename"),
+ AP_INIT_TAKE23("RedirectMatch", add_redirect_regex,
+ (void *) HTTP_MOVED_TEMPORARILY, OR_FILEINFO,
+ "an optional status, then a regular expression and "
+ "destination URL"),
+ AP_INIT_TAKE2("RedirectTemp", add_redirect2,
+ (void *) HTTP_MOVED_TEMPORARILY, OR_FILEINFO,
+ "a document to be redirected, then the destination URL"),
+ 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"),
+ AP_INIT_FLAG("AliasPreservePath", ap_set_flag_slot,
+ (void*)APR_OFFSETOF(alias_dir_conf, alias_preserve_path), OR_FILEINFO,
+ "Set to ON to map the full path after the fakename to the realname."),
+
+ {NULL}
+};
+
+
static void register_hooks(apr_pool_t *p)
{
static const char * const aszSucc[]={ "mod_userdir.c",