在这种情况下,您有一个 Go 中间件 Server,您想用它来覆盖任何现有的 Server 标头自定义值。但是,如果请求链下游的任何处理程序调用 w.Header().Add("Server", "foo"),则会导致响应中出现多个 Server 标头。
预期的行为是让 Server中间件仅在写入所有其他标头后才附加其标头值。但是,ServeHTTP 的语义规定必须在调用完成之前写入标头。
一种解决方法是创建一个自定义 ResponseWriter 来拦截所有标头写入并插入服务器就在所有标头被刷新之前。下面是一个示例:
type serverWriter struct { w http.ResponseWriter name string wroteHeader bool } func (s serverWriter) WriteHeader(code int) { if !s.wroteHeader { 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() }
注意:此方法需要额外的间接层。
更新的服务器中间件可以利用此自定义 ResponseWriter:
// 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) }) }
此解决方案可确保在适当的时间添加 Server 标头,无论何时何地请求链中添加了标头。
有关更多见解,您可以参考 https://kev.inburke.com/kevin/how-to-write-go-middleware/。
以上是Go中间件如何控制HTTP头来防止服务器头重复?的详细内容。更多信息请关注PHP中文网其他相关文章!