<tr><th><a href="directive-dict.html#Override">Override:</a></th><td>FileInfo</td></tr>
<tr><th><a href="directive-dict.html#Status">Status:</a></th><td>Extension</td></tr>
<tr><th><a href="directive-dict.html#Module">Module:</a></th><td>mod_headers</td></tr>
-<tr><th><a href="directive-dict.html#Compatibility">Compatibility:</a></th><td>SetIfEmpty available in 2.4.7 and later, expr=value
+<tr><th><a href="directive-dict.html#Compatibility">Compatibility:</a></th><td>SetIfEmpty available in 2.4.7 and later, expr=value
available in 2.4.10 and later</td></tr>
</table>
<p>This directive can replace, merge or remove HTTP response
modified.</p>
<p> The optional <var>condition</var> argument determines which internal
- table of responses headers this directive will operate against. Despite the
- name, the default value of <code>onsuccess</code> does <em>not</em> limit
- an <var>action</var> to responses with a 2xx status code. Headers set under
- this condition are still used when, for example, a request is <em>successfully</em>
- proxied or generated by CGI, even when they have generated a failing status code.</p>
-
- <p>When your action is a function of an existing header, you may need to specify
- a condition of <code>always</code>, depending on which internal table the
- original header was set in. The table that corresponds to <code>always</code> is
- used for locally generated error responses as well as successful responses.
+ table of responses headers this directive will operate against:
+ <code>onsuccess</code> (default, can be omitted) or <code>always</code>.
+ The difference between the two lists is that the headers contained in the
+ latter are added to the response even on error, and persisted across
+ internal redirects (for example, ErrorDocument handlers).
+
Note also that repeating this directive with both conditions makes sense in
some scenarios because <code>always</code> is not a superset of
<code>onsuccess</code> with respect to existing headers:</p>
<li> You're adding a header to a locally generated non-success (non-2xx) response, such
as a redirect, in which case only the table corresponding to
<code>always</code> is used in the ultimate response.</li>
- <li> You're modifying or removing a header generated by a CGI script,
- in which case the CGI scripts are in the table corresponding to
+ <li> You're modifying or removing a header generated by a CGI script
+ or by <code class="module"><a href="../mod/mod_proxy_fcgi.html">mod_proxy_fcgi</a></code>,
+ in which case the CGI scripts' headers are in the table corresponding to
<code>always</code> and not in the default table.</li>
<li> You're modifying or removing a header generated by some piece of
the server but that header is not being found by the default
<code>onsuccess</code> condition.</li>
</ul>
- <p>Separately from the <var>condition</var> parameter described above, you
- can limit an action based on HTTP status codes for e.g. proxied or CGI
+ <p>This difference between <code>onsuccess</code> and <code>always</code> is
+ a feature that resulted as a consequence of how httpd internally stores
+ headers for a HTTP response, since it does not offer any "normalized" single
+ list of headers. The main problem that can arise if the following concept
+ is not kept in mind while writing the configuration is that some HTTP responses
+ might end up with the same header duplicated (confusing users or sometimes even
+ HTTP clients). For example, suppose that you have a simple PHP proxy setup with
+ <code class="module"><a href="../mod/mod_proxy_fcgi.html">mod_proxy_fcgi</a></code> and your backend PHP scripts adds the
+ <code>X-Foo: bar</code> header to each HTTP response. As described above,
+ <code class="module"><a href="../mod/mod_proxy_fcgi.html">mod_proxy_fcgi</a></code> uses the <code>always</code> table to store
+ headers, so a configuration like the following ends up in the wrong result, namely
+ having the header duplicated with both values:</p>
+
+ <pre class="prettyprint lang-config"># X-Foo's value is set in the 'onsuccess' headers table
+Header set X-Foo: baz</pre>
+
+
+ <p>To circumvent this limitation, there are some known configuration
+ patterns that can help, like the following:</p>
+
+ <pre class="prettyprint lang-config"># 'onsuccess' can be omitted since it is the default
+Header onsuccess unset X-Foo
+Header always set X-Foo "baz"</pre>
+
+
+ <p>Separately from the <var>condition</var> parameter described above, you
+ can limit an action based on HTTP status codes for e.g. proxied or CGI
requests. See the example that uses %{REQUEST_STATUS} in the section above.</p>
<p>The action it performs is determined by the first
argument (second argument if a <var>condition</var> is specified).
This can be one of the following values:</p>
+ <div class="warning"><h3>Warning</h3>
+ <p>Please read the difference between <code>always</code>
+ and <code>onsuccess</code> headers list described above
+ before start reading the actions list, since that important
+ concept still applies. Each action, in fact, works as described
+ but only on the target headers list.</p>
+ </div>
+
<dl>
<dt><code>add</code></dt>
<dd>The response header is added to the existing set of headers,
<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
- <code class="module"><a href="../mod/mod_headers.html">mod_headers</a></code> specific format specifiers (and character
+ <var>value</var> may be a character string, a string containing
+ <code class="module"><a href="../mod/mod_headers.html">mod_headers</a></code> 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 class="bordered"><tr class="header"><th>Format</th><th>Description</th></tr>
<em>boolean</em> expressions such as <If>:</p>
<ul>
<li>The starting point of the grammar is 'string' rather than 'expr'.</li>
- <li>Function calls use the %{funcname:arg} syntax rather than
+ <li>Function calls use the %{funcname:arg} syntax rather than
funcname(arg).</li>
<li>Multi-argument functions are not currently accessible from this
starting point</li>
- <li>Quote the entire parameter, such as
+ <li>Quote the entire parameter, such as
<pre class="prettyprint lang-config">Header set foo-checksum "expr=%{md5:foo}"</pre>
</li>
-
+
</ul>
</div>
documented in the <a href="../expr.html">ap_expr</a> documentation.
<pre class="prettyprint lang-config"># This delays the evaluation of the condition clause compared to <If>
Header always set CustomHeader my-value "expr=%{REQUEST_URI} =~ m#^/special_path.php$#"</pre>
-
+
</dd>
</dl>
<code class="directive">Header</code> directives are processed just
before the response is sent to the network. This means that it is
possible to set and/or override most headers, except for some headers
- added by the HTTP header filter. Prior to 2.2.12, it was not possible
+ added by the HTTP header filter. Prior to 2.2.12, it was not possible
to change the Content-Type header with this directive.</p>
<tr><th><a href="directive-dict.html#Override">Override:</a></th><td>FileInfo</td></tr>
<tr><th><a href="directive-dict.html#Status">Status:</a></th><td>Extension</td></tr>
<tr><th><a href="directive-dict.html#Module">Module:</a></th><td>mod_headers</td></tr>
-<tr><th><a href="directive-dict.html#Compatibility">Compatibility:</a></th><td>SetIfEmpty available in 2.4.7 and later, expr=value
+<tr><th><a href="directive-dict.html#Compatibility">Compatibility:</a></th><td>SetIfEmpty available in 2.4.7 and later, expr=value
available in 2.4.10 and later</td></tr>
</table>
<p>This directive can replace, merge, change or remove HTTP request