
capsule.SystemProxySelector Maven / Gradle / Ivy
The newest version!
package capsule;
import java.util.Map;
import java.util.Properties;
import org.eclipse.aether.repository.Proxy;
import org.eclipse.aether.repository.ProxySelector;
import org.eclipse.aether.repository.RemoteRepository;
import org.eclipse.aether.util.repository.AuthenticationBuilder;
import org.eclipse.aether.util.repository.DefaultProxySelector;
/**
* A proxy selector that uses proxy configuration defined
* in the system environment configuration and Java
* system properties.
*
*
* @author Paolo Di Tommaso
* @author [email protected]
*/
public class SystemProxySelector implements ProxySelector {
private static final int LOG_NONE = 0;
private static final int LOG_QUIET = 1;
private static final int LOG_VERBOSE = 2;
private static final int LOG_DEBUG = 3;
private static final String LOG_PREFIX = "CAPSULE: ";
private final int logLevel;
private final DefaultProxySelector target = new DefaultProxySelector();
private final Map env;
private final Properties props;
private int count;
/**
* Create a proxy selector object looking for proxy settings in the environment
* configurations and the Java system properties. It checks the following properties:
*
* http.proxyHost (Java system property)
* https.proxyHost (Java system property)
* http_proxy (environment variable)
* https_proxy (environment variable)
* HTTP_PROXY (environment variable)
* HTTPS_PROXY (environment variable)
*
* @param logLevel Capsule logging level
*/
public SystemProxySelector(int logLevel) {
this(System.getenv(), System.getProperties(), logLevel);
}
@SuppressWarnings("OverridableMethodCallInConstructor")
SystemProxySelector(Map env, Properties props, int logLevel) {
this.env = env;
this.props = props;
this.logLevel = logLevel;
init();
}
@Override
public Proxy getProxy(RemoteRepository repository) {
return target.getProxy(repository);
}
protected void init() {
addProxyFromProperties("http");
addProxyFromProperties("https");
addProxyFromEnv("http");
addProxyFromEnv("https");
addProxyFromEnv("HTTP");
addProxyFromEnv("HTTPS");
}
protected void addProxyFromEnv(String type) {
checkValidProtocol(type);
String key = type + (isUpper(type) ? "_PROXY" : "_proxy");
String[] items = parseProxy(env.get(key), "http".equals(type) ? "80" : "443");
if (items == null)
return;
String[] credentials = parseCredentials(env.get(key));
String noProxy = env.get(isUpper(type) ? "NO_PROXY" : "no_proxy");
if (noProxy != null)
noProxy = noProxy.replace(',', '|');
Proxy proxy;
if (credentials != null) {
AuthenticationBuilder authenticationBuilder = new AuthenticationBuilder();
authenticationBuilder.addUsername(credentials[0]);
if (credentials[1] != null)
authenticationBuilder.addPassword(credentials[1]);
proxy = new Proxy(type.toLowerCase(), items[0], Integer.parseInt(items[1]), authenticationBuilder.build());
} else {
proxy = new Proxy(type.toLowerCase(), items[0], Integer.parseInt(items[1]));
}
target.add(proxy, noProxy);
count++;
// dump proxy information to logger
if (isLogging(LOG_VERBOSE))
log(LOG_VERBOSE, String.format("Adding `%s` proxy: %s [from system environment]", type, proxy));
}
protected void addProxyFromProperties(String type) {
checkValidProtocol(type);
String host = props.getProperty(type + ".proxyHost");
if (host == null || host.isEmpty())
return; // nothing to do
String port = props.getProperty(type + ".proxyPort");
if (port == null || port.isEmpty())
port = "http".equals(type) ? "80" : "443";
String nonProxy = props.getProperty(type + ".nonProxyHosts");
String username = props.getProperty(type + ".proxyUser");
String password = props.getProperty(type + ".proxyPassword");
Proxy proxy;
if (username != null) {
AuthenticationBuilder authenticationBuilder = new AuthenticationBuilder();
authenticationBuilder.addUsername(username);
if (password != null)
authenticationBuilder.addPassword(password);
proxy = new Proxy(type, host, Integer.parseInt(port), authenticationBuilder.build());
} else {
proxy = new Proxy(type, host, Integer.parseInt(port));
}
// append this proxy to the target selector
target.add(proxy, nonProxy);
count++;
// dump proxy information to logger
if (isLogging(LOG_VERBOSE))
log(LOG_VERBOSE, String.format("Adding `%s` proxy: %s [from Java system properties]", type, proxy));
}
/**
* Given a proxy URL returns a two element arrays containing the user name and the password. The second component
* of the array is null if no password is specified.
*
* @param url The proxy host URL.
* @return An array containing the user name and the password or null when none are present or the url is empty.
*/
static String[] parseCredentials(String url) {
String[] result = new String[2];
if (url == null || url.isEmpty())
return null;
int p = url.indexOf("://");
if (p != -1)
url = url.substring(p + 3);
if ((p = url.indexOf('@')) != -1) {
String credentials = url.substring(0, p);
if ((p = credentials.indexOf(':')) != -1) {
result[0] = credentials.substring(0, p);
result[1] = credentials.substring(p + 1);
} else {
result[0] = credentials;
}
} else {
return null;
}
return result;
}
/**
* Given a proxy URL returns a two element arrays containing the host name and the port
*
* @param url The proxy host URL.
* @param defPort The default proxy port
* @return An array containing the host name and the proxy port or null when url is empty
*/
static String[] parseProxy(String url, String defPort) {
String[] result = new String[2];
if (url == null || url.isEmpty())
return null;
int p = url.indexOf("://");
if (p != -1)
url = url.substring(p + 3);
if ((p = url.indexOf('@')) != -1)
url = url.substring(p + 1);
if ((p = url.indexOf(':')) != -1) {
result[0] = url.substring(0, p);
result[1] = url.substring(p + 1);
} else {
result[0] = url;
result[1] = defPort;
}
// remove trailing slash from the host name
p = result[0].indexOf("/");
if( p != -1 ) {
result[0] = result[0].substring(0,p);
}
// remove trailing slash from the port number
p = result[1].indexOf("/");
if( p != -1 ) {
result[1] = result[1].substring(0,p);
}
return result;
}
/**
* @return The number of defined proxy
*/
int getCount() {
return count;
}
/**
* @return {@code true} if the selector defines at least one proxy server
*/
public boolean isValid() {
return count > 0;
}
private boolean isUpper(String str) {
for (int i = 0; i < str.length(); i++) {
if (Character.isLowerCase(str.charAt(i)))
return false;
}
return true;
}
protected final boolean isLogging(int level) {
return level <= logLevel;
}
protected final void log(int level, String str) {
if (isLogging(level))
System.err.println(LOG_PREFIX + str);
}
protected void checkValidProtocol(String protocol) {
if ("http".equalsIgnoreCase(protocol))
return;
if ("https".equalsIgnoreCase(protocol))
return;
throw new IllegalArgumentException(String.format("Illegal proxy protocol: '%s'", protocol));
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy