为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
慕的地6264312 2021-11-01 10:34:18
假设我有一个 net/http 处理程序链,一个早期的处理程序以 HTTP 错误响应(http.StatusInternalServerError例如)。如何在以下处理程序中检测到这一点,并避免向客户端发送额外数据?或者这完全是解决问题的错误方法?
查看完整描述

2 回答

?
翻翻过去那场雪

TA贡献2065条经验 获得超14个赞

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

只要每个人都调用内部处理程序作为他们对wand做的最后一件事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().

}


查看完整回答
反对 回复 2021-11-01
?
跃然一笑

TA贡献1826条经验 获得超6个赞

第一:可能存在更轻量级的解决方案。

但是,如果您找不到,请考虑使用x/net/context允许您实现超时、截止日期,当然还有中间件链的提前终止。


查看完整回答
反对 回复 2021-11-01
  • 2 回答
  • 0 关注
  • 177 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信