Skip to content

Commit

Permalink
Fix retires (#96)
Browse files Browse the repository at this point in the history
  • Loading branch information
dstiliadis authored Aug 5, 2019
1 parent 6adfa90 commit 36c8237
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 4 deletions.
8 changes: 5 additions & 3 deletions maniphttp/manipulator.go
Original file line number Diff line number Diff line change
Expand Up @@ -552,8 +552,9 @@ func (s *httpManipulator) send(
sp opentracing.Span,
) (*http.Response, error) {

var try int // try number. Starts at 0
var lastError error // last error before retry.
var try int // try number. Starts at 0
var lastError error // last error before retry.
var tokenRenewedOnce bool // after an authorization failures token is renewed at most once.

// We get the context deadline.
deadline, ok := mctx.Context().Deadline()
Expand Down Expand Up @@ -701,7 +702,7 @@ func (s *httpManipulator) send(
return nil, err
}

if s.tokenManager != nil && (response.StatusCode == http.StatusForbidden || response.StatusCode == http.StatusUnauthorized) {
if !tokenRenewedOnce && s.tokenManager != nil && (response.StatusCode == http.StatusForbidden || response.StatusCode == http.StatusUnauthorized) {

// This is a special case where we try to renew our token
// in case of 401 or 403 error.
Expand All @@ -713,6 +714,7 @@ func (s *httpManipulator) send(
err := s.atomicRenewTokenFunc(mctx.Context())
if err == nil {
lastError = errs
tokenRenewedOnce = true
goto RETRY
}
}
Expand Down
42 changes: 41 additions & 1 deletion maniphttp/manipulator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1409,7 +1409,7 @@ func TestHTTP_send(t *testing.T) {
})
})

Convey("Given I have a server returning 403 and with a token manager", t, func() {
Convey("Given I have a server returning 403 and with a token manager that renews the token", t, func() {

ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Header.Get("Authorization") != "Bearer ok-token" {
Expand Down Expand Up @@ -1509,6 +1509,46 @@ func TestHTTP_send(t *testing.T) {
})
})

Convey("Given I have a server returning 403 for all my requests, I should return an error and tokenmanager should only be invoked once", t, func() {

ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusForbidden)
fmt.Fprint(w, `[{"code": 403, "title": "nope", "description": "boom"}]`)
}))
defer ts.Close()

tm := maniptest.NewTestTokenManager()
var tmCalled int64
tm.MockIssue(t, func(context.Context) (string, error) {
atomic.AddInt64(&tmCalled, 1)
time.Sleep(300 * time.Millisecond)
return "ok-token", nil
})

m, _ := New(context.Background(), "toto.com")
m.(*httpManipulator).tokenManager = tm
m.(*httpManipulator).username = "Bearer"
m.(*httpManipulator).password = "ok-token"
m.(*httpManipulator).atomicRenewTokenFunc = elemental.AtomicJob(m.(*httpManipulator).renewToken)

Convey("When I call send", func() {

ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
defer cancel()

_, err := m.(*httpManipulator).send(manipulate.NewContext(ctx), http.MethodPost, ts.URL, nil, nil, sp)

Convey("Then err should be not nil", func() {
So(err, ShouldNotBeNil)
})

Convey("Then the token manager should have been called only once", func() {
So(tmCalled, ShouldEqual, 1)
})
})
})

Convey("Given I have a server returning 423", t, func() {

m, _ := New(context.Background(), "toto.com")
Expand Down

0 comments on commit 36c8237

Please sign in to comment.