如何判断是否已调用net/http的ResponseWriter.Write()?

Fli*_*mzy 3 http go

假设我有一个net/http处理程序链,而早期的处理程序会响应HTTP错误(http.StatusInternalServerError例如).如何在以下处理程序中检测到这一点,并避免向客户端发送其他数据?

或者这完全是解决问题的错误方法?

Ain*_*r-G 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)
}
Run Code Online (Sandbox Code Playgroud)

在您的处理程序中:

//...
if w, ok := w.(*MyResponseWriter); ok && w.WroteHeader {
    log.Println("Already wrote, skipping")
    return
}
Run Code Online (Sandbox Code Playgroud)

编辑:另一件需要考虑的事情.大多数情况下,如果你有一个"链"处理程序,这意味着在处理程序内部调用一个处理程序.所以,如果你有类似的东西

type Handler1 struct { http.Handler }
type Handler2 struct { http.Handler }
type Handler3 struct { http.Handler }
var MyHandler http.Handler = Handler1{Handler2{Handler3{h}}}
Run Code Online (Sandbox Code Playgroud)

只要每个那些调用内部处理程序,因为他们与做的最后一件事wr,你应该罚款,因为那时wr甚至不会到达内处理.例如

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().
}
Run Code Online (Sandbox Code Playgroud)

  • 不调用下一个处理程序并提前返回是正确的方法. (2认同)