Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implant web proxy support #1556

Merged
merged 6 commits into from
Mar 14, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
38 changes: 33 additions & 5 deletions src/main/java/github/scarsz/discordsrv/DiscordSRV.java
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,15 @@
import net.dv8tion.jda.api.utils.MemberCachePolicy;
import net.dv8tion.jda.api.utils.cache.CacheFlag;
import net.kyori.adventure.text.Component;
import okhttp3.Authenticator;
import okhttp3.ConnectionPool;
import okhttp3.Credentials;
import okhttp3.Dispatcher;
import okhttp3.Dns;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.Route;
import okhttp3.internal.Util;
import okhttp3.internal.tls.OkHostnameVerifier;
import org.apache.commons.codec.digest.DigestUtils;
Expand Down Expand Up @@ -721,19 +726,42 @@ private List<InetAddress> lookupPublic(String host) throws UnknownHostException
dispatcher.setMaxRequestsPerHost(20); // most requests are to discord.com
ConnectionPool connectionPool = new ConnectionPool(5, 10, TimeUnit.SECONDS);

OkHttpClient httpClient = new OkHttpClient.Builder()
String proxyHost = config.getString("ProxyHost").trim();
String proxyPort = config.getString("ProxyPort").trim();
ItzMiracleOwO marked this conversation as resolved.
Show resolved Hide resolved
final String authUser = config.getString("ProxyUser").trim();
final String authPassword = config.getString("ProxyPassword").trim();
granny marked this conversation as resolved.
Show resolved Hide resolved

OkHttpClient httpClient; // Initialized below
ItzMiracleOwO marked this conversation as resolved.
Show resolved Hide resolved
OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder()
.dispatcher(dispatcher)
.connectionPool(connectionPool)
.dns(dns)
// more lenient timeouts (normally 10 seconds for these 3)
ItzMiracleOwO marked this conversation as resolved.
Show resolved Hide resolved
.connectTimeout(20, TimeUnit.SECONDS)
.readTimeout(20, TimeUnit.SECONDS)
.writeTimeout(20, TimeUnit.SECONDS)
.hostnameVerifier(noopHostnameVerifier.isPresent() && noopHostnameVerifier.get()
? (hostname, sslSession) -> true
: OkHostnameVerifier.INSTANCE
)
.build();
: OkHostnameVerifier.INSTANCE);

// Reduce proxy username and password logic duplication
ItzMiracleOwO marked this conversation as resolved.
Show resolved Hide resolved
if (proxyHost != null && !proxyHost.isEmpty()) {
granny marked this conversation as resolved.
Show resolved Hide resolved
// This had to be set to empty string to avoid issue with basic auth
ItzMiracleOwO marked this conversation as resolved.
Show resolved Hide resolved
System.setProperty("jdk.http.auth.tunneling.disabledSchemes", "");
ItzMiracleOwO marked this conversation as resolved.
Show resolved Hide resolved
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, Integer.parseInt(proxyPort)));
ItzMiracleOwO marked this conversation as resolved.
Show resolved Hide resolved
httpClientBuilder = httpClientBuilder.proxy(proxy);

if (authPassword != null && !authPassword.isEmpty()) {
ItzMiracleOwO marked this conversation as resolved.
Show resolved Hide resolved
httpClientBuilder = httpClientBuilder.proxyAuthenticator(new Authenticator() {
@Override
public Request authenticate(Route route, Response response) throws IOException {
String credential = Credentials.basic(authUser, authPassword);
return response.request().newBuilder().header("Proxy-Authorization", credential).build();
}
});
}
}

httpClient = httpClientBuilder.build();
ItzMiracleOwO marked this conversation as resolved.
Show resolved Hide resolved

// set custom RestAction failure handler
Consumer<? super Throwable> defaultFailure = RestAction.getDefaultFailure();
Expand Down
5 changes: 5 additions & 0 deletions src/main/resources/config/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ ConfigVersion: ${version}
# You must restart your server after changing this option
BotToken: "BOTTOKEN"

ProxyHost: "Proxy Host"
ProxyPort: 1234 # Proxy Port
ProxyUser: "Your username"
ProxyPassword: "SomePassword"
ItzMiracleOwO marked this conversation as resolved.
Show resolved Hide resolved

# Channel links from game to Discord
# syntax is Channels: {"in-game channel name from Minecraft": "numerical channel ID from Discord", "another in-game channel name from Minecraft": "another numerical channel ID from Discord"}
#
Expand Down
7 changes: 6 additions & 1 deletion src/main/resources/config/zh.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@ ConfigVersion: ${version}
# 更改此選項後必須重新啟動服務器
BotToken: "BOTTOKEN"

# 从游戏到不和谐的频道链接
ProxyHost: "代理服务器地址"
ProxyPort: 1234 # 代理服务器端口
ProxyUser: "代理服务器用户名"
ProxyPw: "代理服务器密码"
ItzMiracleOwO marked this conversation as resolved.
Show resolved Hide resolved

# 从游戏到Discord的频道链接
# 语法为 Channels: {"来自Minecraft的游戏中频道名称": "来自Discord的数字频道ID", "来自Minecraft的另一个游戏中频道名称": "来自Discord的另一个数字频道ID”}
#
# DiscordSRV的所有消息将转到第一个通道,除非为该消息定义了一个通道:
Expand Down