Skip to content

Commit

Permalink
prepare for go1.7 with the new Context on requests
Browse files Browse the repository at this point in the history
  • Loading branch information
mna committed May 12, 2016
1 parent 2a1ed53 commit 0e4cdf8
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 3 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

Package rehttp implements an HTTP Transport (an `http.RoundTripper`) that handles retries. See the [godoc][] for details.

## Installation

Please note that rehttp requires Go1.6+, because it uses the `http.Request.Cancel` field to check for cancelled requests. It *should* work on Go1.5, but only if there is no timeout set on the `*http.Client`. Go's stdlib will return an error on the first request if that's the case, because it requires a `RoundTripper` that implements the (now deprecated in Go1.6) `CancelRequest` method.

On Go1.7+, it uses the context returned by `http.Request.Context` to check for cancelled requests.

## Installation

$ go get github.com/PuerkitoBio/rehttp

## License
Expand Down
10 changes: 10 additions & 0 deletions context_post17.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// +build go1.7

package rehttp

import "net/http"

func contextForRequest(req *http.Request) <-chan struct{} {
// req.Context always returns non-nil.
return req.Context().Done()
}
9 changes: 9 additions & 0 deletions context_pre17.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// +build !go1.7

package rehttp

import "net/http"

func contextForRequest(req *http.Request) <-chan struct{} {
return nil
}
9 changes: 8 additions & 1 deletion rehttp.go
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,10 @@ func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
var attempt int
preventRetry := req.Body != nil && t.PreventRetryWithBody

// get the done cancellation channel for the context, will be nil
// for < go1.7.
done := contextForRequest(req)

// buffer the body if needed
var br *bytes.Reader
if req.Body != nil && !preventRetry {
Expand Down Expand Up @@ -331,8 +335,11 @@ func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
select {
case <-time.After(delay):
attempt++
case <-done:
// request canceled by caller (post-1.7), don't retry
return nil, errors.New("net/http: request canceled")
case <-req.Cancel:
// request canceled by caller, don't retry
// request canceled by caller (pre-1.7), don't retry
return nil, errors.New("net/http: request canceled")
}
}
Expand Down

0 comments on commit 0e4cdf8

Please sign in to comment.