英文:
How to break a chunked in go using net/http?
问题
我有一个带有端点的HTTP服务器,该端点从数据库中返回大量数据流。响应是分块的(< Transfer-Encoding: chunked
)。如果遇到错误,比如数据库崩溃,我可以使用 panic,curl 会警告我有问题:
curl: (18) transfer closed with outstanding read data remaining
但我不想要 panic,我只想要一个简单的日志消息。如果我使用 recover()
,curl 中就不会显示错误,所以没有任何指示有东西出错。
有没有一种方法可以在不使用 panic 的情况下中断分块的 HTTP 响应?
英文:
I have an http server with an endpoint that returns lots of data streamed from a db. The response is chunked (< Transfer-Encoding: chunked
). And if I run into an error, like the DB crashing, I can use a panic & curl will warn me of an issue:
curl: (18) transfer closed with outstanding read data remaining
I don't want a panic though - I just want a simple log message. And if I recover()
I don't get the error in curl so there's no indication of something breaking.
Is there a way to break an chunked http response without a panic?
答案1
得分: 3
你在curl中看到的错误是因为当HTTP服务器看到panic时,立即关闭了连接。为了在没有panic的情况下强制关闭连接,你需要劫持它:
// 在http处理程序内部
// func(w http.ResponseWriter, r *http.Request) {
// 中止HTTP/1.1响应
if w, ok := w.(http.Hijacker); ok {
c, _, err := w.Hijack()
if err != nil {
log.Println("无法关闭连接:", err)
return
}
c.Close()
return
}
英文:
That error you see from curl is because the connection was immediately closed by the http server when it saw the panic. In order to force the connection closed without a panic
, you will have to hijack it:
// inside the http handler
// func(w http.ResponseWriter, r *http.Request) {
// to abort an HTTP/1.1 response
if w, ok := w.(http.Hijacker); ok {
c, _, err := w.Hijack()
if err != nil {
log.Println("cannot close connection:", err)
return
}
c.Close()
return
}
答案2
得分: 1
在Go 1.7中,劫持(如JimB的回答中提出的)可能是最好的解决方案。不幸的是,它只适用于HTTP/1.1 - 在HTTP/2中它不会有任何有用的效果。
Go 1.8引入了一个新的值ErrAbortHandler
,中断HTTP响应流的官方方法是panic(http.ErrAbortHandler)
,它适用于HTTP/1.1和HTTP/2。这在issue 17790中有描述。
英文:
In Go 1.7, hijacking (as proposed in JimB's answer) is probably the best solution. Unfortunately, it only works in HTTP/1.1 — it will not do anything useful in HTTP/2.
Go 1.8 introduces a new value ErrAbortHandler
, and the official way of interrupting an HTTP reply mid-stream is panic(http.ErrAbortHandler)
, which works for both HTTP/1.1 and HTTP/2. This is described in issue 17790.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论