小编典典

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

go

假设我有一连串的net /
http处理程序,而早期的处理程序以HTTP错误(http.StatusInternalServerError例如)响应。如何在以下处理程序中检测到此情况,并避免将其他数据发送到客户端?

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


阅读 254

收藏
2020-07-02

共1个答案

小编典典

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}}}

只要每个那些调用内部处理程序 ,因为他们与做的最后一件事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().
}
2020-07-02