diff options
author | Eric Covener <covener@apache.org> | 2020-02-06 00:05:44 +0100 |
---|---|---|
committer | Eric Covener <covener@apache.org> | 2020-02-06 00:05:44 +0100 |
commit | 584b83f2aa2c429d6c815f67e1f03d601de53560 (patch) | |
tree | 92b982f3ecb04d3a971e3fc31ebc58fc72dc4883 /docs/manual/mod/mod_headers.xml | |
parent | fr doc rebuild. (diff) | |
download | apache2-584b83f2aa2c429d6c815f67e1f03d601de53560.tar.xz apache2-584b83f2aa2c429d6c815f67e1f03d601de53560.zip |
rework the mysteries of onsuccess and always
I thought I was well-versed in this topic but reading my own text and
r1844401 while playing with samesite recipes made me want to rewrite it.
Pushed the advice down into the actions.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1873675 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to '')
-rw-r--r-- | docs/manual/mod/mod_headers.xml | 126 |
1 files changed, 58 insertions, 68 deletions
diff --git a/docs/manual/mod/mod_headers.xml b/docs/manual/mod/mod_headers.xml index e14a632c1a..e2f9748e22 100644 --- a/docs/manual/mod/mod_headers.xml +++ b/docs/manual/mod/mod_headers.xml @@ -330,68 +330,16 @@ available in 2.4.10 and later</compatibility> <p> The optional <var>condition</var> argument determines which internal 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> - - <ul> - <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 - or by <module>mod_proxy_fcgi</module>, - 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>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 - <module>mod_proxy_fcgi</module> and your backend PHP scripts adds the - <code>X-Foo: bar</code> header to each HTTP response. As described above, - <module>mod_proxy_fcgi</module> 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> - - <highlight language="config"> -# X-Foo's value is set in the 'onsuccess' headers table -Header set X-Foo: baz - </highlight> - - <p>To circumvent this limitation, there are some known configuration - patterns that can help, like the following:</p> - - <highlight language="config"> -# 'onsuccess' can be omitted since it is the default -Header onsuccess unset X-Foo -Header always set X-Foo "baz" - </highlight> - - <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> + Guidance on when to specify <code>always</code> is provided relative to each + action below. </p> <note type="warning"><title>Warning</title> - <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> + <p>Carefully read the difference between <code>always</code> + and <code>onsuccess</code> for each action listed below as the + behavior can be unintuitive and is a frequent source of confusion. + Where the guidance suggest repeating the conditions, it is safe to try + each experimentally and use the one you find effective to match the + pre-existing header.</p> </note> <dl> @@ -400,19 +348,30 @@ Header always set X-Foo "baz" even if this header already exists. This can result in two (or more) headers having the same name. This can lead to unforeseen consequences, and in general <code>set</code>, - <code>append</code> or <code>merge</code> should be used instead.</dd> + <code>append</code> or <code>merge</code> should be used instead. + <p>Specify a condition of <code>always</code> if you want the header to + be included in non-2xx response (such as redirects or errors)</p> + </dd> <dt><code>append</code></dt> <dd>The response header is appended to any existing header of the same name. When a new value is merged onto an existing header it is separated from the existing header with a comma. - This is the HTTP standard way of giving a header multiple values.</dd> + This is the HTTP standard way of giving a header multiple values. + <p>If the header was added by this module, you must match the condition + parameter that was originally used. Otherwise, you must determine by trial + and error whether <code>always</code> should be specified because you can't + reliably know which internal table the existing value is present in.</p> + </dd> <dt><code>echo</code></dt> <dd>Request headers with this name are echoed back in the response headers. <var>header</var> may be a <glossary ref="regex">regular expression</glossary>. - <var>value</var> must be omitted.</dd> + <var>value</var> must be omitted. + <p>Specify a condition of <code>always</code> if you want the header to + be included in non-2xx response (such as redirects or errors).</p> + </dd> <dt><code>edit</code></dt> <dt><code>edit*</code></dt> @@ -424,7 +383,11 @@ Header always set X-Foo "baz" The <code>edit</code> form will match and replace exactly once in a header value, whereas the <code>edit*</code> form will replace <em>every</em> instance of the search pattern if it appears more - than once.</dd> + than once. + <p>Because you cannot reliably know which internal header table might have a match, + you should repeat your edit/edit* directive with both <code>always</code> and + <code>onsuccess</code>.</p> + </dd> <dt><code>merge</code></dt> <dd>The response header is appended to any existing header of @@ -434,15 +397,32 @@ Header always set X-Foo "baz" This is the HTTP standard way of giving a header multiple values. Values are compared in a case sensitive manner, and after all format specifiers have been processed. Values in double quotes - are considered different from otherwise identical unquoted values.</dd> + are considered different from otherwise identical unquoted values. + <p>If the header was added by this module, you must match the condition + parameter that was originally used. Otherwise, you must determine by trial + and error whether <code>always</code> should be specified because you can't + reliably know which internal table the existing value is present in.</p> + </dd> + <dt><code>set</code></dt> <dd>The response header is set, replacing any previous header - with this name. The <var>value</var> may be a format string.</dd> + with this name. The <var>value</var> may be a format string. + <p>If the header was added by this module, you must match the condition + parameter that was originally used. Otherwise, you must determine by trial + and error whether <code>always</code> should be specified because you can't + reliably know which internal table the existing value is present in.</p> + </dd> + <dt><code>setifempty</code></dt> <dd>The request header is set, but only if there is no previous header with this name. + <p>If the header was added by this module, you must match the condition + parameter that was originally used. Otherwise, you must determine by trial + and error whether <code>always</code> should be specified because you can't + reliably know which internal table the existing value is present in.</p> + <note> The Content-Type header is a special use case since there might be the chance that its value have been determined but the header is not part @@ -454,17 +434,27 @@ Header always set X-Foo "baz" </highlight> </note></dd> + <dt><code>unset</code></dt> <dd>The response header of this name is removed, if it exists. If there are multiple headers of the same name, all will be - removed. <var>value</var> must be omitted.</dd> + removed. <var>value</var> must be omitted. + <p>Because you cannot reliably know which internal header table might have a match, + you should repeat your this directive with both <code>always</code> and + <code>onsuccess</code>.</p> + </dd> <dt><code>note</code></dt> <dd>The value of the named response <var>header</var> is copied into an internal note whose name is given by <var>value</var>. This is useful if a header sent by a CGI or proxied resource is configured to be unset but should also be logged.<br /> - Available in 2.4.7 and later.</dd> + Available in 2.4.7 and later. + <p>If the header was added by this module, you must match the condition + parameter that was originally used. Otherwise, you must determine by trial + and error whether <code>always</code> should be specified because you can't + reliably know which internal table the existing value is present in.</p> + </dd> </dl> |