Skip to content

net/http: redirection response has closed body #10069

Closed
@JamesDunne

Description

@JamesDunne
  1. What version of Go are you using (go version)?
    go version go1.4.2 darwin/amd64
  2. What operating system and processor architecture are you using?
    Not really relevant to this issue...
    MacBook Pro (15-inch, Mid 2012)
    2.6 GHz Intel Core i7
    16 GB 1600 MHz DDR3
  3. What did you do?
    Implemented a custom redirection policy handler via http.Client's CheckRedirect to stop redirection.
    After a Do() call on a request, the returned response's Body is not nil and reading from it returns an error http: read on closed response body. See example code below.
  4. What did you expect to see?
    Expected either an unclosed, unread-from non-nil Body, or a nil Body.
  5. What did you see instead?
    Saw a closed, already-read-from Body that was not nil.

This unexpected condition required me to hack around the case by explicitly setting resp.Body to nil when detecting my custom redirect policy abort error from the returned url.Error.

Also, I have no access to the intermediate redirection responses. I would want an interception function to be able to inspect the redirection response to see if I should redirect or not, but instead I get a request instance; what good is the request to determine if I should redirect? This design also prevents me from logging relevant redirection details to the end user, so as to properly trace the request-response path.

// Define our redirection policy:
const redirects_max_follow = 0 // for this test case
var redirectPolicyError = errors.New("redirect policy")
client := &http.Client{
    CheckRedirect: func(req *http.Request, via []*http.Request) error {
        if len(via) > redirects_max_follow {
            return redirectPolicyError
        }
        return nil
    },
}

// Make the request:
resp, err := client.Do(req)
if err != nil {
    if uerr, ok := err.(*url.Error); ok {
        if uerr.Err == redirectPolicyError {
            // Redirection responses get their bodies removed by `Do()` automatically.
            // Not sure if this is a bug or not.
            // Setting Body to nil prevents future "http: read on closed response body" error.
            resp.Body = nil
            goto ok
        }
    }
    Error("HTTP error: %s\n", err)
    return -2
ok:
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions