func()

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
	}
}