From: Luca Toscano Date: Sat, 20 Oct 2018 09:21:47 +0000 (+0000) Subject: mod_headers.xml: clarify the difference between X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6e8ce294c024fb2a7b96627ff0a6e6ad629e68a0;p=apache mod_headers.xml: clarify the difference between onsuccess vs always In PR 62380 a user was confused why Header set always was not overriding a header set by a HTTP backend managed via mod_proxy_http. The difference between 'onsuccess' and 'always' is really subtle, even if somebody is familiar with r->headers_out and r->err_headers_out and the httpd's internals. As Stefan mentioned over email, the absence of a "normalized" headers list in the response should be explained, so I tried to do so in this commit. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1844401 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/docs/manual/mod/mod_headers.xml b/docs/manual/mod/mod_headers.xml index 143214d035..e14a632c1a 100644 --- a/docs/manual/mod/mod_headers.xml +++ b/docs/manual/mod/mod_headers.xml @@ -328,16 +328,12 @@ available in 2.4.10 and later modified.

The optional condition argument determines which internal - table of responses headers this directive will operate against. Despite the - name, the default value of onsuccess does not limit - an action to responses with a 2xx status code. Headers set under - this condition are still used when, for example, a request is successfully - proxied or generated by CGI, even when they have generated a failing status code.

- -

When your action is a function of an existing header, you may need to specify - a condition of always, depending on which internal table the - original header was set in. The table that corresponds to always is - used for locally generated error responses as well as successful responses. + 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:

@@ -346,14 +342,42 @@ available in 2.4.10 and later
  • 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 always is used in the ultimate response.
  • -
  • You're modifying or removing a header generated by a CGI script, - in which case the CGI scripts are in the table corresponding to +
  • You're modifying or removing a header generated by a CGI script + or by mod_proxy_fcgi, + in which case the CGI scripts' headers are in the table corresponding to always and not in the default table.
  • You're modifying or removing a header generated by some piece of the server but that header is not being found by the default onsuccess condition.
  • +

    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.

    @@ -362,6 +386,14 @@ available in 2.4.10 and later argument (second argument if a condition is specified). This can be one of the following values:

    + 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.

    +
    +
    add
    The response header is added to the existing set of headers,