From: Eric Covener Date: Wed, 5 Feb 2020 23:05:44 +0000 (+0000) Subject: rework the mysteries of onsuccess and always X-Git-Tag: 2.5.0-alpha2-ci-test-only~1682 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=584b83f2aa2c429d6c815f67e1f03d601de53560;p=thirdparty%2Fapache%2Fhttpd.git 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 --- diff --git a/docs/manual/mod/mod_headers.xml b/docs/manual/mod/mod_headers.xml index e14a632c1ad..e2f9748e229 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

The optional condition argument determines which internal table of responses headers this directive will operate against: onsuccess (default, can be omitted) or always. - 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 always is not a superset of - onsuccess with respect to existing headers:

- - - -

This difference between onsuccess and always 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 - mod_proxy_fcgi and your backend PHP scripts adds the - X-Foo: bar header to each HTTP response. As described above, - mod_proxy_fcgi uses the always table to store - headers, so a configuration like the following ends up in the wrong result, namely - having the header duplicated with both values:

- - -# X-Foo's value is set in the 'onsuccess' headers table -Header set X-Foo: baz - - -

To circumvent this limitation, there are some known configuration - patterns that can help, like the following:

- - -# 'onsuccess' can be omitted since it is the default -Header onsuccess unset X-Foo -Header always set X-Foo "baz" - - -

Separately from the condition 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.

- -

The action it performs is determined by the first - argument (second argument if a condition is specified). - This can be one of the following values:

+ Guidance on when to specify always is provided relative to each + action below.

Warning -

Please read the difference between always - and onsuccess 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.

+

Carefully read the difference between always + and onsuccess 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.

@@ -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 set, - append or merge should be used instead. + append or merge should be used instead. +

Specify a condition of always if you want the header to + be included in non-2xx response (such as redirects or errors)

+
append
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.
+ This is the HTTP standard way of giving a header multiple values. +

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 always should be specified because you can't + reliably know which internal table the existing value is present in.

+
echo
Request headers with this name are echoed back in the response headers. header may be a regular expression. - value must be omitted.
+ value must be omitted. +

Specify a condition of always if you want the header to + be included in non-2xx response (such as redirects or errors).

+
edit
edit*
@@ -424,7 +383,11 @@ Header always set X-Foo "baz" The edit form will match and replace exactly once in a header value, whereas the edit* form will replace every instance of the search pattern if it appears more - than once. + than once. +

Because you cannot reliably know which internal header table might have a match, + you should repeat your edit/edit* directive with both always and + onsuccess.

+
merge
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.
+ are considered different from otherwise identical unquoted values. +

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 always should be specified because you can't + reliably know which internal table the existing value is present in.

+ +
set
The response header is set, replacing any previous header - with this name. The value may be a format string.
+ with this name. The value may be a format string. +

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 always should be specified because you can't + reliably know which internal table the existing value is present in.

+ +
setifempty
The request header is set, but only if there is no previous header with this name. +

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 always should be specified because you can't + reliably know which internal table the existing value is present in.

+ 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"
+
unset
The response header of this name is removed, if it exists. If there are multiple headers of the same name, all will be - removed. value must be omitted.
+ removed. value must be omitted. +

Because you cannot reliably know which internal header table might have a match, + you should repeat your this directive with both always and + onsuccess.

+
note
The value of the named response header is copied into an internal note whose name is given by value. This is useful if a header sent by a CGI or proxied resource is configured to be unset but should also be logged.
- Available in 2.4.7 and later.
+ Available in 2.4.7 and later. +

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 always should be specified because you can't + reliably know which internal table the existing value is present in.

+