MCPcopy Create free account
hub / github.com/containers/image / makeRequestToResolvedURL

Method makeRequestToResolvedURL

docker/docker_client.go:535–590  ·  view source on GitHub ↗

makeRequestToResolvedURL creates and executes a http.Request with the specified parameters, adding authentication and TLS options for the Docker client. streamLen, if not -1, specifies the length of the data expected on stream. makeRequest should generally be preferred. In case of an HTTP 429 status

(ctx context.Context, method string, requestURL *url.URL, headers map[string][]string, stream io.Reader, streamLen int64, auth sendAuth, extraScope *authScope)

Source from the content-addressed store, hash-verified

533// In case of an HTTP 429 status code in the response, it may automatically retry a few times.
534// TODO(runcom): too many arguments here, use a struct
535func (c *dockerClient) makeRequestToResolvedURL(ctx context.Context, method string, requestURL *url.URL, headers map[string][]string, stream io.Reader, streamLen int64, auth sendAuth, extraScope *authScope) (*http.Response, error) {
536 delay := backoffInitialDelay
537 attempts := 0
538 for {
539 res, err := c.makeRequestToResolvedURLOnce(ctx, method, requestURL, headers, stream, streamLen, auth, extraScope)
540 if err != nil {
541 return nil, err
542 }
543 attempts++
544
545 // By default we use pre-defined scopes per operation. In
546 // certain cases, this can fail when our authentication is
547 // insufficient, then we might be getting an error back with a
548 // Www-Authenticate Header indicating an insufficient scope.
549 //
550 // Check for that and update the client challenges to retry after
551 // requesting a new token
552 //
553 // We only try this on the first attempt, to not overload an
554 // already struggling server.
555 // We also cannot retry with a body (stream != nil) as stream
556 // was already read
557 if attempts == 1 && stream == nil && auth != noAuth {
558 if retry, newScope := needsRetryWithUpdatedScope(res); retry {
559 logrus.Debug("Detected insufficient_scope error, will retry request with updated scope")
560 res.Body.Close()
561 // Note: This retry ignores extraScope. That’s, strictly speaking, incorrect, but we don’t currently
562 // expect the insufficient_scope errors to happen for those callers. If that changes, we can add support
563 // for more than one extra scope.
564 res, err = c.makeRequestToResolvedURLOnce(ctx, method, requestURL, headers, stream, streamLen, auth, newScope)
565 if err != nil {
566 return nil, err
567 }
568 extraScope = newScope
569 }
570 }
571
572 if res.StatusCode != http.StatusTooManyRequests || // Only retry on StatusTooManyRequests, success or other failure is returned to caller immediately
573 stream != nil || // We can't retry with a body (which is not restartable in the general case)
574 attempts == backoffNumIterations {
575 return res, nil
576 }
577 // close response body before retry or context done
578 res.Body.Close()
579
580 delay = min(parseRetryAfter(res, delay), backoffMaxDelay)
581 logrus.Debugf("Too many requests to %s: sleeping for %f seconds before next attempt", requestURL.Redacted(), delay.Seconds())
582 select {
583 case <-ctx.Done():
584 return nil, ctx.Err()
585 case <-time.After(delay):
586 // Nothing
587 }
588 delay *= 2 // If the registry does not specify a delay, back off exponentially.
589 }
590}
591
592// makeRequestToResolvedURLOnce creates and executes a http.Request with the specified parameters, adding authentication and TLS options for the Docker client.

Callers 5

makeRequestMethod · 0.95
getExternalBlobMethod · 0.95
PutBlobWithOptionsMethod · 0.80
mountBlobMethod · 0.80

Calls 5

parseRetryAfterFunction · 0.85
DebugMethod · 0.80
CloseMethod · 0.65

Tested by

no test coverage detected