package server import "net/http" // Middleware wraps an http.Handler to add behavior. // This is the server-side counterpart of the client middleware type // func(http.RoundTripper) http.RoundTripper. type Middleware func(http.Handler) http.Handler // Chain composes middlewares so that Chain(A, B, C)(handler) == A(B(C(handler))). // Middlewares are applied from right to left: C wraps handler first, then B wraps // the result, then A wraps last. This means A is the outermost layer and sees // every request first. func Chain(mws ...Middleware) Middleware { return func(h http.Handler) http.Handler { for i := len(mws) - 1; i >= 0; i-- { h = mws[i](h) } return h } } // statusWriter wraps http.ResponseWriter to capture the response status code. // It implements Unwrap() so that http.ResponseController can access the // underlying ResponseWriter's optional interfaces (Flusher, Hijacker, etc.). type statusWriter struct { http.ResponseWriter status int written bool } // WriteHeader captures the status code and delegates to the underlying writer. func (w *statusWriter) WriteHeader(code int) { if !w.written { w.status = code w.written = true } w.ResponseWriter.WriteHeader(code) } // Write delegates to the underlying writer, defaulting status to 200 if // WriteHeader was not called explicitly. func (w *statusWriter) Write(b []byte) (int, error) { if !w.written { w.status = http.StatusOK w.written = true } return w.ResponseWriter.Write(b) } // Unwrap returns the underlying ResponseWriter. This is required for // http.ResponseController to detect optional interfaces like http.Flusher // and http.Hijacker on the original writer. func (w *statusWriter) Unwrap() http.ResponseWriter { return w.ResponseWriter }