Define multiple Access-Control-Allow-Origin

We host files on our “cdn”, and we wanted to restrict access from only our servers - many of them, running under multiple domain names - so we had to define Access-Control-Allow-Origin for multiple origins.

After many tries and errors, we ended with this configuration: {
    root * /var/www/
    import standard_conf

    @allowedOrigin expression `{http.request.header.Origin}.matches('^https?://.*\\.cilex4\\.com.*$') || 
                    {http.request.header.Origin}.matches('^https?://.*\\.cilex5\\.com.*$') || 

  header @allowedOrigin {
    Access-Control-Allow-Origin {http.request.header.Origin}
    Access-Control-Allow-Methods GET, HEAD, OPTIONS
    Access-Control-Allow-Headers Authorization, Content-Type, Accept
    Access-Control-Max-Age 86400

Hope it helps other!

( was added to allow testing from jsfiddle)

Caddy is great, but we find the doc confusing and poorly helpful…

1 Like

Comments like this aren’t helpful either. If you don’t specify exactly what you found confusing, then there’s no way we can improve the docs.

Please elaborate. What are you confused about?

FYI, you can use the Caddyfile placeholder shortcut {header.Origin} instead.

These aren’t correct – if a header value contains spaces, then you need to quote them. Otherwise, Caddy will interpret them as individual tokens separated by the spaces, and that changes the behaviour. For example if there’s two tokens following the header name, then it’s a header replacement operation, instead of setting a value.

You can probably simplify your regexp by using | for each domain. Try something like this:


Thank you for your answer @francislavoie . Sorry if my comment wasn’t super helpful (I’m fully aware it wasn’t really).

I just searched a lot on the doc site, on the forum, etc and never managed to find a working or workable example about how to achieve this goal about having a large, readable and maintainable list of sites authorized to access the resource. Finally it was which did put me on the right way…

Thanks of lot for your hints about {header.Origin} and quoting Access-Control-Allow-Methods and -Headers! You’re obviously 100% right, I’m going to apply them now.

Please, don’t consider I’m trolling with this next remark - it’s just to illustrate why I find it difficult to use the doc: I have searched the Doc server right now for “header.Origin” or “origin”, and the search engine brought no answer.

Again, Caddy is great.

1 Like

Caddy doesn’t document specifics for individual HTTP headers; it doesn’t make sense to do so, that’s not really a concern of the webserver specifically. Some headers do have special meaning, and we do call those out (e.g. Host and some proxy headers like X-Forwarded-*) but most only have a meaning to clients.

We document how to match against and manipulate headers, it’s the user’s job to connect the dots to do what they need.

Right - now I’ve found on Caddyfile Concepts — Caddy Documentation that {header.*} {http.request.header.*} allows to use {header.Origin} instead of {http.request.header.Origin}.

Not using Caddy every day, I have the feeling that I should have read and memorized all of the doc, examples, wikis and stackoverflow to be able to use it properly.

Perhaps next time I’ll just ask my question directly - but I always try to find solutions be myself before bothering the authors.


Thanks again !

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.