Commit dfd7f181 authored by Brad Fitzpatrick's avatar Brad Fitzpatrick

net/http: revert back to (and test) Go 1 CheckRedirect behavior

If a Client's CheckRedirect function returns an error, we
again return both a non-nil *Response and a non-nil error.

Fixes #3795

R=golang-dev, n13m3y3r
CC=golang-dev
https://golang.org/cl/6429044
parent dd78f745
...@@ -33,10 +33,11 @@ type Client struct { ...@@ -33,10 +33,11 @@ type Client struct {
// CheckRedirect specifies the policy for handling redirects. // CheckRedirect specifies the policy for handling redirects.
// If CheckRedirect is not nil, the client calls it before // If CheckRedirect is not nil, the client calls it before
// following an HTTP redirect. The arguments req and via // following an HTTP redirect. The arguments req and via are
// are the upcoming request and the requests made already, // the upcoming request and the requests made already, oldest
// oldest first. If CheckRedirect returns an error, the client // first. If CheckRedirect returns an error, the Client's Get
// returns that error (wrapped in a url.Error) instead of // method returns both the previous Response and
// CheckRedirect's error (wrapped in a url.Error) instead of
// issuing the Request req. // issuing the Request req.
// //
// If CheckRedirect is nil, the Client uses its default policy, // If CheckRedirect is nil, the Client uses its default policy,
...@@ -221,6 +222,7 @@ func (c *Client) doFollowingRedirects(ireq *Request) (resp *Response, err error) ...@@ -221,6 +222,7 @@ func (c *Client) doFollowingRedirects(ireq *Request) (resp *Response, err error)
req := ireq req := ireq
urlStr := "" // next relative or absolute URL to fetch (after first request) urlStr := "" // next relative or absolute URL to fetch (after first request)
redirectFailed := false
for redirect := 0; ; redirect++ { for redirect := 0; ; redirect++ {
if redirect != 0 { if redirect != 0 {
req = new(Request) req = new(Request)
...@@ -239,6 +241,7 @@ func (c *Client) doFollowingRedirects(ireq *Request) (resp *Response, err error) ...@@ -239,6 +241,7 @@ func (c *Client) doFollowingRedirects(ireq *Request) (resp *Response, err error)
err = redirectChecker(req, via) err = redirectChecker(req, via)
if err != nil { if err != nil {
redirectFailed = true
break break
} }
} }
...@@ -268,16 +271,24 @@ func (c *Client) doFollowingRedirects(ireq *Request) (resp *Response, err error) ...@@ -268,16 +271,24 @@ func (c *Client) doFollowingRedirects(ireq *Request) (resp *Response, err error)
return return
} }
if resp != nil {
resp.Body.Close()
}
method := ireq.Method method := ireq.Method
return nil, &url.Error{ urlErr := &url.Error{
Op: method[0:1] + strings.ToLower(method[1:]), Op: method[0:1] + strings.ToLower(method[1:]),
URL: urlStr, URL: urlStr,
Err: err, Err: err,
} }
if redirectFailed {
// Special case for Go 1 compatibility: return both the response
// and an error if the CheckRedirect function failed.
// See http://golang.org/issue/3795
return resp, urlErr
}
if resp != nil {
resp.Body.Close()
}
return nil, urlErr
} }
func defaultCheckRedirect(req *Request, via []*Request) error { func defaultCheckRedirect(req *Request, via []*Request) error {
......
...@@ -234,6 +234,12 @@ func TestRedirects(t *testing.T) { ...@@ -234,6 +234,12 @@ func TestRedirects(t *testing.T) {
if urlError, ok := err.(*url.Error); !ok || urlError.Err != checkErr { if urlError, ok := err.(*url.Error); !ok || urlError.Err != checkErr {
t.Errorf("with redirects forbidden, expected a *url.Error with our 'no redirects allowed' error inside; got %#v (%q)", err, err) t.Errorf("with redirects forbidden, expected a *url.Error with our 'no redirects allowed' error inside; got %#v (%q)", err, err)
} }
if res == nil {
t.Fatalf("Expected a non-nil Response on CheckRedirect failure (http://golang.org/issue/3795)")
}
if res.Header.Get("Location") == "" {
t.Errorf("no Location header in Response")
}
} }
var expectedCookies = []*Cookie{ var expectedCookies = []*Cookie{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment