Files
reproxy/vendor/github.com/go-pkgz/rest/cache_control.go
2021-04-12 11:38:21 -05:00

63 lines
1.8 KiB
Go

package rest
import (
"crypto/sha1" //nolint not used for cryptography
"fmt"
"net/http"
"strings"
"time"
)
// CacheControl is a middleware setting cache expiration. Using url+version for etag
func CacheControl(expiration time.Duration, version string) func(http.Handler) http.Handler {
etag := func(r *http.Request, version string) string {
s := fmt.Sprintf("%s:%s", version, r.URL.String())
return fmt.Sprintf("%x", sha1.Sum([]byte(s))) //nolint
}
return func(h http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
e := `"` + etag(r, version) + `"`
w.Header().Set("Etag", e)
w.Header().Set("Cache-Control", fmt.Sprintf("max-age=%d, no-cache", int(expiration.Seconds())))
if match := r.Header.Get("If-None-Match"); match != "" {
if strings.Contains(match, e) {
w.WriteHeader(http.StatusNotModified)
return
}
}
h.ServeHTTP(w, r)
}
return http.HandlerFunc(fn)
}
}
// CacheControlDynamic is a middleware setting cache expiration. Using url+ func(r) for etag
func CacheControlDynamic(expiration time.Duration, versionFn func(r *http.Request) string) func(http.Handler) http.Handler {
etag := func(r *http.Request, version string) string {
s := fmt.Sprintf("%s:%s", version, r.URL.String())
return fmt.Sprintf("%x", sha1.Sum([]byte(s))) //nolint
}
return func(h http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
e := `"` + etag(r, versionFn(r)) + `"`
w.Header().Set("Etag", e)
w.Header().Set("Cache-Control", fmt.Sprintf("max-age=%d, no-cache", int(expiration.Seconds())))
if match := r.Header.Get("If-None-Match"); match != "" {
if strings.Contains(match, e) {
w.WriteHeader(http.StatusNotModified)
return
}
}
h.ServeHTTP(w, r)
}
return http.HandlerFunc(fn)
}
}