Let\'s say I have a middleware in Go where I want to override any existing Server
headers with my own value.
// Server attaches a Server header
It's not possible to change headers (add/remove/modify) after you use WriteHeader(Status).
For this to work, change to:
// Server attaches a Server header to the response.
func Server(h http.Handler, serverName string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Server", serverName)
h.ServeHTTP(w, r)
})
}
You can define a custom type which wraps a ResponseWriter and inserts the Server header just before all headers are written, at the cost of an additional layer of indirection. Here is an example:
type serverWriter struct {
w http.ResponseWriter
name string
wroteHeader bool
}
func (s serverWriter) WriteHeader(code int) {
if s.wroteHeader == false {
s.w.Header().Set("Server", s.name)
s.wroteHeader = true
}
s.w.WriteHeader(code)
}
func (s serverWriter) Write(b []byte) (int, error) {
return s.w.Write(b)
}
func (s serverWriter) Header() http.Header {
return s.w.Header()
}
// Server attaches a Server header to the response.
func Server(h http.Handler, serverName string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
sw := serverWriter{
w: w,
name: serverName,
wroteHeader: false,
}
h.ServeHTTP(sw, r)
})
}
I wrote more about this here. https://kev.inburke.com/kevin/how-to-write-go-middleware/