All Downloads are FREE. Search and download functionalities are using the official Maven repository.

alpine.common.util.ProxyUtil Maven / Gradle / Ivy

The newest version!
/*
 * This file is part of Alpine.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * SPDX-License-Identifier: Apache-2.0
 * Copyright (c) Steve Springett. All Rights Reserved.
 */
package alpine.common.util;

import alpine.Config;
import alpine.common.logging.Logger;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;

import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Optional;
import java.util.Set;

/**
 * Utility class for working with HTTP proxies.
 *
 * @since 2.3.0
 */
public final class ProxyUtil {

    private static final Logger LOGGER = Logger.getLogger(ProxyUtil.class);

    private ProxyUtil() {
    }

    /**
     * Attempt to use application specific proxy settings if they exist.
     * Otherwise, attempt to use environment variables if they exist.
     * 

* Ported from Dependency-Track's {@code ManagedHttpClientFactory}. * * @return A {@link ProxyConfig} object, or {@code null} if no proxy is configured * @see Source */ @SuppressWarnings("unused") public static ProxyConfig getProxyConfig() { ProxyConfig proxyCfg = fromConfig(Config.getInstance()); if (proxyCfg == null) { proxyCfg = fromEnvironment(System.getenv()); } return proxyCfg; } /** * Creates a {@link ProxyConfig} object from the application.properties configuration. *

* Ported from Dependency-Track's {@code ManagedHttpClientFactory}. * * @return A {@link ProxyConfig} object, or {@code null} if no proxy is configured * @see Source */ static ProxyConfig fromConfig(final Config config) { if (config == null) { return null; } final String host = config.getProperty(Config.AlpineKey.HTTP_PROXY_ADDRESS); if (host == null) { return null; } final int port = config.getPropertyAsInt(Config.AlpineKey.HTTP_PROXY_PORT); final String username = config.getProperty(Config.AlpineKey.HTTP_PROXY_USERNAME); final String password = config.getPropertyOrFile(Config.AlpineKey.HTTP_PROXY_PASSWORD); final String noProxy = config.getProperty(Config.AlpineKey.NO_PROXY); final var proxyCfg = new ProxyConfig(); proxyCfg.setHost(host); if (port != -1) { proxyCfg.setPort(port); } if (username != null) { final Pair domainUsername = parseProxyUsername(username); Optional.ofNullable(domainUsername.getLeft()).ifPresent(proxyCfg::setDomain); Optional.ofNullable(domainUsername.getRight()).ifPresent(proxyCfg::setUsername); } if (password != null) { proxyCfg.setPassword(StringUtils.trimToNull(password)); } if (noProxy != null) { proxyCfg.setNoProxy(Set.of(noProxy.split(","))); } return proxyCfg; } /** * Creates a {@link ProxyConfig} object from the environment. *

* Ported from Dependency-Track's {@code ManagedHttpClientFactory}. * * @return A {@link ProxyConfig} object, or {@code null} if no proxy is configured * @see Source */ static ProxyConfig fromEnvironment(final Map env) { ProxyConfig proxyCfg = null; try { proxyCfg = buildFromEnvironment(env, "https_proxy"); if (proxyCfg == null) { proxyCfg = buildFromEnvironment(env, "http_proxy"); } } catch (MalformedURLException | SecurityException | UnsupportedEncodingException e) { LOGGER.warn("Could not parse proxy settings from environment", e); } if (proxyCfg != null) { for (Map.Entry entry : env.entrySet()) { if ("no_proxy".equalsIgnoreCase(entry.getKey().toUpperCase())) { proxyCfg.setNoProxy(Set.of(entry.getValue().split(","))); break; } } } return proxyCfg; } /** * Retrieves and parses the {@code https_proxy} and {@code http_proxy} settings. * This method ignores the case of the variables in the environment. *

* Ported from Dependency-Track's {@code ManagedHttpClientFactory}. * * @param variable the name of the environment variable * @return a {@link ProxyConfig} object, or {@code null} if proxy is not defined * @throws MalformedURLException if the URL of the proxy setting cannot be parsed * @throws SecurityException if the environment variable cannot be retrieved * @see Source */ private static ProxyConfig buildFromEnvironment(final Map env, final String variable) throws MalformedURLException, UnsupportedEncodingException { if (env == null || variable == null) { return null; } String proxy = null; for (Map.Entry entry : env.entrySet()) { if (variable.equalsIgnoreCase(entry.getKey().toUpperCase())) { proxy = entry.getValue(); break; } } if (proxy == null) { return null; } final var proxyUrl = URI.create(proxy).toURL(); final var proxyCfg = new ProxyConfig(); proxyCfg.setHost(proxyUrl.getHost()); proxyCfg.setPort(proxyUrl.getPort()); if (proxyUrl.getUserInfo() != null) { final String[] credentials = proxyUrl.getUserInfo().split(":"); if (credentials.length > 0) { final String username = URLDecoder.decode(credentials[0], StandardCharsets.UTF_8); final Pair domainUsername = parseProxyUsername(username); Optional.ofNullable(domainUsername.getLeft()).ifPresent(proxyCfg::setDomain); Optional.ofNullable(domainUsername.getRight()).ifPresent(proxyCfg::setUsername); } if (credentials.length == 2) { proxyCfg.setPassword(URLDecoder.decode(credentials[1], StandardCharsets.UTF_8)); } } return proxyCfg; } /** * Optionally parses usernames if they are NTLM formatted. *

* Ported from Dependency-Track's {@code ManagedHttpClientFactory}. * * @param username The username to parse * @return A {@link Pair} consisting of the user's domain (if any), and the username * @see Source */ private static Pair parseProxyUsername(final String username) { if (username.contains("\\")) { return Pair.of( username.substring(0, username.indexOf("\\")), username.substring(username.indexOf("\\") + 1) ); } return Pair.of(null, username); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy