public void process()

in src/main/java/com/microsoft/azure/proton/transport/proxy/impl/ProxyImpl.java [274:361]


        public void process() throws TransportException {
            if (!getIsHandshakeInProgress()) {
                underlyingInput.process();
                return;
            }

            switch (proxyState) {
                case PN_PROXY_CONNECTING:
                    inputBuffer.flip();

                    final ProxyResponse connectResponse = readProxyResponse(inputBuffer);

                    if (connectResponse == null || connectResponse.isMissingContent()) {
                        LOGGER.info("Request is missing content. Waiting for more bytes.");
                        break;
                    }

                    // Clean up response to prepare for challenge
                    proxyResponse.set(null);

                    final boolean isSuccess = proxyHandler.validateProxyResponse(connectResponse);
                    // When connecting to proxy, it does not challenge us for authentication. If the user has specified
                    // a configuration, and it is not NONE, then we fail due to misconfiguration.
                    if (isSuccess) {
                        if (proxyConfiguration == null || proxyConfiguration.authentication() == ProxyAuthenticationType.NONE) {
                            proxyState = ProxyState.PN_PROXY_CONNECTED;
                        } else {
                            if (LOGGER.isErrorEnabled()) {
                                LOGGER.error("ProxyConfiguration mismatch. User configured: '{}', but authentication is not required",
                                    proxyConfiguration.authentication());
                            }
                            closeTailProxyError(PROXY_CONNECT_USER_ERROR);
                        }
                        break;
                    }

                    final Map<String, List<String>> headers = connectResponse.getHeaders();
                    final Set<ProxyAuthenticationType> supportedTypes = getAuthenticationTypes(headers);

                    // The proxy did not successfully connect, user has specified that they want a particular
                    // authentication method, but it is not in list of supported authentication methods.
                    if (proxyConfiguration != null && !supportedTypes.contains(proxyConfiguration.authentication())) {
                        if (LOGGER.isErrorEnabled()) {
                            LOGGER.error("Proxy authentication required. User configured: '{}', but supported proxy authentication methods are: {}",
                                proxyConfiguration.authentication(),
                                supportedTypes.stream().map(type -> type.toString()).collect(Collectors.joining(",")));
                        }
                        closeTailProxyError(PROXY_CONNECT_USER_ERROR + PROXY_CONNECT_FAILED
                                + connectResponse);
                        break;
                    }

                    final List<String> challenges = headers.getOrDefault(PROXY_AUTHENTICATE, new ArrayList<>());
                    final ProxyChallengeProcessor processor = proxyConfiguration != null
                            ? getChallengeProcessor(host, challenges, proxyConfiguration.authentication())
                            : getChallengeProcessor(host, challenges, supportedTypes);

                    if (processor != null) {
                        proxyState = ProxyState.PN_PROXY_CHALLENGE;
                        ProxyImpl.this.headers = processor.getHeader();
                    } else {
                        LOGGER.warn("Could not get ProxyChallengeProcessor for challenges.");
                        closeTailProxyError(PROXY_CONNECT_FAILED + String.join(";", challenges));
                    }
                    break;
                case PN_PROXY_CHALLENGE_RESPONDED:
                    inputBuffer.flip();
                    final ProxyResponse challengeResponse = readProxyResponse(inputBuffer);

                    if (challengeResponse == null || challengeResponse.isMissingContent()) {
                        LOGGER.warn("Request is missing content. Waiting for more bytes.");
                        break;
                    }
                    //Clean up
                    proxyResponse.set(null);

                    final boolean result = proxyHandler.validateProxyResponse(challengeResponse);

                    if (result) {
                        proxyState = ProxyState.PN_PROXY_CONNECTED;
                    } else {
                        closeTailProxyError(PROXY_CONNECT_FAILED + challengeResponse);
                    }
                    break;
                default:
                    underlyingInput.process();
            }
        }