Compare commits

..
2 changed files with 50 additions and 8 deletions

No files matched your search

@@ -47,20 +47,21 @@ import static org.jackhuang.hmcl.util.logging.Logger.LOG;
public final class CurseForgeRemoteModRepository implements RemoteModRepository {
private static final String PREFIX = "https://api.curseforge.com";
private static final String apiKey = System.getProperty("hmcl.curseforge.apikey", JarUtils.getAttribute("hmcl.curseforge.apikey", ""));
private static final Semaphore SEMAPHORE = new Semaphore(16);
public static final String API_KEY = System.getProperty("hmcl.curseforge.apikey", JarUtils.getAttribute("hmcl.curseforge.apikey", ""));
private static final int WORD_PERFECT_MATCH_WEIGHT = 5;
private static <R extends HttpRequest> R withApiKey(R request) {
if (request.getUrl().startsWith(PREFIX) && !apiKey.isEmpty()) {
request.header("X-API-KEY", apiKey);
if (request.getUrl().startsWith(PREFIX) && !API_KEY.isEmpty()) {
request.header("X-API-KEY", API_KEY);
}
return request;
}
public static boolean isAvailable() {
return !apiKey.isEmpty();
return !API_KEY.isEmpty();
}
private final Type type;
@@ -18,6 +18,7 @@
package org.jackhuang.hmcl.util.io;
import org.glavo.url.WebURL;
import org.jackhuang.hmcl.mod.curse.CurseForgeRemoteModRepository;
import org.jackhuang.hmcl.util.Pair;
import org.jackhuang.hmcl.util.StringUtils;
import org.jetbrains.annotations.NotNull;
@@ -163,6 +164,45 @@ public final class NetworkUtils {
}
}
private static final List<Pair<String, String>> API_KEYS;
static {
if (CurseForgeRemoteModRepository.API_KEY.isEmpty()) {
API_KEYS = List.of();
} else {
API_KEYS = List.of(
pair("api.curseforge.com", CurseForgeRemoteModRepository.API_KEY),
pair("forgecdn.net", CurseForgeRemoteModRepository.API_KEY)
);
}
}
private static boolean matchDomainSuffix(String domain, String suffix) {
return domain.endsWith(suffix)
&& (domain.length() == suffix.length() || domain.charAt(domain.length() - suffix.length() - 1) == '.');
}
public static void injectApiKey(WebURL url, URLConnection connection) {
if (!(connection instanceof HttpURLConnection))
return;
if (connection.getRequestProperty("x-api-key") != null) {
return;
}
String host = url.getHost();
if (host == null || host.isEmpty())
return;
for (Pair<String, String> pair : API_KEYS) {
String hostSuffix = pair.getKey();
if (matchDomainSuffix(host, hostSuffix)) {
connection.addRequestProperty("x-api-key", pair.getValue());
return;
}
}
}
public static URLConnection createConnection(WebURL url) throws IOException {
URLConnection connection;
try {
@@ -176,6 +216,7 @@ public final class NetworkUtils {
httpConnection.setRequestProperty("Accept-Language", Locale.getDefault().toLanguageTag());
httpConnection.setRequestProperty("User-Agent", USER_AGENT);
httpConnection.setInstanceFollowRedirects(false);
injectApiKey(url, connection);
}
return connection;
}
@@ -293,10 +334,10 @@ public final class NetworkUtils {
throw new IOException("Too much redirects");
}
HttpURLConnection redirected = (HttpURLConnection) new URL(conn.getURL(), encodeLocation(newURL))
.openConnection();
properties
.forEach((key, value) -> value.forEach(element -> redirected.addRequestProperty(key, element)));
WebURL redirectedUrl = WebURL.of(conn.getURL()).resolve(newURL);
HttpURLConnection redirected = (HttpURLConnection) redirectedUrl.toURL().openConnection();
properties.forEach((key, value) -> value.forEach(element -> redirected.addRequestProperty(key, element)));
injectApiKey(redirectedUrl, redirected);
redirected.setRequestMethod(method);
conn = redirected;
++redirect;