Hi

I was reading this thread 

https://stackoverflow.com/questions/17948827/reusing-http-connections-in-golang

and found this comment

one interesting note is that the read step appears to be necessary and 
> sufficient. 
> The read-step alone will return the connection to the pool, but the close 
> alone will not; the connection would end up in TCP_WAIT. 
> Also ran into trouble because I was using a json.NewDecoder() to read the 
> response.Body, which did not fully read it. 
> Make sure to include the io.Copy(ioutil.Discard, res.Body) if you're not 
> sure
>

Do we always need to do `io.Copy(ioutil.Discard, res.Body)` before closing 
the body?

I'm using go 1.8.3 and here is what i found so far:

>From the source code https://golang.org/src/net/http/response.go#L189

Body is assigend by `readTransfer` and is of type `http.body` 

https://golang.org/src/net/http/transfer.go#L724

http.body,  has comments

// body turns a Reader into a ReadCloser.
// Close ensures that the body has been fully read
// and then reads the trailer if necessary.
type body struct {
...
}

and the close method

func (b *body) Close() error {
    b.mu.Lock()
    defer b.mu.Unlock()
    if b.closed {
        return nil
    }
    var err error
    switch {
    case b.sawEOF:
        // Already saw EOF, so no need going to look for it.
    case b.hdr == nil && b.closing:
        // no trailer and closing the connection next.
        // no point in reading to EOF.
    case b.doEarlyClose:
        // Read up to maxPostHandlerReadBytes bytes of the body, looking for
        // for EOF (and trailers), so we can re-use this connection.
        if lr, ok := b.src.(*io.LimitedReader); ok && lr.N > 
maxPostHandlerReadBytes {
            // There was a declared Content-Length, and we have more bytes 
remaining
            // than our maxPostHandlerReadBytes tolerance. So, give up.
            b.earlyClose = true
        } else {
            var n int64
            // Consume the body, or, which will also lead to us reading
            // the trailer headers after the body, if present.
            n, err = io.CopyN(ioutil.Discard, bodyLocked{b}, 
maxPostHandlerReadBytes)
            if err == io.EOF {
                err = nil
            }
            if n == maxPostHandlerReadBytes {
                b.earlyClose = true
            }
        }
    default:
        // Fully consume the body, which will also lead to us reading
        // the trailer headers after the body, if present.
        _, err = io.Copy(ioutil.Discard, bodyLocked{b})
    }
    b.closed = true
    return err
}

It seems to me that it's already doing that. And if I understand correctly, 
the `b.doEarlyClose` only apply when reading request and not applicable to 
http response.

So in conclusion my question is do we need to always read the resp.Body 
before closing it?

Thank you.



-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to