From bb976e776e15b67b2fc55f1ccedf36fd63c1f44b Mon Sep 17 00:00:00 2001 From: Antoine Pourchet Date: Tue, 26 Feb 2019 23:26:37 -0800 Subject: [PATCH] Locking SendWithAuth to fix race condition When SendWithAuth gets called in a multithreaded environment on the same Client object, a concurrent read and write of c.Token might happen in GetAccessToken. This patch solves the issue by locking the client while we get a new access token in SendWithAuth. --- client.go | 3 +++ types.go | 2 ++ 2 files changed, 5 insertions(+) diff --git a/client.go b/client.go index b494af8..bf4d370 100644 --- a/client.go +++ b/client.go @@ -125,10 +125,12 @@ func (c *Client) Send(req *http.Request, v interface{}) error { // making the main request // client.Token will be updated when changed func (c *Client) SendWithAuth(req *http.Request, v interface{}) error { + c.Lock() if c.Token != nil { if !c.tokenExpiresAt.IsZero() && c.tokenExpiresAt.Sub(time.Now()) < RequestNewTokenBeforeExpiresIn { // c.Token will be updated in GetAccessToken call if _, err := c.GetAccessToken(); err != nil { + c.Unlock() return err } } @@ -136,6 +138,7 @@ func (c *Client) SendWithAuth(req *http.Request, v interface{}) error { req.Header.Set("Authorization", "Bearer "+c.Token.Token) } + c.Unlock() return c.Send(req, v) } diff --git a/types.go b/types.go index 2eb4c82..6441ddf 100644 --- a/types.go +++ b/types.go @@ -5,6 +5,7 @@ import ( "fmt" "io" "net/http" + "sync" "time" ) @@ -168,6 +169,7 @@ type ( // Client represents a Paypal REST API Client Client struct { + sync.Mutex Client *http.Client ClientID string Secret string