Skip to content

Commit

Permalink
Copy headers when following redirect URL and process special 307 http…
Browse files Browse the repository at this point in the history
… header (#550)
  • Loading branch information
vadmeste authored and harshavardhana committed Nov 12, 2016
1 parent 88cd2fc commit 42ea28a
Showing 1 changed file with 41 additions and 13 deletions.
54 changes: 41 additions & 13 deletions api.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,18 @@ func (r *lockedRandSource) Seed(seed int64) {
r.lk.Unlock()
}

// redirectHeaders copies all headers when following a redirect URL.
// This won't be needed anymore from go 1.8 (https://github.com/golang/go/issues/4800)
func redirectHeaders(req *http.Request, via []*http.Request) error {
if len(via) == 0 {
return nil
}
for key, val := range via[0].Header {
req.Header[key] = val
}
return nil
}

func privateNew(endpoint, accessKeyID, secretAccessKey string, secure bool) (*Client, error) {
// construct endpoint.
endpointURL, err := getEndpointURL(endpoint, secure)
Expand All @@ -174,7 +186,8 @@ func privateNew(endpoint, accessKeyID, secretAccessKey string, secure bool) (*Cl

// Instantiate http client and bucket location cache.
clnt.httpClient = &http.Client{
Transport: http.DefaultTransport,
Transport: http.DefaultTransport,
CheckRedirect: redirectHeaders,
}

// Instantiae bucket location cache.
Expand Down Expand Up @@ -364,20 +377,35 @@ func (c Client) dumpHTTP(req *http.Request, resp *http.Response) error {

// do - execute http request.
func (c Client) do(req *http.Request) (*http.Response, error) {
// do the request.
resp, err := c.httpClient.Do(req)
if err != nil {
// Handle this specifically for now until future Golang
// versions fix this issue properly.
urlErr, ok := err.(*url.Error)
if ok && strings.Contains(urlErr.Err.Error(), "EOF") {
return nil, &url.Error{
Op: urlErr.Op,
URL: urlErr.URL,
Err: fmt.Errorf("Connection closed by foreign host %s. Retry again.", urlErr.URL),
var resp *http.Response
var err error
// Do the request in a loop in case of 307 http is met since golang still doesn't
// handle properly this situation (https://github.com/golang/go/issues/7912)
for {
resp, err = c.httpClient.Do(req)
if err != nil {
// Handle this specifically for now until future Golang
// versions fix this issue properly.
urlErr, ok := err.(*url.Error)
if ok && strings.Contains(urlErr.Err.Error(), "EOF") {
return nil, &url.Error{
Op: urlErr.Op,
URL: urlErr.URL,
Err: fmt.Errorf("Connection closed by foreign host %s. Retry again.", urlErr.URL),
}
}
return nil, err
}
// Redo the request with the new redirect url if http 307 is returned, quit the loop otherwise
if resp != nil && resp.StatusCode == http.StatusTemporaryRedirect {
newURL, err := url.Parse(resp.Header.Get("Location"))
if err != nil {
break
}
req.URL = newURL
} else {
break
}
return nil, err
}

// Response cannot be non-nil, report if its the case.
Expand Down

0 comments on commit 42ea28a

Please sign in to comment.