feat(middlewares): etag path-based middleware
Signed-off-by: James Elliott <james-d-elliott@users.noreply.github.com>feat-path-etag
parent
5e9d8d6c71
commit
a33560a4d1
|
@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue