Using Traefik version 1.7.12 deployed to Azure Service Fabric.
I'd like Traefik to add cache-control header to the responses of certain requests from a web app which is also deployed to the cluster. The way I found this can be done is to create 2 separate services with different frontend routing rules for my application. The final result would be something like this:
Route Rule
Host:devmachine.localhost;PathPrefix:/
which adds "cache-control:no-cache" response header.
AND
Route Rule
Host:devmachine.localhost;Path:/{url:(.*)(/banner$|\.(js|css)\??)}
which adds "cache-control:max-age:86400" response header.
Here is a snippet from each service's manifest in the cluster respectively:
<Extensions>
<Extension Name="Traefik">
<Labels xmlns="http://schemas.microsoft.com/2015/03/fabact-no-schema">
<Label Key="traefik.enable">true</Label>
<Label Key="traefik.frontend.passHostHeader">true</Label>
<Label Key="traefik.frontend.rule">Host:devmachine.localhost;PathPrefix:/</Label>
<Label Key="traefik.backend.loadbalancer.stickiness">true</Label>
<Label Key="traefik.backend.healthcheck.path">/somepage</Label>
<Label Key="traefik.backend.healthcheck.interval">60s</Label>
<label key="traefik.frontend.headers.customResponseHeaders">cache-control:no-cache</label>
</Labels>
</Extension>
</Extensions>
AND
<Extensions>
<Extension Name="Traefik">
<Labels xmlns="http://schemas.microsoft.com/2015/03/fabact-no-schema">
<Label Key="traefik.enable">true</Label>
<Label Key="traefik.frontend.passHostHeader">true</Label>
<Label Key="traefik.frontend.rule">Host:devmachine.localhost;Path:/{url:(.*)(/banner$|\\.(js|css)\\??)}</Label>
<label key="traefik.frontend.headers.customResponseHeaders">cache-control:max-age=86400</label>
<label key="traefik.frontend.priority">200</label>
</Labels>
</Extension>
</Extensions>
Problem is that all my responses are getting "no-cache" header, as if the 2nd matcher isn't applied, including the following sample URIs (which are supposed to be handled by the 2nd routing rule):
https://example.com/banner
https://example.com/scripts/some.js
https://example.com/scripts/some-hdbxy778.js
https://example.com/scripts/someother.js?v=2.744
This is despite the fact that the 2nd routing rule is longer (since traefik is supposed to sort them by length descendingly) and the manual setting of priority (200).
This turned out to be a casing issue. Service Fabric provider in traefik deserializes extension configurations into a local type utilizing "xml.Unmarshal".
According to the docs (https://golang.org/pkg/encoding/xml/#Unmarshal)
Unmarshal uses a case-sensitive comparison to match XML element names to tag values and struct field names.
Which makes sense.
Traefik's documentation was updated to point this out: https://github.com/containous/traefik/pull/5160