ASF Bugzilla – Attachment 36018 Details for
Bug 57337
Content negotiation fails with conditional Redirect
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Propsed patch (first attempt, against 2.4.33)
conditional_vhost_redirect_fix-v1-2.4.33.patch (text/plain), 11.17 KB, created by
Alex Smith
on 2018-07-07 16:34:48 UTC
(
hide
)
Description:
Propsed patch (first attempt, against 2.4.33)
Filename:
MIME Type:
Creator:
Alex Smith
Created:
2018-07-07 16:34:48 UTC
Size:
11.17 KB
patch
obsolete
>diff -rU 10 httpd-2.4.33/modules/mappers/mod_alias.c httpd-2.4.33-patched/modules/mappers/mod_alias.c >--- httpd-2.4.33/modules/mappers/mod_alias.c 2018-02-13 23:43:36.000000000 +0000 >+++ httpd-2.4.33-patched/modules/mappers/mod_alias.c 2018-07-07 16:06:47.270120336 +0100 >@@ -46,20 +46,21 @@ > } alias_entry; > > typedef struct { > apr_array_header_t *aliases; > apr_array_header_t *redirects; > } alias_server_conf; > > typedef struct { > unsigned int alias_set:1; > unsigned int redirect_set:1; >+ apr_array_header_t *aliases; > apr_array_header_t *redirects; > const ap_expr_info_t *alias; > char *handler; > const ap_expr_info_t *redirect; > int redirect_status; /* 301, 302, 303, 410, etc */ > } alias_dir_conf; > > module AP_MODULE_DECLARE_DATA alias_module; > > static char magic_error_value; >@@ -72,20 +73,21 @@ > > a->aliases = apr_array_make(p, 20, sizeof(alias_entry)); > a->redirects = apr_array_make(p, 20, sizeof(alias_entry)); > return a; > } > > 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->aliases = apr_array_make(p, 2, sizeof(alias_entry)); > a->redirects = apr_array_make(p, 2, sizeof(alias_entry)); > return a; > } > > static void *merge_alias_config(apr_pool_t *p, void *basev, void *overridesv) > { > alias_server_conf *a = > (alias_server_conf *) apr_pcalloc(p, sizeof(alias_server_conf)); > alias_server_conf *base = (alias_server_conf *) basev; > alias_server_conf *overrides = (alias_server_conf *) overridesv; >@@ -95,109 +97,128 @@ > return a; > } > > static void *merge_alias_dir_config(apr_pool_t *p, void *basev, void *overridesv) > { > alias_dir_conf *a = > (alias_dir_conf *) apr_pcalloc(p, sizeof(alias_dir_conf)); > alias_dir_conf *base = (alias_dir_conf *) basev; > alias_dir_conf *overrides = (alias_dir_conf *) overridesv; > >+ a->aliases = apr_array_append(p, overrides->aliases, base->aliases); > a->redirects = apr_array_append(p, overrides->redirects, base->redirects); > > a->alias = (overrides->alias_set == 0) ? base->alias : overrides->alias; > 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; > > return a; > } > > /* need prototype for overlap check */ > static int alias_matches(const char *uri, const char *alias_fakename); > >-static const char *add_alias_internal(cmd_parms *cmd, void *dummy, >+static const char *add_alias_internal(cmd_parms *cmd, alias_dir_conf *dirconf, > const char *fake, const char *real, > int use_regex) > { >+ alias_entry *new; > server_rec *s = cmd->server; >- alias_server_conf *conf = ap_get_module_config(s->module_config, >- &alias_module); >- alias_entry *new = apr_array_push(conf->aliases); >- alias_entry *entries = (alias_entry *)conf->aliases->elts; >- int i; >+ alias_server_conf *serverconf = ap_get_module_config(s->module_config, >+ &alias_module); > > /* XXX: real can NOT be relative to DocumentRoot here... compat bug. */ > > const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_CONTEXT); > > if (err != NULL) { > return err; > } > >- if (use_regex) { >- new->regexp = ap_pregcomp(cmd->pool, fake, AP_REG_EXTENDED); >- if (new->regexp == NULL) >- return "Regular expression could not be compiled."; >- new->real = real; >- } >- else { >- /* XXX This may be optimized, but we must know that new->real >- * exists. If so, we can dir merge later, trusing new->real >- * and just canonicalizing the remainder. Not till I finish >- * cleaning out the old ap_canonical stuff first. >- */ >- new->real = real; >- } >- new->fake = fake; >- new->handler = cmd->info; >- > /* check for overlapping (Script)Alias directives > * and throw a warning if found one > */ > if (!use_regex) { >- for (i = 0; i < conf->aliases->nelts - 1; ++i) { >- alias_entry *alias = &entries[i]; >+ int num_server_elts = serverconf->aliases->nelts; >+ int num_dir_elts = dirconf->aliases->nelts; >+ int total_elts = num_server_elts + num_dir_elts; >+ int i; >+ >+ for (i = 0; i < total_elts; ++i) { >+ alias_entry *alias; >+ if (i < num_server_elts) { >+ alias = &serverconf->aliases->elts[i]; >+ } >+ else { >+ alias = &dirconf->aliases->elts[i - num_server_elts]; >+ } > > if ( (!alias->regexp && alias_matches(fake, alias->fake) > 0) > || (alias->regexp && !ap_regexec(alias->regexp, fake, 0, NULL, 0))) { > ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server, APLOGNO(00671) > "The %s directive in %s at line %d will probably " > "never match because it overlaps an earlier " > "%sAlias%s.", > cmd->cmd->name, cmd->directive->filename, > cmd->directive->line_num, > alias->handler ? "Script" : "", > alias->regexp ? "Match" : ""); > > break; /* one warning per alias should be sufficient */ > } > } > } > >+ /* Add a new entry for the alias in either the server or per-directory >+ * (including e.g. <If> section) configuration, as appropriate. >+ */ >+ if (cmd->path) { >+ new = apr_array_push(dirconf->aliases); >+ } >+ else { >+ new = apr_array_push(serverconf->aliases); >+ } >+ >+ if (use_regex) { >+ new->regexp = ap_pregcomp(cmd->pool, fake, AP_REG_EXTENDED); >+ if (new->regexp == NULL) >+ return "Regular expression could not be compiled."; >+ new->real = real; >+ } >+ else { >+ /* XXX This may be optimized, but we must know that new->real >+ * exists. If so, we can dir merge later, trusing new->real >+ * and just canonicalizing the remainder. Not till I finish >+ * cleaning out the old ap_canonical stuff first. >+ */ >+ new->real = real; >+ } >+ new->fake = fake; >+ new->handler = cmd->info; >+ > return NULL; > } > >-static const char *add_alias(cmd_parms *cmd, void *dummy, const char *fake, >+static const char *add_alias(cmd_parms *cmd, void *dirconfv, const char *fake, > const char *real) > { >+ alias_dir_conf *dirconf = (alias_dir_conf *) dirconfv; > if (real) { > >- return add_alias_internal(cmd, dummy, fake, real, 0); >+ return add_alias_internal(cmd, dirconf, fake, real, 0); > > } > else { >- alias_dir_conf *dirconf = (alias_dir_conf *) dummy; >- > const char *err = ap_check_cmd_context(cmd, NOT_IN_DIRECTORY|NOT_IN_FILES); > > if (err != NULL) { > return err; > } > > if (!cmd->path) { > return "Alias must have two arguments when used globally"; > } > >@@ -211,24 +232,24 @@ > } > > dirconf->handler = cmd->info; > dirconf->alias_set = 1; > > return NULL; > > } > } > >-static const char *add_alias_regex(cmd_parms *cmd, void *dummy, >+static const char *add_alias_regex(cmd_parms *cmd, void *dirconfv, > const char *fake, const char *real) > { >- return add_alias_internal(cmd, dummy, fake, real, 1); >+ return add_alias_internal(cmd, (alias_dir_conf *) dirconfv, fake, real, 1); > } > > static const char *add_redirect_internal(cmd_parms *cmd, > alias_dir_conf *dirconf, > const char *arg1, const char *arg2, > const char *arg3, int use_regex) > { > alias_entry *new; > server_rec *s = cmd->server; > alias_server_conf *serverconf = ap_get_module_config(s->module_config, >@@ -598,29 +619,44 @@ > > } > > return NULL; > } > > static int translate_alias_redir(request_rec *r) > { > ap_conf_vector_t *sconf = r->server->module_config; > alias_server_conf *serverconf = ap_get_module_config(sconf, &alias_module); >+ void *dconf = r->per_dir_config; >+ alias_dir_conf *dirconf = >+ (alias_dir_conf *) ap_get_module_config(dconf, &alias_module); > char *ret; > int status; > > if (r->uri[0] != '/' && r->uri[0] != '\0') { > return DECLINED; > } > >+ /* Look for matching redirections in the following order: >+ * - The whole-<Location> redirect in the <Location> that is relevant to >+ * this request, if there is one. >+ * - An unconditional server / vhost redirect. >+ * - A per-directory redirect at the top-level for the server / vhost, >+ * which may have come from a conditional <If> section -- we only expect >+ * that much to have been merged into r->per_dir_config at this point, >+ * since we are still translating URLs and mapping them to the file >+ * system. >+ */ > if ((ret = try_redirect(r, &status)) != NULL > || (ret = try_alias_list(r, serverconf->redirects, 1, &status)) >+ != NULL >+ || (ret = try_alias_list(r, dirconf->redirects, 1, &status)) > != NULL) { > 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 " >@@ -640,22 +676,34 @@ > */ > 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; > } > >+ /* Look for matching aliases in the following order: >+ * - The whole-<Location> alias in the <Location> that is relevant to this >+ * request, if there is one. >+ * - An unconditional server / vhost alias. >+ * - A per-directory alias at the top-level for the server / vhost, >+ * which may have come from a conditional <If> section -- we only expect >+ * that much to have been merged into r->per_dir_config since at this >+ * point we are translating URLs, before mapping to the file system can >+ * occur. >+ */ > if ((ret = try_alias(r)) != NULL > || (ret = try_alias_list(r, serverconf->aliases, 0, &status)) >+ != NULL >+ || (ret = try_alias_list(r, dirconf->aliases, 0, &status)) > != NULL) { > r->filename = ret; > return OK; > } > > return DECLINED; > } > > static int fixup_redir(request_rec *r) > {
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 57337
: 36018 |
36019