darkweak / souin

An HTTP cache system, RFC compliant, compatible with @tyktechnologies, @traefik, @caddyserver, @go-chi, @bnkamalesh, @beego, @devfeel, @labstack, @gofiber, @go-goyave, @go-kratos, @gin-gonic, @roadrunner-server, @zalando, @zeromicro, @nginx and @apache
https://docs.souin.io
MIT License
677 stars 51 forks source link

Cache-Control: stale-while-revalidate #486

Open the-leonat opened 5 months ago

the-leonat commented 5 months ago

Does souin implement asynchronous background fetching similar to varnish grace setting? I could not find anything about it in the docs and it seems to ignore my cache-control response header of my upstream webserver. public, max-age=120, stale-while-revalidate=3600. after the content turns stale souin replies once with: Cache-Status: Souin; fwd=uri-miss; key={{key}}-/; detail=UNCACHEABLE-STATUS-CODE

server responds with code 304.

func isCacheableCode(code int) bool {
    switch code {
    case 200, 203, 204, 206, 300, 301, 404, 405, 410, 414, 501:
        return true
    }

    return false
}

but 304 is not a cacheable status code by implementation. is this a bug?

darkweak commented 4 months ago

Hello @the-leonat sorry for the delay, I was on other subjects.

In theory the stale while revalidate is working but seeing your issue, there is probably a bug.
After reading your issue, it seems the revalidation doesn't work, because it tries to store the given response that has a 304 status code. the revalidation block is the following:

        err := next(customWriter, rq)
        s.SurrogateKeyStorer.Invalidate(rq.Method, customWriter.Header())

        statusCode := customWriter.GetStatusCode()
        if err == nil {
            if validator.IfUnmodifiedSincePresent && statusCode != http.StatusNotModified {
                customWriter.Buf.Reset()
                customWriter.Rw.WriteHeader(http.StatusPreconditionFailed)

                return nil, errors.New("")
            }

            if statusCode != http.StatusNotModified {
                err = s.Store(customWriter, rq, requestCc, cachedKey)
            }
        }

If it returns a detail=UNCACHEABLE-STATUS-CODE that means you're going through the Store function and your http status code is not a not modified.