feat(middlewares): etag path-based middleware

Signed-off-by: James Elliott <james-d-elliott@users.noreply.github.com>
feat-path-etag
James Elliott 2023-05-28 23:02:51 +10:00
parent 5e9d8d6c71
commit a33560a4d1
No known key found for this signature in database
GPG Key ID: 0F1C4A096E857E49
1 changed files with 66 additions and 0 deletions

View File

@ -0,0 +1,66 @@
package middlewares
import (
"bytes"
"crypto/sha256"
"net/url"
"sync"
"github.com/valyala/fasthttp"
)
func NewPathETag() *PathETag {
return &PathETag{
lock: &sync.Mutex{},
tags: map[string][]byte{},
}
}
type PathETag struct {
lock *sync.Mutex
tags map[string][]byte
}
func (m *PathETag) Middleware(next RequestHandler) RequestHandler {
hash := sha256.New()
return func(ctx *AutheliaCtx) {
var (
found bool
furl *url.URL
err error
)
if furl, err = ctx.GetXForwardedURL(); err == nil {
m.lock.Lock()
defer m.lock.Unlock()
if etag, ok := m.tags[furl.String()]; ok {
found = true
ctx.Response.Header.SetBytesV(fasthttp.HeaderETag, etag)
ctx.Response.Header.SetBytesK(headerCacheControl, "public, max-age=0, must-revalidate")
if bytes.Equal(etag, ctx.Request.Header.Peek(fasthttp.HeaderIfNoneMatch)) {
ctx.SetStatusCode(fasthttp.StatusNotModified)
return
}
}
}
next(ctx)
if !found && furl != nil {
if _, err = hash.Write(ctx.Response.Body()); err != nil {
return
}
m.tags[furl.String()] = hash.Sum(nil)
hash.Reset()
}
}
}