Cache headers being skipped when origin header is set

Hi there,

I’m seeing strange behavior with and without trailing slash in origin http header. It seems like Chrome selectively adds this header for certain files. On my website https://redastrologer.com, I see origin header added only for font files.

Here’s an example -

Without trailing slash origin:https://redastrologer.com - no expire or cache-control headers are set

curl -kI -H "origin:https://redastrologer.com" -H "cache-control:no-cache" https://redastrologer.com/wp-content/plugins/elementor/assets/lib/font-awesome/webfonts/fa-solid-900.woff2
HTTP/2 200 
date: Thu, 17 Jun 2021 03:45:38 GMT
content-type: font/woff2
content-length: 80300
last-modified: Sat, 12 Jun 2021 19:13:06 GMT
etag: "60c50742-139ac"
x-frame-options: SAMEORIGIN
cf-cache-status: HIT
age: 2963
accept-ranges: bytes
cf-request-id: 0ab9ac213800000ec8b9269000000001
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
report-to: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v2?s=Qi7AQar3jepSNNLBn%2FDwZ3cCQgQnudEP9i5EsEYFA1CqKlUIuxTD3k0Bs5HBo7aOCtZ55gtrQbWresIgQiQQ1wKukENqbrwdeKMZbS%2FtiOA3%2BhDBCrGyrM0anXJ19J0%3D"}],"group":"cf-nel","max_age":604800}
nel: {"report_to":"cf-nel","max_age":604800}
strict-transport-security: max-age=15552000; includeSubDomains; preload
x-content-type-options: nosniff
server: cloudflare
cf-ray: 660949485dad0ec8-BOM
alt-svc: h3-27=":443"; ma=86400, h3-28=":443"; ma=86400, h3-29=":443"; ma=86400, h3=":443"; ma=86400

With trailing slash - origin:https://redastrologer.com/ - expire and cache-control headers are set

curl -kI -H "origin:https://redastrologer.com/" -H "cache-control:no-cache" https://redastrologer.com/wp-content/plugins/elementor/assets/lib/font-awesome/webfonts/fa-solid-900.woff2
HTTP/2 200 
date: Thu, 17 Jun 2021 03:45:51 GMT
content-type: font/woff2
content-length: 80300
last-modified: Sat, 12 Jun 2021 19:13:06 GMT
etag: "60c50742-139ac"
expires: Fri, 17 Jun 2022 03:45:51 GMT
cache-control: max-age=31536000
pragma: public
cache-control: public
referrer-policy: no-referrer-when-downgrade
cf-cache-status: MISS
accept-ranges: bytes
cf-request-id: 0ab9ac525200002e28cc818000000001
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
report-to: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v2?s=yoDMGSg3w1yWJxciWJzOjGiHmtLTLqJVED2yBKGn7hIw2YukaFMd7WfqjLqfkfHiPHgkCxuLraMZ%2Fo6T9I4P5tXBJAFQXm941pxN6qCBdtvm%2Bt5a9Nfx3JBIR2Z9UKc%3D"}],"group":"cf-nel","max_age":604800}
nel: {"report_to":"cf-nel","max_age":604800}
strict-transport-security: max-age=15552000; includeSubDomains; preload
x-content-type-options: nosniff
server: cloudflare
cf-ray: 66094996edb62e28-BOM
alt-svc: h3-27=":443"; ma=86400, h3-28=":443"; ma=86400, h3-29=":443"; ma=86400, h3=":443"; ma=86400

Any ideas on might be going wrong here? Thanks!

I also verified the headers are set in both the cases on the origin server

@MoreHelp ^

Origin Request headers should not have trailing slashes. Are you seeing a browser generate these requests, or is it only from cURL? Cloudflares cache by default includes the Origin request header in the cache key, so each different Origin header results in a different asset being cached.

If you run the same two cURL commands directly against your origin what output do you get?

curl -k --dump-header - -o /dev/null -H "origin: https://redastrologer.com/" https://redastrologer.com/wp-content/plugins/elementor/assets/lib/font-awesome/webfonts/fa-solid-900.woff2 --connect-to ::ORIGIN-IP-HERE

curl -k --dump-header - -o /dev/null -H "origin: https://redastrologer.com"  https://redastrologer.com/wp-content/plugins/elementor/assets/lib/font-awesome/webfonts/fa-solid-900.woff2 --connect-to ::ORIGIN-IP-HERE
1 Like

Hi Michael, thanks for looking into this.

You are right the requests from the browser do not have trailing slash in origin header, but why are the cache-control headers not set for requests (set in the origin server) without trailing slash?

Below is the the response for both the commands. I do see cache-control set on the origin server for both the requests.

❯ curl -k --dump-header - -o /dev/null -H "origin: https://redastrologer.com/" https://redastrologer.com/wp-content/plugins/elementor/assets/lib/font-awesome/webfonts/fa-solid-900.woff2 --connect-to ::3.108.151.192
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0HTTP/1.1 200 OK
Server: nginx
Date: Mon, 21 Jun 2021 16:47:29 GMT
Content-Type: font/woff2
Content-Length: 80300
Last-Modified: Sat, 12 Jun 2021 19:13:06 GMT
Connection: keep-alive
ETag: "60c50742-139ac"
Expires: Tue, 21 Jun 2022 16:47:29 GMT
Cache-Control: max-age=31536000
Pragma: public
Cache-Control: public
Referrer-Policy: no-referrer-when-downgrade
Accept-Ranges: bytes

100 80300  100 80300    0     0  40250      0  0:00:01  0:00:01 --:--:-- 40230

❯ curl -k --dump-header - -o /dev/null -H "origin: https://redastrologer.com" https://redastrologer.com/wp-content/plugins/elementor/assets/lib/font-awesome/webfonts/fa-solid-900.woff2 --connect-to ::3.108.151.192
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:--  0:00:01 --:--:--     0HTTP/1.1 200 OK
Server: nginx
Date: Mon, 21 Jun 2021 16:47:47 GMT
Content-Type: font/woff2
Content-Length: 80300
Last-Modified: Sat, 12 Jun 2021 19:13:06 GMT
Connection: keep-alive
ETag: "60c50742-139ac"
Expires: Tue, 21 Jun 2022 16:47:47 GMT
Cache-Control: max-age=31536000
Pragma: public
Cache-Control: public
Referrer-Policy: no-referrer-when-downgrade
Accept-Ranges: bytes

100 80300  100 80300    0     0  37090      0  0:00:02  0:00:02 --:--:-- 37090

I suspect you changed the Cache-Control headers after you made a request for the file. If I append a query parameter to the URL I see the correct Cache-Control response headers. To purge a file that has an Origin request header you either have to Purge Everything, or use single file purge with the API. (The example on the API includes an Origin header.

https://api.cloudflare.com/#zone-purge-files-by-url

Just as an aside, I think your Pragma header does nothing on browsers released this century, similarly with Expires. And you have two different Cache-Control headers, which while valid, makes debugging difficult.

2 Likes

Thanks for the tip! Indeed adding query parameters does show correct response headers. I did try purging the font URLs (using the admin UI), but seems like it has no effect. I tried with other font files as well.

Checked again with couple of fonts, after doing the purge response headers have CF-Cache MISS without origin header, but with origin header still shows as HIT and without the Cache-Control headers.

If you have an Origin request header then the UI does not work for Purge. You must use the API. The example at the link I posted above is exactly what you need:

curl -X POST "https://api.cloudflare.com/client/v4/zones/023e105f4ecef8ad9ca31a8372d0c353/purge_cache" \
     -H "X-Auth-Email: [email protected]" \
     -H "X-Auth-Key: c2547eb745079dac9320b638f5e225cf483cc5cfdda41" \
     -H "Content-Type: application/json" \
     --data '{"files":[{"url":"https://redastrologer.com/wp-content/plugins/elementor/assets/lib/font-awesome/webfonts/fa-solid-900.woff2","headers":{"Origin":"https://redastrologer.com"}}]}'

Thanks, that worked! I missed the detail about Origin header requests not being purged from the UI. A note in the UI would be nice :slight_smile:

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