Charles L.
Charles L.

Reputation: 6295

How to break a chunked in go using net/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?

Upvotes: 2

Views: 1135

Answers (2)

jch
jch

Reputation: 5651

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.

Upvotes: 1

Mr_Pink
Mr_Pink

Reputation: 109378

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
}

Upvotes: 3

Related Questions