package org.simplejavamail.mailer.config;
import org.simplejavamail.mailer.internal.socks.SocksProxyConfig;
import static java.lang.String.format;
import static org.simplejavamail.util.ConfigLoader.Property.*;
import static org.simplejavamail.util.ConfigLoader.valueOrProperty;
import static org.simplejavamail.internal.util.MiscUtil.checkArgumentNotEmpty;
import static org.simplejavamail.internal.util.MiscUtil.valueNullOrEmpty;
/**
* The proxy configuration that indicates whether the connections should be routed through a proxy.
* <p>
* In case a proxy is required, the properties <em>"mail.smtp.socks.host"</em> and <em>"mail.smtp.socks.port"</em> will be set.
* <p>
* As the underlying JavaMail framework only support anonymous SOCKS proxy servers for non-ssl connections, authenticated SOCKS5 proxy is made
* possible using an intermediary anonymous proxy server which relays the connection through an authenticated remote proxy server. Anonymous proxies
* are still handled by JavaMail's own time-tested proxy client implementation.
* <p>
* Attempting to use a proxy and SSL SMTP authentication will result in an error, as the underlying JavaMail framework ignores any proxy settings for
* SSL connections.
*/
public class ProxyConfig extends SocksProxyConfig {
/**
* The temporary intermediary SOCKS5 relay server bridge is a server that sits in between JavaMail and the remote proxy. Default port is {@value
* #DEFAULT_PROXY_BRIDGE_PORT}.
*/
@SuppressWarnings("JavaDoc")
public static final int DEFAULT_PROXY_BRIDGE_PORT = 1081;
/**
* 'Skip proxy' constructor short-cut.
*
* @see #ProxyConfig(String, Integer, String, String)
*/
public ProxyConfig() {
this(null, null, null, null);
}
/**
* 'Anonymous proxy' constructor short-cut.
*
* @param remoteProxyHost The host of the remote proxy.
* @param remoteProxyPort The port of the remote proxy.
* @see #ProxyConfig(String, Integer, String, String)
*/
public ProxyConfig(final String remoteProxyHost, final Integer remoteProxyPort) {
this(remoteProxyHost, remoteProxyPort, null, null);
}
/**
* Creates an proxy configuration, which can be anonymous or authenticated. Host and port are required and either both or none of username and
* password should be provided. All arguments can be empty if the related properties are configured in a config file.
*
* @param remoteProxyHost The host of the remote proxy.
* @param remoteProxyPort The port of the remote proxy.
* @param username Username is mandatory when authentication is required.
* @param password Password is mandatory when authentication is required.
*/
@SuppressWarnings({ "WeakerAccess", "SameParameterValue" })
public ProxyConfig(final String remoteProxyHost, final Integer remoteProxyPort, final String username, final String password) {
super(
valueOrProperty(remoteProxyHost, PROXY_HOST),
valueOrProperty(remoteProxyPort, PROXY_PORT),
valueOrProperty(username, PROXY_USERNAME),
valueOrProperty(password, PROXY_PASSWORD),
valueOrProperty(null, PROXY_SOCKS5BRIDGE_PORT, DEFAULT_PROXY_BRIDGE_PORT)
);
if (!valueNullOrEmpty(this.remoteProxyHost)) {
checkArgumentNotEmpty(this.remoteProxyPort, "remoteProxyPort not given and not configured in config file");
if (!valueNullOrEmpty(this.username) && valueNullOrEmpty(this.password)) {
throw new IllegalArgumentException("Proxy username provided but no password given as argument or in config file");
}
if (valueNullOrEmpty(this.username) && !valueNullOrEmpty(this.password)) {
throw new IllegalArgumentException("Proxy password provided but no username given as argument or in config file");
}
}
}
/**
* If a host was provided then proxy is required.
*/
public boolean requiresProxy() {
return remoteProxyHost != null;
}
/**
* If a username was provided, we will need to authenticate with the proxy.
*/
public boolean requiresAuthentication() {
return username != null;
}
@Override
public String toString() {
String str = "";
if (remoteProxyHost == null) {
return "no-proxy";
} else {
str += format("%s:%s", remoteProxyHost, remoteProxyPort);
}
if (username != null) {
str += format(", username: %s", username);
}
if (proxyBridgePort != DEFAULT_PROXY_BRIDGE_PORT) {
str += format(", proxy bridge @ localhost:%s", proxyBridgePort);
}
return str;
}
public int getProxyBridgePort() {
return proxyBridgePort;
}
/**
* @param proxyBridgePort Port override for the temporary intermediary SOCKS5 relay server bridge (default is {@value
* #DEFAULT_PROXY_BRIDGE_PORT}).
*/
public void setProxyBridgePort(final int proxyBridgePort) {
this.proxyBridgePort = proxyBridgePort;
}
public String getRemoteProxyHost() {
return remoteProxyHost;
}
public Integer getRemoteProxyPort() {
return remoteProxyPort;
}
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
}