Commit 0de3c9a2 authored by Luca Toscano's avatar Luca Toscano
Browse files

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
parent 8a114a4c
Loading
Loading
Loading
Loading
+44 −12
Changes for docs/manual/mod/mod_headers.xml: 44 added lines, 12 removed lines.
Original line number Diff line number Diff line
@@ -328,16 +328,12 @@ available in 2.4.10 and later</compatibility>
    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>
@@ -346,14 +342,42 @@ available in 2.4.10 and later</compatibility>
       <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 <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>
@@ -362,6 +386,14 @@ available in 2.4.10 and later</compatibility>
    argument (second argument if a <var>condition</var> is specified).
    This can be one of the following values:</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>
    </note>

    <dl>
    <dt><code>add</code></dt>
    <dd>The response header is added to the existing set of headers,