blob: 3cc317c508fcb081e026a0a38951222cfe3776f6 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
package org.apache.chemistry.opencmis.workbench;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.chemistry.opencmis.commons.impl.IOUtils;
/**
* Tries to detect the OS proxy configuration.
*/
public class ProxyDetector {
public static final String HTTP_PROXY_HOST = "http.proxyHost";
public static final String HTTP_PROXY_PORT = "http.proxyPort";
public static final String HTTP_PROXY_USER = "http.proxyUser";
public static final String HTTP_PROXY_PASSWORD = "http.proxyPassword";
public static final String HTTPS_PROXY_HOST = "https.proxyHost";
public static final String HTTPS_PROXY_PORT = "https.proxyPort";
public static final String HTTPS_PROXY_USER = "https.proxyUser";
public static final String HTTPS_PROXY_PASSWORD = "https.proxyPassword";
public static final String HTTP_NON_PROXY_HOSTS = "http.nonProxyHosts";
public static final Pattern PROXY_ENV_VAR1 = Pattern.compile("http.?:\\/\\/(.+):(\\d+).*");
public static final Pattern PROXY_ENV_VAR2 = Pattern.compile("(.+):(\\d+)");
public static final Pattern PROXY_WIN_REG = Pattern.compile("\\s+Proxy(.+)\\s+REG.+\\s+(.+)");
private static boolean debug = false;
/**
* Gets proxy settings from system properties.
*/
public static ProxySettings getJavaProxySettings() {
ProxySettings settings = new ProxySettings();
settings.setHttpProxyHost(System.getProperty(HTTP_PROXY_HOST));
settings.setHttpProxyPort(parsePort(System.getProperty(HTTP_PROXY_PORT)));
settings.setHttpProxyUser(System.getProperty(HTTP_PROXY_USER));
settings.setHttpProxyPassword(System.getProperty(HTTP_PROXY_PASSWORD));
settings.setHttpsProxyHost(System.getProperty(HTTPS_PROXY_HOST));
settings.setHttpsProxyPort(parsePort(System.getProperty(HTTPS_PROXY_PORT)));
settings.setHttpsProxyUser(System.getProperty(HTTPS_PROXY_USER));
settings.setHttpsProxyPassword(System.getProperty(HTTPS_PROXY_PASSWORD));
String nonProxyHosts = System.getProperty(HTTP_NON_PROXY_HOSTS);
if (nonProxyHosts != null) {
List<String> noHosts = new ArrayList<String>();
String nph = nonProxyHosts;
int pp = nph.indexOf('|');
while (pp > -1) {
String noHost = nph.substring(0, pp).trim();
if (noHost.length() > 0) {
noHosts.add(noHost);
}
nph = nph.substring(pp + 1);
pp = nph.indexOf('|');
}
nph = nph.trim();
if (nph.length() > 0) {
noHosts.add(nph);
}
settings.setNonProxyHosts(noHosts);
}
if (settings.getHttpProxyHost() != null || settings.getHttpsProxyHost() != null) {
return settings;
}
return null;
}
/**
* Gets proxy settings from environment variables.
*/
public static ProxySettings getEnvProxySettings() {
ProxySettings settings = new ProxySettings();
Map<String, String> env = System.getenv();
for (Map.Entry<String, String> e : env.entrySet()) {
String key = e.getKey().trim().toLowerCase(Locale.ENGLISH);
if ("http_proxy".equals(key)) {
Matcher m = PROXY_ENV_VAR1.matcher(e.getValue());
if (m.matches()) {
settings.setHttpProxyHost(parseHost(m.group(1)));
settings.setHttpProxyPort(parsePort(m.group(2)));
settings.setHttpProxyUser(parseProxyUser(m.group(1)));
settings.setHttpProxyPassword(parseProxyPassword(m.group(1)));
} else {
m = PROXY_ENV_VAR2.matcher(e.getValue());
if (m.matches()) {
settings.setHttpProxyHost(parseHost(m.group(1)));
settings.setHttpProxyPort(parsePort(m.group(2)));
settings.setHttpProxyUser(parseProxyUser(m.group(1)));
settings.setHttpProxyPassword(parseProxyPassword(m.group(1)));
}
}
} else if ("https_proxy".equals(key)) {
Matcher m = PROXY_ENV_VAR1.matcher(e.getValue());
if (m.matches()) {
settings.setHttpsProxyHost(parseHost(m.group(1)));
settings.setHttpsProxyPort(parsePort(m.group(2)));
settings.setHttpsProxyUser(parseProxyUser(m.group(1)));
settings.setHttpsProxyPassword(parseProxyPassword(m.group(1)));
} else {
m = PROXY_ENV_VAR2.matcher(e.getValue());
if (m.matches()) {
settings.setHttpProxyHost(parseHost(m.group(1)));
settings.setHttpProxyPort(parsePort(m.group(2)));
settings.setHttpsProxyUser(parseProxyUser(m.group(1)));
settings.setHttpsProxyPassword(parseProxyPassword(m.group(1)));
}
}
} else if ("no_proxy".equals(key)) {
List<String> noHosts = new ArrayList<String>();
for (String noHost : e.getValue().split(",")) {
noHost = noHost.trim();
if (noHost.length() == 0) {
continue;
}
if (noHost.charAt(0) == '.') {
noHost = "*" + noHost;
}
if (noHost.charAt(noHost.length() - 1) == '.') {
noHost = noHost + "*";
}
noHosts.add(noHost);
}
settings.setNonProxyHosts(noHosts);
}
}
if (settings.getHttpProxyHost() != null || settings.getHttpsProxyHost() != null) {
return settings;
}
return null;
}
/**
* Gets proxy settings from the Windows registry.
*/
public static ProxySettings getRegistryProxySettings() {
if (!isWindows()) {
return null;
}
BufferedReader reader = null;
try {
ProxySettings settings = new ProxySettings();
Process process = Runtime
.getRuntime()
.exec("reg query \"HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\" /v Proxy*");
reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
Matcher m = PROXY_WIN_REG.matcher(line);
if (!m.matches()) {
continue;
}
String key = m.group(1).trim().toLowerCase(Locale.ENGLISH);
String value = m.group(2).trim();
if ("enable".equals(key)) {
if (!value.equals("0x1")) {
// proxies disabled
return null;
}
} else if ("server".equals(key)) {
// server
String host = value;
int port = 80;
int x = value.indexOf(':');
if (x > 0) {
host = value.substring(0, x);
port = parsePort(value.substring(x + 1));
}
settings.setHttpProxyHost(host);
settings.setHttpProxyPort(port);
settings.setHttpsProxyHost(host);
settings.setHttpsProxyPort(port);
} else if ("override".equals(key)) {
// no proxy
List<String> noHosts = new ArrayList<String>();
for (String noHost : value.split(";")) {
noHost = noHost.trim();
if (noHost.length() == 0) {
continue;
}
noHosts.add(noHost);
}
settings.setNonProxyHosts(noHosts);
}
}
if (settings.getHttpProxyHost() != null || settings.getHttpsProxyHost() != null) {
return settings;
}
} catch (IOException e) {
// ignore
if (debug) {
e.printStackTrace();
}
} finally {
IOUtils.closeQuietly(reader);
}
return null;
}
private static String parseHost(String host) {
if (host == null) {
return null;
}
int at = host.lastIndexOf('@');
if (at > -1) {
return host.substring(at + 1);
}
return host;
}
private static int parsePort(String port) {
if (port == null) {
return 80;
}
try {
return Integer.parseInt(port);
} catch (NumberFormatException e) {
throw new RuntimeException("Invalid port: " + port);
}
}
private static String parseProxyUser(String host) {
if (host == null) {
return null;
}
int at = host.lastIndexOf('@');
if (at == -1) {
return null;
}
int colon = host.indexOf(':');
if (colon == -1 || colon > at) {
return host.substring(0, at);
}
return host.substring(0, colon);
}
private static String parseProxyPassword(String host) {
if (host == null) {
return null;
}
int at = host.lastIndexOf('@');
if (at == -1) {
return null;
}
int colon = host.indexOf(':');
if (colon == -1 || colon > at) {
return null;
}
return host.substring(colon + 1, at);
}
private static boolean isWindows() {
return System.getProperty("os.name").startsWith("Windows");
}
/**
* Main.
*/
public static void main(String[] args) {
boolean javaParams = false;
boolean useSystemProxy = false;
for (String arg : args) {
if (arg.equalsIgnoreCase("-j")) {
javaParams = true;
} else if (arg.equalsIgnoreCase("-s")) {
useSystemProxy = true;
} else if (arg.equalsIgnoreCase("-d")) {
debug = true;
} else if (arg.equalsIgnoreCase("-h") || arg.equalsIgnoreCase("-?")) {
System.out.println("Parameters:");
System.out.println("-j print Java system properties");
System.out.println("-s add java.net.useSystemProxies property");
return;
}
}
ProxySettings settings = null;
settings = getJavaProxySettings();
if (settings == null) {
// try environment variables
settings = getEnvProxySettings();
}
if (settings == null) {
// try the Windows registry
settings = getRegistryProxySettings();
}
// print proxy settings
if (javaParams) {
String proxyStr = "";
if (settings != null) {
proxyStr = settings.toJavaConfigString();
}
if (useSystemProxy) {
if (proxyStr.length() > 0) {
proxyStr = proxyStr + " ";
}
proxyStr = proxyStr + "-Djava.net.useSystemProxies=true";
}
System.out.println(proxyStr);
} else {
if (settings != null) {
System.out.println(settings.toString());
} else {
System.out.println("DIRECT");
}
}
}
/**
* Proxy settings holder.
*/
public static class ProxySettings {
private String httpProxyHost;
private int httpProxyPort;
private String httpProxyUser;
private String httpProxyPassword;
private String httpsProxyHost;
private int httpsProxyPort;
private String httpsProxyUser;
private String httpsProxyPassword;
private List<String> nonProxyHosts;
public ProxySettings() {
}
public String getHttpProxyHost() {
return httpProxyHost;
}
public void setHttpProxyHost(String httpProxyHost) {
this.httpProxyHost = httpProxyHost;
}
public int getHttpProxyPort() {
return httpProxyPort;
}
public void setHttpProxyPort(int httpProxyPort) {
this.httpProxyPort = httpProxyPort;
}
public String getHttpProxyUser() {
return httpProxyUser;
}
public void setHttpProxyUser(String httpProxyUser) {
this.httpProxyUser = httpProxyUser;
}
public String getHttpProxyPassword() {
return httpProxyPassword;
}
public void setHttpProxyPassword(String httpProxyPassword) {
this.httpProxyPassword = httpProxyPassword;
}
public String getHttpsProxyHost() {
return httpsProxyHost;
}
public void setHttpsProxyHost(String httpsProxyHost) {
this.httpsProxyHost = httpsProxyHost;
}
public int getHttpsProxyPort() {
return httpsProxyPort;
}
public void setHttpsProxyPort(int httpsProxyPort) {
this.httpsProxyPort = httpsProxyPort;
}
public String getHttpsProxyUser() {
return httpsProxyUser;
}
public void setHttpsProxyUser(String httpsProxyUser) {
this.httpsProxyUser = httpsProxyUser;
}
public String getHttpsProxyPassword() {
return httpsProxyPassword;
}
public void setHttpsProxyPassword(String httpsProxyPassword) {
this.httpsProxyPassword = httpsProxyPassword;
}
public List<String> getNonProxyHosts() {
return nonProxyHosts;
}
public void setNonProxyHosts(List<String> nonProxyHosts) {
this.nonProxyHosts = nonProxyHosts;
}
public String toJavaConfigString() {
StringBuilder sb = new StringBuilder();
if (httpProxyHost != null) {
sb.append("-D" + HTTP_PROXY_HOST + "=" + httpProxyHost + " -D" + HTTP_PROXY_PORT + "=" + httpProxyPort);
}
if (httpProxyUser != null) {
if (sb.length() > 0) {
sb.append(' ');
}
sb.append("-D" + HTTP_PROXY_USER + "=" + httpProxyUser);
}
if (httpProxyPassword != null) {
if (sb.length() > 0) {
sb.append(' ');
}
sb.append("-D" + HTTP_PROXY_PASSWORD + "=" + httpProxyPassword);
}
if (httpsProxyHost != null) {
if (sb.length() > 0) {
sb.append(' ');
}
sb.append("-D" + HTTPS_PROXY_HOST + "=" + httpsProxyHost + " -D" + HTTPS_PROXY_PORT + "="
+ httpsProxyPort);
}
if (httpsProxyUser != null) {
if (sb.length() > 0) {
sb.append(' ');
}
sb.append("-D" + HTTPS_PROXY_USER + "=" + httpsProxyUser);
}
if (httpsProxyPassword != null) {
if (sb.length() > 0) {
sb.append(' ');
}
sb.append("-D" + HTTPS_PROXY_PASSWORD + "=" + httpsProxyPassword);
}
if (nonProxyHosts != null && !nonProxyHosts.isEmpty()) {
if (sb.length() > 0) {
sb.append(' ');
}
if (isWindows()) {
sb.append('\"');
}
sb.append("-D" + HTTP_NON_PROXY_HOSTS + "=");
boolean first = true;
for (String host : nonProxyHosts) {
if (!first) {
sb.append('|');
} else {
first = false;
}
sb.append(host);
}
if (isWindows()) {
sb.append('\"');
}
}
return sb.toString();
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
if (httpProxyHost != null) {
sb.append("HTTP proxy: " + httpProxyHost + ":" + httpProxyPort);
}
if (httpProxyUser != null) {
if (sb.length() > 0) {
sb.append('\n');
}
sb.append("HTTP proxy user: " + httpProxyUser);
}
if (httpProxyPassword != null) {
if (sb.length() > 0) {
sb.append('\n');
}
sb.append("HTTP proxy password: " + httpProxyPassword);
}
if (httpsProxyHost != null) {
if (sb.length() > 0) {
sb.append('\n');
}
sb.append("HTTPS proxy: " + httpsProxyHost + ":" + httpsProxyPort);
}
if (httpsProxyUser != null) {
if (sb.length() > 0) {
sb.append('\n');
}
sb.append("HTTPS proxy user: " + httpsProxyUser);
}
if (httpsProxyPassword != null) {
if (sb.length() > 0) {
sb.append('\n');
}
sb.append("HTTPS proxy password: " + httpsProxyPassword);
}
if (nonProxyHosts != null && !nonProxyHosts.isEmpty()) {
if (sb.length() > 0) {
sb.append('\n');
}
sb.append("Non proxy hosts: ");
boolean first = true;
for (String host : nonProxyHosts) {
if (!first) {
sb.append(",");
} else {
first = false;
}
sb.append(host);
}
}
return sb.toString();
}
}
}