public void addAuthResponse(
            final HttpHost host,
            final ChallengeType challengeType,
            final HttpRequest request,
            final AuthExchange authExchange,
            final HttpContext context) {
        final HttpClientContext clientContext = HttpClientContext.cast(context);
        final String exchangeId = clientContext.getExchangeId();
        AuthScheme authScheme = authExchange.getAuthScheme();
        switch (authExchange.getState()) {
        case FAILURE:
            return;
        case SUCCESS:
            Asserts.notNull(authScheme, "AuthScheme");
            if (authScheme.isConnectionBased()) {
                return;
            }
            break;
        case HANDSHAKE:
            Asserts.notNull(authScheme, "AuthScheme");
            break;
        case CHALLENGED:
            final Queue<AuthScheme> authOptions = authExchange.getAuthOptions();
            if (authOptions != null) {
                while (!authOptions.isEmpty()) {
                    authScheme = authOptions.remove();
                    authExchange.select(authScheme);
                    if (LOG.isDebugEnabled()) {
                        LOG.debug("{} Generating response to an authentication challenge using {} scheme",
                                exchangeId, authScheme.getName());
                    }
                    try {
                        final String authResponse = authScheme.generateAuthResponse(host, request, clientContext);
                        if (authResponse != null) {
                            final Header header = new BasicHeader(
                                    challengeType == ChallengeType.TARGET ? HttpHeaders.AUTHORIZATION : HttpHeaders.PROXY_AUTHORIZATION,
                                    authResponse);
                            request.addHeader(header);
                        }
                        break;
                    } catch (final AuthenticationException ex) {
                        if (LOG.isWarnEnabled()) {
                            LOG.warn("{} {} authentication error: {}", exchangeId, authScheme, ex.getMessage());
                        }
                    }
                }
                return;
            }
            Asserts.notNull(authScheme, "AuthScheme");
        default:
        }
        // This is the SUCCESS and HANDSHAKE states, same as the initial response.
        // This only happens if the handshake requires multiple requests, which is
        // unlikely in practice.
        if (authScheme != null) {
            try {
                final String authResponse = authScheme.generateAuthResponse(host, request, clientContext);
                final Header header = new BasicHeader(
                        challengeType == ChallengeType.TARGET ? HttpHeaders.AUTHORIZATION : HttpHeaders.PROXY_AUTHORIZATION,
                        authResponse);
                request.addHeader(header);
            } catch (final AuthenticationException ex) {
                if (LOG.isErrorEnabled()) {
                    LOG.error("{} {} authentication error: {}", exchangeId, authScheme, ex.getMessage());
                }
            }
        }
    }
Generates a response to the authentication challenge based on the actual {@link AuthExchange} state
and adds it to the given {@link HttpRequest} message .

@param host the hostname of the opposite endpoint.
@param challengeType the challenge type (target or proxy).
@param request the request message head.
@param authExchange the current authentication exchange state.
@param context the current execution context.
httpclient5/src/main/java/org/apache/hc/client5/http/impl/auth/AuthenticationHandler.java