Apache: difference between "Header always set" and "Header set"?

25,827

What is the difference between Header always set and Header set in Apache?

As the quoted bit from the manual says, without 'always' your additions will only go out on succesful responses.

But this also includes "successfully" forward errors via mod_proxy and perhaps other similar handlers that roughly act like proxies. What generates your 404s that you found to disagree with the manual? A 404 on a local file certainly behaves as the quoted bit describes.

That is, what does the always keyword change about the circumstances under which the header is set?

Apache's API keeps two lists associated with each request, headers and err_headers. The former is not used if the server encounters an error processing the request the latter is.

Should I always set my headers using always?

It depends on their significance. Let's say you were setting Cache-Control headers that were related to what you had expected to serve for some resource. Now let's say you were actually serving something like a 400 or 502. You might not want that cached!

Is there any reason not to?

See above.

-/-

There is also a bit in the manual you did not quote which explains the proxy or CGI of an error code but not for one which Apache is generating an error response for:

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.

Share:
25,827

Related videos on Youtube

caleb531
Author by

caleb531

Hi, I'm Caleb Evans. Here's a little about me: Who I am: a college student from Carlsbad, California What I love: my Lord Jesus Christ, programming, spending time with family, eating pizza What I do: create HTML5 web applications, build useful tools Favorite operating system: OS X Favorite editor: Atom Favorite language: Python Spaces or tabs? Depends.

Updated on September 18, 2020

Comments

  • caleb531
    caleb531 over 3 years

    Questions

    1. What is the difference between Header always set and Header set in Apache?
    2. That is, what does the always keyword change about the circumstances under which the header is set?
    3. Should I always set my headers using always?
    4. Is there any reason not to?

    Background

    I've seen...

    Header always set X-Frame-Options DENY
    

    ...as well as...

    Header always set Access-Control-Allow-Headers "*"
    

    ...and I sometimes hear that the presence of the always keyword ensures that the header is properly set, or that it's simply better to include the always keyword in general. However, I have never found a clear, definitive answer for why that is the case.

    I've already checked the Apache docs for mod_headers, which only briefly mention always:

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

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

    As far as I can tell, this means that Header set always ensures that the header is set even on non-200 pages. However, my HTTP headers set with Header set have always seemed to apply just fine on my 404 pages and such. Am I misunderstanding something here?

    FWIW, I've found SO posts like What is the difference between "always" and "onsuccess" in Apache's Header config?, but the only answer there didn't really explain it clearly for me.

    Thanks very much,
    Caleb

  • caleb531
    caleb531 over 7 years
    Thank you for your clear answers. The 404 issue I am experiencing is on my own personal site (see calebevans.me/blahblah). I am using ErrorDocument in an .htaccess to serve the 404s. In my htaccess, I have Header set X-NotSetWithAlways true, however this header is sent on the aforementioned 404 page (/blahblah), which is why I'm flustered. Any thoughts?
  • Gilles Mordant
    Gilles Mordant over 7 years
    Probably something like the ErrorDocument is handled as a subrequest and the scope of your Header set ... matches the subrequest used to (successfully) serve the ErrorDocument
  • caleb531
    caleb531 over 7 years
    Strange, because the Chrome Dev Tools reports that /blahblah is definitely being served with a 404 status code—both locally and on production—even if I use onsuccess. to set the header. Both the ErrorDocument and the Header set directives are at the top-level of my .htaccess, and I've already tried swapping the order of the directives to no avail. Perhaps it's an Apache bug?
  • Gilles Mordant
    Gilles Mordant over 7 years
    What I mean is that a successful error doc is in the same class as successfully forwarding an "error" generated by CGI or proxy. It's that second subsequent for the errordoc that triggers mod_headers a 2nd time. Since it successfully serves the errordoc, the added header is used