diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/fabric/FabricVersionList.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/fabric/FabricVersionList.java index 0d31af861..9837bc679 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/fabric/FabricVersionList.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/fabric/FabricVersionList.java @@ -68,7 +68,7 @@ public final class FabricVersionList extends VersionList { private static final String GAME_META_URL = "https://meta.fabricmc.net/v2/versions/game"; private List getGameVersions(String metaUrl) throws IOException { - String json = NetworkUtils.doGet(NetworkUtils.toURL(downloadProvider.injectURL(metaUrl))); + String json = NetworkUtils.doGet(downloadProvider.injectURLWithCandidates(metaUrl)); return JsonUtils.GSON.>fromJson(json, new TypeToken>() { }.getType()).stream().map(GameVersion::getVersion).collect(Collectors.toList()); } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/java/JavaDownloadTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/java/JavaDownloadTask.java index cc93cc9d1..25956b71c 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/java/JavaDownloadTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/java/JavaDownloadTask.java @@ -27,7 +27,6 @@ import org.jackhuang.hmcl.task.Task; import org.jackhuang.hmcl.util.gson.JsonUtils; import org.jackhuang.hmcl.util.io.ChecksumMismatchException; import org.jackhuang.hmcl.util.io.FileUtils; -import org.jackhuang.hmcl.util.io.NetworkUtils; import org.jackhuang.hmcl.util.platform.OperatingSystem; import org.jackhuang.hmcl.util.versioning.VersionNumber; import org.tukaani.xz.LZMAInputStream; @@ -58,8 +57,8 @@ public class JavaDownloadTask extends Task { this.javaVersion = javaVersion; this.rootDir = rootDir; this.downloadProvider = downloadProvider; - this.javaDownloadsTask = new GetTask(NetworkUtils.toURL(downloadProvider.injectURL( - "https://piston-meta.mojang.com/v1/products/java-runtime/2ec0cc96c44e5a76b9c8b7c39df7210883d12871/all.json"))) + this.javaDownloadsTask = new GetTask(downloadProvider.injectURLWithCandidates( + "https://piston-meta.mojang.com/v1/products/java-runtime/2ec0cc96c44e5a76b9c8b7c39df7210883d12871/all.json")) .thenComposeAsync(javaDownloadsJson -> { JavaDownloads allDownloads = JsonUtils.fromNonNullJson(javaDownloadsJson, JavaDownloads.class); if (!allDownloads.getDownloads().containsKey(platform)) throw new UnsupportedPlatformException(); @@ -69,7 +68,7 @@ public class JavaDownloadTask extends Task { for (JavaDownloads.JavaDownload download : candidates) { if (VersionNumber.compare(download.getVersion().getName(), Integer.toString(javaVersion.getMajorVersion())) >= 0) { this.download = download; - return new GetTask(NetworkUtils.toURL(downloadProvider.injectURL(download.getManifest().getUrl()))); + return new GetTask(downloadProvider.injectURLWithCandidates(download.getManifest().getUrl())); } } throw new UnsupportedPlatformException(); @@ -117,7 +116,7 @@ public class JavaDownloadTask extends Task { if (file.getDownloads().containsKey("lzma")) { DownloadInfo download = file.getDownloads().get("lzma"); File tempFile = jvmDir.resolve(entry.getKey() + ".lzma").toFile(); - FileDownloadTask task = new FileDownloadTask(NetworkUtils.toURL(downloadProvider.injectURL(download.getUrl())), tempFile, new FileDownloadTask.IntegrityCheck("SHA-1", download.getSha1())); + FileDownloadTask task = new FileDownloadTask(downloadProvider.injectURLWithCandidates(download.getUrl()), tempFile, new FileDownloadTask.IntegrityCheck("SHA-1", download.getSha1())); task.setName(entry.getKey()); dependencies.add(task.thenRunAsync(() -> { Path decompressed = jvmDir.resolve(entry.getKey() + ".tmp"); @@ -135,7 +134,7 @@ public class JavaDownloadTask extends Task { })); } else if (file.getDownloads().containsKey("raw")) { DownloadInfo download = file.getDownloads().get("raw"); - FileDownloadTask task = new FileDownloadTask(NetworkUtils.toURL(downloadProvider.injectURL(download.getUrl())), dest.toFile(), new FileDownloadTask.IntegrityCheck("SHA-1", download.getSha1())); + FileDownloadTask task = new FileDownloadTask(downloadProvider.injectURLWithCandidates(download.getUrl()), dest.toFile(), new FileDownloadTask.IntegrityCheck("SHA-1", download.getSha1())); task.setName(entry.getKey()); if (file.isExecutable()) { dependencies.add(task.thenRunAsync(() -> dest.toFile().setExecutable(true))); diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/neoforge/NeoForgeBMCLVersionList.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/neoforge/NeoForgeBMCLVersionList.java index a783372ab..37396af5b 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/neoforge/NeoForgeBMCLVersionList.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/neoforge/NeoForgeBMCLVersionList.java @@ -22,12 +22,12 @@ import com.google.gson.annotations.SerializedName; import com.google.gson.reflect.TypeToken; import org.jackhuang.hmcl.download.VersionList; import org.jackhuang.hmcl.util.Immutable; -import org.jackhuang.hmcl.util.Lang; import org.jackhuang.hmcl.util.StringUtils; import org.jackhuang.hmcl.util.gson.Validation; import org.jackhuang.hmcl.util.io.HttpRequest; import org.jackhuang.hmcl.util.versioning.VersionNumber; +import java.util.Collections; import java.util.List; import java.util.Optional; import java.util.concurrent.CompletableFuture; @@ -86,7 +86,7 @@ public final class NeoForgeBMCLVersionList extends VersionList { private static final String GAME_META_URL = "https://meta.quiltmc.org/v3/versions/game"; private List getGameVersions(String metaUrl) throws IOException { - String json = NetworkUtils.doGet(NetworkUtils.toURL(downloadProvider.injectURL(metaUrl))); + String json = NetworkUtils.doGet(downloadProvider.injectURLWithCandidates(metaUrl)); return JsonUtils.GSON.>fromJson(json, new TypeToken>() { }.getType()).stream().map(GameVersion::getVersion).collect(Collectors.toList()); } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/io/NetworkUtils.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/io/NetworkUtils.java index 9a604cbd5..5d4e51a6c 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/io/NetworkUtils.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/io/NetworkUtils.java @@ -178,6 +178,34 @@ public final class NetworkUtils { return IOUtils.readFullyAsString(con.getInputStream()); } + public static String doGet(List urls) throws IOException { + List exceptions = null; + for (URL url : urls) { + try { + HttpURLConnection con = createHttpConnection(url); + con = resolveConnection(con); + return IOUtils.readFullyAsString(con.getInputStream()); + } catch (IOException e) { + if (exceptions == null) { + exceptions = new ArrayList<>(1); + } + exceptions.add(e); + } + } + + if (exceptions == null) { + throw new IOException("No candidate URL"); + } else if (exceptions.size() == 1) { + throw exceptions.get(0); + } else { + IOException exception = new IOException("Failed to doGet"); + for (IOException e : exceptions) { + exception.addSuppressed(e); + } + throw exception; + } + } + public static String doPost(URL u, Map params) throws IOException { StringBuilder sb = new StringBuilder(); if (params != null) {