@@ -716,50 +716,11 @@ func (c *dockerClient) setupRequestAuth(req *http.Request, extraScope *authScope
716716 req .SetBasicAuth (c .auth .Username , c .auth .Password )
717717 return nil
718718 case "bearer" :
719- registryToken := c .registryToken
720- if registryToken == "" {
721- cacheKey := ""
722- scopes := []authScope {c .scope }
723- if extraScope != nil {
724- // Using ':' as a separator here is unambiguous because getBearerToken below
725- // uses the same separator when formatting a remote request (and because
726- // repository names that we create can't contain colons, and extraScope values
727- // coming from a server come from `parseAuthScope`, which also splits on colons).
728- cacheKey = fmt .Sprintf ("%s:%s:%s" , extraScope .resourceType , extraScope .remoteName , extraScope .actions )
729- if colonCount := strings .Count (cacheKey , ":" ); colonCount != 2 {
730- return fmt .Errorf (
731- "Internal error: there must be exactly 2 colons in the cacheKey ('%s') but got %d" ,
732- cacheKey ,
733- colonCount ,
734- )
735- }
736- scopes = append (scopes , * extraScope )
737- }
738- var token bearerToken
739- t , inCache := c .tokenCache .Load (cacheKey )
740- if inCache {
741- token = t .(bearerToken )
742- }
743- if ! inCache || time .Now ().After (token .expirationTime ) {
744- var (
745- t * bearerToken
746- err error
747- )
748- if c .auth .IdentityToken != "" {
749- t , err = c .getBearerTokenOAuth2 (req .Context (), challenge , scopes )
750- } else {
751- t , err = c .getBearerToken (req .Context (), challenge , scopes )
752- }
753- if err != nil {
754- return err
755- }
756-
757- token = * t
758- c .tokenCache .Store (cacheKey , token )
759- }
760- registryToken = token .token
719+ token , err := c .obtainBearerToken (req .Context (), challenge , extraScope )
720+ if err != nil {
721+ return err
761722 }
762- req .Header .Set ("Authorization" , fmt .Sprintf ("Bearer %s" , registryToken ))
723+ req .Header .Set ("Authorization" , fmt .Sprintf ("Bearer %s" , token ))
763724 return nil
764725 default :
765726 logrus .Debugf ("no handler for %s authentication" , challenge .Scheme )
@@ -769,6 +730,54 @@ func (c *dockerClient) setupRequestAuth(req *http.Request, extraScope *authScope
769730 return nil
770731}
771732
733+ // obtainBearerToken gets an "Authorization: Bearer" token if one is available, or obtains a fresh one.
734+ func (c * dockerClient ) obtainBearerToken (ctx context.Context , challenge challenge , extraScope * authScope ) (string , error ) {
735+ registryToken := c .registryToken
736+ if registryToken == "" {
737+ cacheKey := ""
738+ scopes := []authScope {c .scope }
739+ if extraScope != nil {
740+ // Using ':' as a separator here is unambiguous because getBearerToken below
741+ // uses the same separator when formatting a remote request (and because
742+ // repository names that we create can't contain colons, and extraScope values
743+ // coming from a server come from `parseAuthScope`, which also splits on colons).
744+ cacheKey = fmt .Sprintf ("%s:%s:%s" , extraScope .resourceType , extraScope .remoteName , extraScope .actions )
745+ if colonCount := strings .Count (cacheKey , ":" ); colonCount != 2 {
746+ return "" , fmt .Errorf (
747+ "Internal error: there must be exactly 2 colons in the cacheKey ('%s') but got %d" ,
748+ cacheKey ,
749+ colonCount ,
750+ )
751+ }
752+ scopes = append (scopes , * extraScope )
753+ }
754+ var token bearerToken
755+ t , inCache := c .tokenCache .Load (cacheKey )
756+ if inCache {
757+ token = t .(bearerToken )
758+ }
759+ if ! inCache || time .Now ().After (token .expirationTime ) {
760+ var (
761+ t * bearerToken
762+ err error
763+ )
764+ if c .auth .IdentityToken != "" {
765+ t , err = c .getBearerTokenOAuth2 (ctx , challenge , scopes )
766+ } else {
767+ t , err = c .getBearerToken (ctx , challenge , scopes )
768+ }
769+ if err != nil {
770+ return "" , err
771+ }
772+
773+ token = * t
774+ c .tokenCache .Store (cacheKey , token )
775+ }
776+ registryToken = token .token
777+ }
778+ return registryToken , nil
779+ }
780+
772781func (c * dockerClient ) getBearerTokenOAuth2 (ctx context.Context , challenge challenge ,
773782 scopes []authScope ) (* bearerToken , error ) {
774783 realm , ok := challenge .Parameters ["realm" ]
0 commit comments