<name>Header</name>
<description>Configure HTTP response headers</description>
<syntax>Header [<var>condition</var>] add|append|echo|edit|edit*|merge|set|unset|note
-<var>header</var> [<var>value</var>] [<var>replacement</var>]
+<var>header</var> [<var>[expr=]value]</var>] [<var>replacement</var>]
[early|env=[!]<var>variable</var>]|expr=<var>expression</var>]
</syntax>
<contextlist><context>server config</context><context>virtual host</context>
<context>directory</context><context>.htaccess</context></contextlist>
<override>FileInfo</override>
-<compatibility>Default condition was temporarily changed to "always" in 2.3.9 and 2.3.10</compatibility>
<usage>
<p>This directive can replace, merge or remove HTTP response
<code>add</code> a <var>value</var> is specified as the next argument.
If <var>value</var>
contains spaces, it should be surrounded by double quotes.
- <var>value</var> may be a character string, a string containing format
- specifiers or a combination of both. The following format specifiers
- are supported in <var>value</var>:</p>
+ <var>value</var> may be a character string, a string containing
+ <module>mod_headers</module> specific format specifiers (and character
+ literals), or an <a href="../expr.html">ap_expr</a> expression prefixed
+ with <em>expr=</em></p>
+
+ <p> The following format specifiers are supported in <var>value</var>:</p>
<table border="1" style="zebra">
<columnspec><column width=".25"/><column width=".75"/></columnspec>
const char *condition_var;
const char *subs;
ap_expr_info_t *expr;
+ ap_expr_info_t *expr_out;
} header_entry;
/* echo_do is used for Header echo to iterate through the request headers*/
* contains a pointer to the function used to format the tag. Then save each
* tag in the tag array anchored in the header_entry.
*/
-static char *parse_format_string(apr_pool_t *p, header_entry *hdr, const char *s)
+static char *parse_format_string(cmd_parms *cmd, header_entry *hdr, const char *s)
{
+ apr_pool_t *p = cmd->pool;
char *res;
/* No string to parse with unset and echo commands */
s = hdr->subs;
}
+ if (!strncmp(s, "expr=", 5)) {
+ const char *err;
+ hdr->expr_out = ap_expr_parse_cmd(cmd, s+5,
+ AP_EXPR_FLAG_STRING_RESULT,
+ &err, NULL);
+ if (err) {
+ return apr_pstrcat(cmd->pool,
+ "Can't parse value expression : ", err, NULL);
+ }
+ return NULL;
+ }
+
hdr->ta = apr_array_make(p, 10, sizeof(format_tag));
while (*s) {
new->condition_var = condition_var;
new->expr = expr;
- return parse_format_string(cmd->pool, new, value);
+ return parse_format_string(cmd, new, value);
}
/* Handle all (xxx)Header directives */
* (formatter) specific to the tag. Handlers return text strings.
* Concatenate the return from each handler into one string that is
* returned from this call.
+ * If the original value was prefixed with "expr=", processing is
+ * handled instead by ap_expr.
*/
static char* process_tags(header_entry *hdr, request_rec *r)
{
int i;
const char *s;
char *str = NULL;
+ format_tag *tag = NULL;
+
+ if (hdr->expr_out) {
+ const char *err;
+ const char *val;
+ val = ap_expr_str_exec(r, hdr->expr_out, &err);
+ if (err) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02557)
+ "Can't evaluate value expression: %s", err);
+ return "";
+ }
+ return apr_pstrdup(r->pool, val);
+ }
- format_tag *tag = (format_tag*) hdr->ta->elts;
+ tag = (format_tag*) hdr->ta->elts;
for (i = 0; i < hdr->ta->nelts; i++) {
s = tag[i].func(r, tag[i].arg);