@@ 0,0 1,48 @@
package feature
import (
"context"
"net/http"
"strings"
)
var featureCtxKey = &contextKey{"feature"}
type contextKey struct {
name string
}
// Creates an HTTP middleware to process Accept-Features headers.
func Middleware() func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
header := r.Header.Get("Accept-Features")
features := strings.Split(header, ",")
ctx := context.WithValue(r.Context(),
featureCtxKey, features)
r = r.WithContext(ctx)
next.ServeHTTP(w, r)
})
}
}
// Returns the list of enabled features on this context.
func ForContext(ctx context.Context) []string {
raw, ok := ctx.Value(featureCtxKey).([]string)
if !ok {
return []string{}
}
return raw
}
// Returns true if the requested feature is enabled via the Accept-Features
// HTTP header
func Enabled(ctx context.Context, name string) bool {
for _, feat := range ForContext(ctx) {
if feat == name {
return true
}
}
return false
}
@@ 39,6 39,7 @@ import (
"git.sr.ht/~sircmpwn/core-go/crypto"
"git.sr.ht/~sircmpwn/core-go/database"
"git.sr.ht/~sircmpwn/core-go/email"
+ "git.sr.ht/~sircmpwn/core-go/feature"
"git.sr.ht/~sircmpwn/core-go/redis"
)
@@ 254,7 255,15 @@ func (server *Server) WithDefaultMiddleware() *Server {
server.router.Use(cors.Handler(cors.Options{
AllowedOrigins: []string{"*"},
AllowedMethods: []string{"GET", "POST", "OPTIONS"},
- AllowedHeaders: []string{"User-Agent", "X-Requested-With", "If-Modified-Since", "Cache-Control", "Content-Type", "Range"},
+ AllowedHeaders: []string{
+ "User-Agent",
+ "X-Requested-With",
+ "If-Modified-Since",
+ "Cache-Control",
+ "Content-Type",
+ "Range",
+ "Accept-Features",
+ },
ExposedHeaders: []string{"Content-Length", "Content-Range"},
MaxAge: 1728000,
}))
@@ 264,6 273,7 @@ func (server *Server) WithDefaultMiddleware() *Server {
server.router.Use(redis.Middleware(rc))
server.router.Use(auth.Middleware(server.conf, apiconf))
server.router.Use(middleware.RealIP)
+ server.router.Use(feature.Middleware())
if debug {
server.router.Use(middleware.Logger)
}