FetchToken fetches a token using a GET request
(ctx context.Context, client *http.Client, headers http.Header, to TokenOptions)
| 166 | |
| 167 | // FetchToken fetches a token using a GET request |
| 168 | func FetchToken(ctx context.Context, client *http.Client, headers http.Header, to TokenOptions) (*FetchTokenResponse, error) { |
| 169 | c := *client |
| 170 | client = &c |
| 171 | tracing.UpdateHTTPClient(client, tracing.Name("remotes.docker.resolver", "FetchToken")) |
| 172 | |
| 173 | req, err := http.NewRequestWithContext(ctx, http.MethodGet, to.Realm, nil) |
| 174 | if err != nil { |
| 175 | return nil, err |
| 176 | } |
| 177 | |
| 178 | for k, v := range headers { |
| 179 | req.Header[k] = append(req.Header[k], v...) |
| 180 | } |
| 181 | if len(req.Header.Get("User-Agent")) == 0 { |
| 182 | req.Header.Set("User-Agent", "containerd/"+version.Version) |
| 183 | } |
| 184 | |
| 185 | reqParams := req.URL.Query() |
| 186 | |
| 187 | if to.Service != "" { |
| 188 | reqParams.Add("service", to.Service) |
| 189 | } |
| 190 | |
| 191 | for _, scope := range to.Scopes { |
| 192 | reqParams.Add("scope", scope) |
| 193 | } |
| 194 | |
| 195 | if to.Secret != "" { |
| 196 | req.SetBasicAuth(to.Username, to.Secret) |
| 197 | } |
| 198 | |
| 199 | if to.FetchRefreshToken { |
| 200 | reqParams.Add("offline_token", "true") |
| 201 | } |
| 202 | |
| 203 | req.URL.RawQuery = reqParams.Encode() |
| 204 | |
| 205 | resp, err := client.Do(req) |
| 206 | if err != nil { |
| 207 | return nil, err |
| 208 | } |
| 209 | defer resp.Body.Close() |
| 210 | |
| 211 | if resp.StatusCode < 200 || resp.StatusCode >= 400 { |
| 212 | return nil, remoteserrors.NewUnexpectedStatusErr(resp) |
| 213 | } |
| 214 | |
| 215 | decoder := json.NewDecoder(resp.Body) |
| 216 | |
| 217 | var tr FetchTokenResponse |
| 218 | if err = decoder.Decode(&tr); err != nil { |
| 219 | return nil, fmt.Errorf("unable to decode token response: %w", err) |
| 220 | } |
| 221 | |
| 222 | // `access_token` is equivalent to `token` and if both are specified |
| 223 | // the choice is undefined. Canonicalize `access_token` by sticking |
| 224 | // things in `token`. |
| 225 | if tr.AccessToken != "" { |
no test coverage detected
searching dependent graphs…