</usage>
</directivesynopsis>
+<directivesynopsis>
+<name>SubstituteInheritBefore</name>
+<description>Change the merge order of inherited patterns</description>
+<syntax>SubstituteInheritBefore on|off</syntax>
+<default>SubstituteInheritBefore off</default>
+<contextlist><context>directory</context>
+<context>.htaccess</context></contextlist>
+<override>FileInfo</override>
+<compatibility>Available in httpd 2.4.17 and later</compatibility>
+
+<usage>
+ <p>Whether to apply the inherited <directive>Substitute</directive>
+ patterns first (<code>on</code>), or after the ones of the current
+ context (<code>off</code>).
+ The former was the default in versions 2.4 and earlier, but changed
+ starting with 2.5, hence <directive>SubstituteInheritBefore</directive>
+ set to <code>on</code> allows to restore the legacy behaviour.
+ <directive>SubstituteInheritBefore</directive> is itself inherited,
+ hence contexts that inherit it (those that don't specify their own
+ <directive>SubstituteInheritBefore</directive> value) will apply the
+ closest defined merge order.
+</usage>
+</directivesynopsis>
+
</modulesynopsis>
apr_array_header_t *patterns;
apr_size_t max_line_length;
int max_line_length_set;
+ int inherit_before_set,
+ inherit_before;
} subst_dir_conf;
typedef struct {
subst_dir_conf *base = (subst_dir_conf *) basev;
subst_dir_conf *over = (subst_dir_conf *) overv;
- a->patterns = apr_array_append(p, base->patterns,
- over->patterns);
+ if (!over->inherit_before_set) {
+ over->inherit_before = base->inherit_before;
+ }
+ if (over->inherit_before) {
+ a->patterns = apr_array_append(p, base->patterns,
+ over->patterns);
+ }
+ else {
+ a->patterns = apr_array_append(p, over->patterns,
+ base->patterns);
+ }
a->max_line_length = over->max_line_length_set ?
over->max_line_length : base->max_line_length;
a->max_line_length_set = over->max_line_length_set ?
return NULL;
}
+static const char *set_inherit_before(cmd_parms *cmd, void *cfg, int flag)
+{
+ subst_dir_conf *dcfg = (subst_dir_conf *)cfg;
+
+ dcfg->inherit_before = (flag != 0);
+ dcfg->inherit_before_set = 1;
+
+ return NULL;
+}
+
#define PROTO_FLAGS AP_FILTER_PROTO_CHANGE|AP_FILTER_PROTO_CHANGE_LENGTH
static void register_hooks(apr_pool_t *pool)
{
"Pattern to filter the response content (s/foo/bar/[inf])"),
AP_INIT_TAKE1("SubstituteMaxLineLength", set_max_line_length, NULL, OR_FILEINFO,
"Maximum line length"),
+ AP_INIT_FLAG("SubstituteInheritBefore", set_inherit_before, NULL, OR_FILEINFO,
+ "Apply inherited patterns before those of the current context"),
{NULL}
};