Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nuster seems to ignore cache-control headers from BE. Like "no-cache" #128

Open
jorisroling opened this issue Feb 15, 2023 · 5 comments
Open

Comments

@jorisroling
Copy link

Nuster seems to ignore cache-control headers from BE.
Like "no-cache"
Seems ridiculous, but this is what I see.

Any truth in it?

@jiangwenyuan
Copy link
Owner

That's true. The original purpose of this is to cache something cannot be cached or hard to be cached.

Image you have a simple query server which use POST to do the search, and every query is against DB. The system is very old and very unlikely to be upgraded to use something like Redis, while every search query cause heavy load in DB server.

So we can introduce nuster to cache this kind of query.

@jorisroling
Copy link
Author

Yes, very true, it might have a purpose as such.

But it currently does cache those responses that have an explicit cache-control header (like 'private, no-cache, must-revalidate'), and those should actually not be cache (as instructed). HAproxy does honour these instructions, and unfortunately Nuster does not, while Nuster has a proper PURGE option. I whish Nuster would honour the cache-conrol headers better.

The page https://cache-tests.fyi shows Nuster as (at least) respond to the 'no-store' directive, but I don't see this in my setup. Maybe the rule I use is wrong?

nuster rule get key method.scheme.host.uri ttl 1h code 200 if is_get !is_monitor

@jiangwenyuan
Copy link
Owner

It's indeed something great to have.
As a workaround, you can use

acl not_cache1 res.hdr(cache-control) -i "private"

@jorisroling
Copy link
Author

jorisroling commented Feb 16, 2023

I tried the following:

acl is_private res.hdr(cache-control) -i "private"
nuster rule get key method.scheme.host.uri ttl 1h code 200 if is_get !is_monitor !is_private

The second request now shows a HIT (where I expected a MISS).

Like this (second hit):

*   Trying 127.0.0.1:80...
* Connected to localhost (127.0.0.1) port 80 (#0)
> GET /graphql?extensions=%7b%22persistedQuery%22%3a%7b%22version%22%3a1%2c%22sha256Hash%22%3a%22ecf4edb46db40b5132295c0291d62fb65d6759a9eedfa4d5d612dd5ec54a6b38%22%7d%7d HTTP/1.1
> Host: localhost
> User-Agent: curl/7.86.0
> Accept: */*
> content-type: application/json
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< x-powered-by: yonderbox-graphql v1.5.0
< access-control-allow-origin: *
< access-control-expose-headers: x-powered-by
< cache-control: private
< content-type: application/json; charset=utf-8
< content-length: 100
< etag: W/"64-pCNUOD6DZiPor9gRPcTPDcQA2zU"
< date: Thu, 16 Feb 2023 10:03:29 GMT
< keep-alive: timeout=5
< x-proxy-host: localhost
< x-proxy-host: localhost
< x-cache-status: HIT

@jiangwenyuan
Copy link
Owner

Yes, it won't work if you just use the acl as is.

So

acl is_private res.hdr(cache-control) -i "private"
nuster rule get key method.scheme.host.uri ttl 1h code 200 if is_get !is_monitor !is_private

When in request stage, is_private is false, hence is_get !is_monitor !is_private is true, so it will be cache.

Please refer to https://github.com/jiangwenyuan/nuster#ifunless-condition for the detail request/response stage evaluation.

You should use something like this

acl hasCacheControl res.hdr(cache-control) -m found
acl is_private res.hdr(cache-control) -i "private"
nuster rule all if hasCacheControl !is_private

So in request stage:
hasCacheControl: false
!is_private: true

in response stage:
hasCacheControl: true
!is_private: false

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants