假設我有一個net/http處理程序鏈,並且早期的一個響應HTTP錯誤(例如http.StatusInternalServerError
)。我如何在以下處理程序中檢測到這一點,並避免向客戶端發送其他數據?如何判斷net/http的ResponseWriter.Write()是否已被調用?
或者這是完全錯誤的方法來解決這個問題?
假設我有一個net/http處理程序鏈,並且早期的一個響應HTTP錯誤(例如http.StatusInternalServerError
)。我如何在以下處理程序中檢測到這一點,並避免向客戶端發送其他數據?如何判斷net/http的ResponseWriter.Write()是否已被調用?
或者這是完全錯誤的方法來解決這個問題?
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
甚至不會達到內部處理程序。例如。
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().
}
首先:可能存在更輕的解決方案。
但是,如果找不到,請考慮使用x/net/context
來實現超時,截止日期,當然還有提前終止中間件鏈。
不調用下一個處理程序並提前返回是正確的方法。 – elithrar