Caddy: header directive does not overwrite proxy-set headers

Created on 19 Aug 2020  路  3Comments  路  Source: caddyserver/caddy

My backend service sets some headers for local development, but I want them overwritten by Caddy with safer values. The documentation clearly states:

  • is the name of the header field. By default, will overwrite any existing field of the same name. Prefix with + to add the field instead of replace, or prefix with - to remove the field.

However, the following snippet:

# allow everything from every origin
header {
    access-control-allow-credentials true
    access-control-allow-headers "content-type, range"
    access-control-allow-methods "DELETE, GET, PATCH, POST"
    access-control-allow-origin {http.request.header.origin}
    access-control-expose-headers content-range
}

Is not overwriting the values, it is just prepending them. The response is:

access-control-allow-credentials: true
access-control-allow-credentials: true
access-control-allow-headers: content-type, range
access-control-allow-headers: Content-Type
access-control-allow-headers: Range
access-control-allow-methods: DELETE, GET, PATCH, POST
access-control-allow-methods: DELETE
access-control-allow-methods: GET
access-control-allow-methods: PATCH
access-control-allow-methods: POST
access-control-allow-origin: https://localhost:1234
access-control-allow-origin: http://localhost:1234
access-control-expose-headers: content-range
access-control-expose-headers: Content-Range
access-control-max-age: 86400

This duplication of headers breaks everything, as browsers just consider the duplicate entries to be invalid.

While at that: how do I handle multiple value headers, such as access-control-allow-methods and access-control-allow-headers? My backend handles it differently (one per like) than this Caddy config.

question

All 3 comments

Thanks for the issue, but this seems to be working as intended. As per the docs:

By default, header operations are performed immediately unless any of the headers are being deleted, in which case the header operations are automatically deferred until the time they are being written to the client.

This means that the backend is actually _appending_ the headers, not the other way around: the headers middleware is _not_ prepending them.

~There's no way to manually defer these operations yet using the Caddyfile, but you can absolutely use the JSON config's deferred property with a value of true to do this.~ Edit: Derp, yes there is, the defer subdirective.

Alternatively, you can use the header_down subdirective of reverse_proxy to make adjustments there instead: https://caddyserver.com/docs/caddyfile/directives/reverse_proxy

@mholt actually, after reading your answer, I can do that with just Caddyfile using defer.

Oops, you're right. I forgot about that and didn't read the docs myself.

Was this page helpful?
0 / 5 - 0 ratings