From d127edf99067399447ed98a25e580b340e444459 Mon Sep 17 00:00:00 2001 From: "Vlad A. Ionescu" Date: Thu, 8 Oct 2020 15:54:18 -0700 Subject: [PATCH] Prevent context canceled errors from being permanent in authorizer Signed-off-by: Vlad A. Ionescu Check if context is canceled before returning cached token or err. Signed-off-by: Vlad A. Ionescu Fix possible race conditions Signed-off-by: Vlad A. Ionescu Fix block Signed-off-by: Vlad A. Ionescu --- util/resolver/authorizer.go | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/util/resolver/authorizer.go b/util/resolver/authorizer.go index 9fb5bc31..15c8cf42 100644 --- a/util/resolver/authorizer.go +++ b/util/resolver/authorizer.go @@ -269,13 +269,31 @@ func (ah *authHandler) doBearerAuth(ctx context.Context) (token string, err erro scoped := strings.Join(to.Scopes, " ") ah.Lock() - if r, exist := ah.scopedTokens[scoped]; exist { + for { + r, exist := ah.scopedTokens[scoped] + if !exist { + // no entry cached + break + } ah.Unlock() r.Wait() - if r.expires.IsZero() || r.expires.After(time.Now()) { + if r.err != nil { + select { + case <-ctx.Done(): + return "", r.err + default: + } + } + if !errors.Is(r.err, context.Canceled) && + (r.expires.IsZero() || r.expires.After(time.Now())) { return r.token, r.err } + // r.err is canceled or token expired. Get rid of it and try again ah.Lock() + r2, exist := ah.scopedTokens[scoped] + if exist && r == r2 { + delete(ah.scopedTokens, scoped) + } } // only one fetch token job