func()

in rest/request.go [805:884]


func (r *Request) Stream(ctx context.Context) (io.ReadCloser, error) {
	if r.err != nil {
		return nil, r.err
	}

	if err := r.tryThrottle(ctx); err != nil {
		return nil, err
	}

	client := r.c.Client
	if client == nil {
		client = http.DefaultClient
	}

	var retryAfter *RetryAfter
	url := r.URL().String()
	for {
		req, err := r.newHTTPRequest(ctx)
		if err != nil {
			return nil, err
		}
		if r.body != nil {
			req.Body = ioutil.NopCloser(r.body)
		}

		r.backoff.Sleep(r.backoff.CalculateBackoff(r.URL()))
		if retryAfter != nil {
			// We are retrying the request that we already send to apiserver
			// at least once before.
			// This request should also be throttled with the client-internal rate limiter.
			if err := r.tryThrottleWithInfo(ctx, retryAfter.Reason); err != nil {
				return nil, err
			}
			retryAfter = nil
		}

		resp, err := client.Do(req)
		updateURLMetrics(ctx, r, resp, err)
		if r.c.base != nil {
			if err != nil {
				r.backoff.UpdateBackoff(r.URL(), err, 0)
			} else {
				r.backoff.UpdateBackoff(r.URL(), err, resp.StatusCode)
			}
		}
		if err != nil {
			// we only retry on an HTTP response with 'Retry-After' header
			return nil, err
		}

		switch {
		case (resp.StatusCode >= 200) && (resp.StatusCode < 300):
			handleWarnings(resp.Header, r.warningHandler)
			return resp.Body, nil

		default:
			done, transformErr := func() (bool, error) {
				defer resp.Body.Close()

				var retry bool
				retryAfter, retry = r.retry.NextRetry(req, resp, err, neverRetryError)
				if retry {
					err := r.retry.BeforeNextRetry(ctx, r.backoff, retryAfter, url, r.body)
					if err == nil {
						return false, nil
					}
					klog.V(4).Infof("Could not retry request - %v", err)
				}
				result := r.transformResponse(resp, req)
				if err := result.Error(); err != nil {
					return true, err
				}
				return true, fmt.Errorf("%d while accessing %v: %s", result.statusCode, url, string(result.body))
			}()
			if done {
				return nil, transformErr
			}
		}
	}
}