我怎么知道net / http的ResponseWriter.Write()是否被调用? [英] How can I tell if net/http's ResponseWriter.Write() has been called?

查看:173
本文介绍了我怎么知道net / http的ResponseWriter.Write()是否被调用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



或者,这是完全错误的方法来解决这个问题? b $ b

解决方案

http.ResponseWriter 是一个界面。因此,只需编写一个新的实例:

  type MyResponseWriter struct {
http.ResponseWriter
WroteHeader bool

$ b func(w * MyResponseWriter)Write(b [] byte)(int,error){
w.WroteHeader = true
返回w.ResponseWriter。 Write(b)
}

func(w * MyResponseWriter)WriteHeader(code int){
w.WroteHeader = true
w.ResponseWriter.WriteHeader(code)
}

在您的处理程序中:

  // ... 
if w,ok:= w。(* MyResponseWriter);好的&& w.WroteHeader {
log.Println(已经写了,跳过)
return
}






编辑:要考虑的另一件事。大多数情况下,如果你有一个链的处理程序,这意味着一个处理程序在处理程序中被调用。因此,如果你有类似于

 类型Handler1 struct {http.Handler} 
类型Handler2 struct {http.Handler}
type Handler3 struct {http.Handler}
var MyHandler http.Handler = Handler1 {Handler2 {Handler3 {h}}}

,只要每个人调用内部处理程序作为他们对 w 和<$ c $做的最后一件事情你应该没问题,因为然后 w r 甚至不会到达内部处理者。例如

  func(h Handler2)ServeHTTP(w http.ResponseWriter,r * http.Request){
if somethingBadHappened (){
w.WriteHeader(http.StatusInternalServerError)
return
}
h.ServeHTTP(w,r)//如果somethingBadHappened()没有被调用。
}


Suppose I have a chain of net/http Handlers, and an early one responds with an HTTP error (http.StatusInternalServerError, for instance). How can I detect this in the following handlers, and avoid sending additional data to the client?

Or is this entirely the wrong approach to the problem?

解决方案

http.ResponseWriter is an interface. So just compose a new instance of it:

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

And in your handlers:

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


EDIT: Another thing to consider. Most of the time if you have a "chain" of handlers that means that a handler is called inside a handler. So if you have something like

type Handler1 struct { http.Handler }
type Handler2 struct { http.Handler }
type Handler3 struct { http.Handler }
var MyHandler http.Handler = Handler1{Handler2{Handler3{h}}}

as long as each of those call the inner handler as the last thing they do with w and r, you should be fine because then w and r won't even reach the inner handler. 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().
}

这篇关于我怎么知道net / http的ResponseWriter.Write()是否被调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆