pquerna / cachecontrol

Golang HTTP Cache-Control Parser and Interpretation
Apache License 2.0
133 stars 17 forks source link

Surrogate-Control headers #11

Open ryanschneider opened 6 years ago

ryanschneider commented 6 years ago

It looks like this package does not support the less common Surrogate-Control header sometimes used by CDNs.

The logic to support Surrogate-Control would basically the same as Cache-Control, but the header is specifically meant for reverse proxy <-> origin server controls (Cache-Control is meant for end browsers).

See: https://www.w3.org/TR/edge-arch/

Often used by CDNs: https://docs.fastly.com/guides/tutorials/cache-control-tutorial https://www.nuevocloud.com/documentation/getting-started/cache-headers-cache-control-surrogate-control-and-expires

See https://github.com/nicolasazrak/caddy-cache/issues/24 for discussion.

pquerna commented 6 years ago

I think basic support could be done today using the low level api, eg by populating Object.RespDirectives with the parsed results of ParseResponseCacheControl(respHeaders.Get("Surrogate-Control")): https://godoc.org/github.com/pquerna/cachecontrol/cacheobject#Object

Having said that, adding a field to the options object would also let this work using the high level API and remain compatible with existing API users too: https://godoc.org/github.com/pquerna/cachecontrol#Options

ryanschneider commented 6 years ago

Ya, I was looking in those areas, my naive first pass was to update UsingRequestReponse like so:

        var reqDir *RequestCacheDirectives = nil
    ctrlHeader := "Cache-Control"
    if respHeaders.Get("Surrogate-Control") != "" {
        ctrlHeader = "Surrogate-Control"
    }

    respDir, err := ParseResponseCacheControl(respHeaders.Get(ctrlHeader))
    if err != nil {
        return nil, time.Time{}, err
    }

Which is to say, use the Surrogate-Control header if its there, otherwise fallback to Cache-Control, but I agree that making it controllable via Options would be good, so I'll look into how that could be done.