假设我有一个net / http处理程序链,而早期的处理程序响应HTTP错误(例如http.StatusInternalServerError
)。如何在以下处理程序中检测到这一点,并避免向客户端发送其他数据?
或者这完全是解决这个问题的错误方法吗?
答案 0 :(得分:6)
http.ResponseWriter
是一个界面。所以只需撰写一个新实例:
type MyResponseWriter struct {
http.ResponseWriter
WroteHeader bool
}
func (w *MyResponseWriter) Write(b []byte) (int, error) {
w.WroteHeader = true
return w.ResponseWriter.Write(b)
}
func (w *MyResponseWriter) WriteHeader(code int) {
w.WroteHeader = true
w.ResponseWriter.WriteHeader(code)
}
在你的处理程序中:
//...
if w, ok := w.(*MyResponseWriter); ok && w.WroteHeader {
log.Println("Already wrote, skipping")
return
}
编辑:需要考虑的另一件事。大多数时候,如果你有一个"链"处理程序,这意味着在处理程序内调用处理程序。所以如果你有像
这样的东西type Handler1 struct { http.Handler }
type Handler2 struct { http.Handler }
type Handler3 struct { http.Handler }
var MyHandler http.Handler = Handler1{Handler2{Handler3{h}}}
只要每个人调用内部处理程序作为他们使用w
和r
做的最后一件事,你应该没事,因为w
并且r
甚至没有达到内部处理程序。 E.g。
func (h Handler2) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if somethingBadHappened() {
w.WriteHeader(http.StatusInternalServerError)
return
}
h.ServeHTTP(w, r) // Not called if somethingBadHappened().
}
答案 1 :(得分:0)
首先:可能存在重量较轻的解决方案。
但是,如果找不到,请考虑使用x/net/context
来实现超时,截止日期,当然还要提前终止中间件链。