feat: middleware reach, response writer interfaces, and CORS fixes

- Run global middleware for all requests, including OPTIONS preflights, NotFound, and MethodNotAllowed — previously bypassed by httprouter's internal handling
- Implement Hijacker, Flusher, and Pusher on the response writer for WebSocket, SSE, and HTTP/2 push support
- Fix CORS: echo a single matching origin, handle AllowCredentials with wildcard, append Vary: Origin
- Logger logs from a defer to capture correct status on panicked requests
- Static and StaticFS accept route middleware; add Context.AddHeader; warn on NotFound handler override
This commit is contained in:
2026-05-17 17:51:56 +02:00
parent 36c6d76e53
commit ae5d1f610a
7 changed files with 237 additions and 69 deletions

View File

@@ -8,19 +8,25 @@ type Group struct {
mws []Middleware
}
func (g *Group) Static(prefix, root string) {
g.StaticFS(prefix, http.Dir(root))
func (g *Group) Static(prefix, root string, mws ...Middleware) {
g.StaticFS(prefix, http.Dir(root), mws...)
}
func (g *Group) StaticFS(prefix string, fs http.FileSystem) {
func (g *Group) StaticFS(prefix string, fs http.FileSystem, mws ...Middleware) {
if prefix == "" || prefix[len(prefix)-1] != '/' {
prefix += "/"
}
fullPrefix := g.prefix + prefix
handler := http.StripPrefix(fullPrefix, http.FileServer(fs))
g.k.r.Handler(http.MethodGet, fullPrefix+"*filepath", handler)
g.k.r.Handler(http.MethodHead, fullPrefix+"*filepath", handler)
h := func(ctx *Context) error {
handler.ServeHTTP(ctx.w, ctx.r)
return nil
}
g.k.handle(http.MethodGet, fullPrefix+"*filepath", h, mws...)
g.k.handle(http.MethodHead, fullPrefix+"*filepath", h, mws...)
}
func (g *Group) Group(prefix string, mws ...Middleware) *Group {
@@ -68,5 +74,9 @@ func (g *Group) TRACE(path string, h Handler, mws ...Middleware) {
}
func (g *Group) handle(method, path string, h Handler, mws ...Middleware) {
g.k.handle(method, g.prefix+path, h, append(g.mws, mws...)...)
combined := make([]Middleware, 0, len(g.mws)+len(mws))
combined = append(combined, g.mws...)
combined = append(combined, mws...)
g.k.handle(method, g.prefix+path, h, combined...)
}