in pkg/server/responseCache.go [73:123]
func (rcm *ResponseCacheManager) handle(w http.ResponseWriter, request *http.Request, handler func(request *http.Request) (*bytebufferpool.ByteBuffer, bool, error)) {
w.Header().Set("Vary", "Accept-Encoding")
cacheKey := generateCacheKey(request)
value := rcm.cache.Get(nil, cacheKey)
var result []byte
if value != nil && request.Header.Get("Cache-Control") != "no-cache" {
var err error
result, err = decompressData(value)
if err != nil {
slog.Error("cannot decompress cached result", "error", err)
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
prevEtag := request.Header.Get("If-None-Match")
eTag := computeEtag(result)
if prevEtag == eTag {
w.Header().Set("ETag", eTag)
w.WriteHeader(http.StatusNotModified)
return
}
} else {
buffer, releaseBuffer, err := handler(request)
if err != nil {
rcm.handleError(err, w)
return
}
result, err = rcm.compressData(buffer.B)
if err != nil {
slog.Error("cannot compress result", "error", err)
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
rcm.cache.Set(cacheKey, result)
result = buffer.B
if releaseBuffer {
bytebufferpool.Put(buffer)
}
}
w.Header().Set("ETag", computeEtag(result))
w.Header().Set("Content-Length", strconv.Itoa(len(result)))
w.Header().Set("Content-Type", "text/plain")
w.WriteHeader(http.StatusOK)
_, err := w.Write(result)
if err != nil {
slog.Error("cannot write cached result", "error", err)
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
}