- 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
60 lines
1.1 KiB
Go
60 lines
1.1 KiB
Go
package kite
|
|
|
|
import (
|
|
"bufio"
|
|
"fmt"
|
|
"net"
|
|
"net/http"
|
|
)
|
|
|
|
type responseWriter struct {
|
|
http.ResponseWriter
|
|
statusCode int
|
|
written bool
|
|
}
|
|
|
|
func newResponseWriter(w http.ResponseWriter) *responseWriter {
|
|
return &responseWriter{
|
|
ResponseWriter: w,
|
|
statusCode: http.StatusOK,
|
|
}
|
|
}
|
|
|
|
func (rw *responseWriter) WriteHeader(statusCode int) {
|
|
if rw.written {
|
|
return
|
|
}
|
|
|
|
rw.statusCode = statusCode
|
|
rw.written = true
|
|
rw.ResponseWriter.WriteHeader(statusCode)
|
|
}
|
|
|
|
func (rw *responseWriter) Write(b []byte) (int, error) {
|
|
if !rw.written {
|
|
rw.WriteHeader(http.StatusOK)
|
|
}
|
|
return rw.ResponseWriter.Write(b)
|
|
}
|
|
|
|
func (rw *responseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
|
|
h, ok := rw.ResponseWriter.(http.Hijacker)
|
|
if !ok {
|
|
return nil, nil, fmt.Errorf("underlying ResponseWriter does not implement http.Hijacker")
|
|
}
|
|
return h.Hijack()
|
|
}
|
|
|
|
func (rw *responseWriter) Flush() {
|
|
if f, ok := rw.ResponseWriter.(http.Flusher); ok {
|
|
f.Flush()
|
|
}
|
|
}
|
|
|
|
func (rw *responseWriter) Push(target string, opts *http.PushOptions) error {
|
|
if p, ok := rw.ResponseWriter.(http.Pusher); ok {
|
|
return p.Push(target, opts)
|
|
}
|
|
return http.ErrNotSupported
|
|
}
|