1
0
Fork 0
mirror of https://codeberg.org/Mercury-IM/Smack synced 2024-11-25 15:52:06 +01:00

Merge pull request #466 from Vshnv/master

Added proxy support for XEP-0363
This commit is contained in:
Florian Schmaus 2021-03-29 18:15:40 +02:00 committed by GitHub
commit 8c57d34b97
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 70 additions and 17 deletions

View file

@ -16,6 +16,10 @@
*/ */
package org.jivesoftware.smack.proxy; package org.jivesoftware.smack.proxy;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.SocketAddress;
/** /**
* Class which stores proxy information such as proxy type, host, port, * Class which stores proxy information such as proxy type, host, port,
* authentication etc. * authentication etc.
@ -44,19 +48,10 @@ public class ProxyInfo {
this.proxyPort = pPort; this.proxyPort = pPort;
this.proxyUsername = pUser; this.proxyUsername = pUser;
this.proxyPassword = pPass; this.proxyPassword = pPass;
switch (proxyType) { this.proxySocketConnection =
case HTTP: ProxySocketConnection
proxySocketConnection = new HTTPProxySocketConnection(this); .forProxyType(proxyType)
break; .apply(this);
case SOCKS4:
proxySocketConnection = new Socks4ProxySocketConnection(this);
break;
case SOCKS5:
proxySocketConnection = new Socks5ProxySocketConnection(this);
break;
default:
throw new IllegalStateException();
}
} }
public static ProxyInfo forHttpProxy(String pHost, int pPort, String pUser, public static ProxyInfo forHttpProxy(String pHost, int pPort, String pUser,
@ -74,6 +69,18 @@ public class ProxyInfo {
return new ProxyInfo(ProxyType.SOCKS5, pHost, pPort, pUser, pPass); return new ProxyInfo(ProxyType.SOCKS5, pHost, pPort, pUser, pPass);
} }
public Proxy.Type getJavaProxyType() {
switch (proxyType) {
case HTTP:
return Proxy.Type.HTTP;
case SOCKS4:
case SOCKS5:
return Proxy.Type.SOCKS;
default:
throw new AssertionError("Invalid proxy type: " + proxyType);
}
}
public ProxyType getProxyType() { public ProxyType getProxyType() {
return proxyType; return proxyType;
} }
@ -97,4 +104,11 @@ public class ProxyInfo {
public ProxySocketConnection getProxySocketConnection() { public ProxySocketConnection getProxySocketConnection() {
return proxySocketConnection; return proxySocketConnection;
} }
public Proxy toJavaProxy() {
final SocketAddress proxySocketAddress = new InetSocketAddress(proxyAddress, proxyPort);
final Proxy.Type type = getJavaProxyType();
return new Proxy(type, proxySocketAddress);
}
} }

View file

@ -19,6 +19,8 @@ package org.jivesoftware.smack.proxy;
import java.io.IOException; import java.io.IOException;
import java.net.Socket; import java.net.Socket;
import org.jivesoftware.smack.util.Function;
public interface ProxySocketConnection { public interface ProxySocketConnection {
/** /**
@ -34,4 +36,16 @@ public interface ProxySocketConnection {
void connect(Socket socket, String host, int port, int timeout) void connect(Socket socket, String host, int port, int timeout)
throws IOException; throws IOException;
static Function<ProxySocketConnection, ProxyInfo> forProxyType(ProxyInfo.ProxyType proxyType) {
switch (proxyType) {
case HTTP:
return HTTPProxySocketConnection::new;
case SOCKS4:
return Socks4ProxySocketConnection::new;
case SOCKS5:
return Socks5ProxySocketConnection::new;
default:
throw new AssertionError("Unknown proxy type: " + proxyType);
}
}
} }

View file

@ -27,7 +27,6 @@ import java.net.HttpURLConnection;
import java.net.URL; import java.net.URL;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects; import java.util.Objects;
import java.util.WeakHashMap; import java.util.WeakHashMap;
import java.util.logging.Level; import java.util.logging.Level;
@ -37,6 +36,7 @@ import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext; import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.SSLSocketFactory;
import org.jivesoftware.smack.AbstractXMPPConnection;
import org.jivesoftware.smack.ConnectionCreationListener; import org.jivesoftware.smack.ConnectionCreationListener;
import org.jivesoftware.smack.ConnectionListener; import org.jivesoftware.smack.ConnectionListener;
import org.jivesoftware.smack.Manager; import org.jivesoftware.smack.Manager;
@ -46,6 +46,7 @@ import org.jivesoftware.smack.XMPPConnectionRegistry;
import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.XMPPException.XMPPErrorException;
import org.jivesoftware.smack.proxy.ProxyInfo;
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
import org.jivesoftware.smackx.disco.packet.DiscoverInfo; import org.jivesoftware.smackx.disco.packet.DiscoverInfo;
import org.jivesoftware.smackx.httpfileupload.UploadService.Version; import org.jivesoftware.smackx.httpfileupload.UploadService.Version;
@ -429,15 +430,15 @@ public final class HttpFileUploadManager extends Manager {
private void upload(InputStream iStream, long fileSize, Slot slot, UploadProgressListener listener) throws IOException { private void upload(InputStream iStream, long fileSize, Slot slot, UploadProgressListener listener) throws IOException {
final URL putUrl = slot.getPutUrl(); final URL putUrl = slot.getPutUrl();
final XMPPConnection connection = connection();
final HttpURLConnection urlConnection = (HttpURLConnection) putUrl.openConnection(); final HttpURLConnection urlConnection = createURLConnection(connection, putUrl);
urlConnection.setRequestMethod("PUT"); urlConnection.setRequestMethod("PUT");
urlConnection.setUseCaches(false); urlConnection.setUseCaches(false);
urlConnection.setDoOutput(true); urlConnection.setDoOutput(true);
urlConnection.setFixedLengthStreamingMode(fileSize); urlConnection.setFixedLengthStreamingMode(fileSize);
urlConnection.setRequestProperty("Content-Type", "application/octet-stream"); urlConnection.setRequestProperty("Content-Type", "application/octet-stream");
for (Entry<String, String> header : slot.getHeaders().entrySet()) { for (Map.Entry<String, String> header : slot.getHeaders().entrySet()) {
urlConnection.setRequestProperty(header.getKey(), header.getValue()); urlConnection.setRequestProperty(header.getKey(), header.getValue());
} }
@ -503,6 +504,30 @@ public final class HttpFileUploadManager extends Manager {
} }
} }
private static HttpURLConnection createURLConnection(XMPPConnection connection, URL putUrl) throws IOException {
Objects.requireNonNull(connection);
Objects.requireNonNull(putUrl);
ProxyInfo proxyInfo = fetchProxyInfo(connection);
if (proxyInfo != null) {
return createProxiedURLConnection(proxyInfo, putUrl);
}
return (HttpURLConnection) putUrl.openConnection();
}
private static HttpURLConnection createProxiedURLConnection(ProxyInfo proxyInfo, URL putUrl) throws IOException {
Objects.requireNonNull(proxyInfo);
Objects.requireNonNull(putUrl);
return (HttpURLConnection) putUrl.openConnection(proxyInfo.toJavaProxy());
}
private static ProxyInfo fetchProxyInfo(XMPPConnection connection) {
if (!(connection instanceof AbstractXMPPConnection)) {
return null;
}
AbstractXMPPConnection xmppConnection = (AbstractXMPPConnection) connection;
return xmppConnection.getConfiguration().getProxyInfo();
}
public static UploadService.Version namespaceToVersion(String namespace) { public static UploadService.Version namespaceToVersion(String namespace) {
UploadService.Version version; UploadService.Version version;
switch (namespace) { switch (namespace) {