Add explicit timeout of 10s to resource-downloads to avoid stalling

This commit is contained in:
Lukas Rieger (Blue) 2025-01-14 18:32:21 +01:00
parent 91e0cdf283
commit b3dfc47e64
No known key found for this signature in database
GPG Key ID: AA33883B1BBA03E6
2 changed files with 29 additions and 9 deletions

View File

@ -39,10 +39,11 @@
import java.io.IOException;
import java.io.OutputStream;
import java.io.Reader;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
@ -53,7 +54,7 @@
public class MinecraftVersion {
private static final Gson GSON = new Gson();
private static final String LATEST_KNOWN_VERSION = "1.20.6";
private static final String LATEST_KNOWN_VERSION = "1.21.4";
private static final String EARLIEST_RESOURCEPACK_VERSION = "1.13";
private static final String EARLIEST_DATAPACK_VERSION = "1.19.4";
@ -143,7 +144,7 @@ private static void download(VersionManifest.Version version, Path file) throws
try {
try (
DigestInputStream in = new DigestInputStream(
new URI(download.getUrl()).toURL().openStream(),
download.createInputStream(),
MessageDigest.getInstance("SHA-1")
);
OutputStream out = Files.newOutputStream(unverifiedFile)
@ -165,7 +166,7 @@ private static void download(VersionManifest.Version version, Path file) throws
// rename once verified
FileHelper.atomicMove(unverifiedFile, file);
} catch (NoSuchAlgorithmException | IOException | URISyntaxException ex) {
} catch (NoSuchAlgorithmException | IOException ex) {
Logger.global.logWarning("Failed to download '" + download.getUrl() + "': " + ex);
} finally {
Files.deleteIfExists(unverifiedFile);

View File

@ -33,7 +33,7 @@
import org.jetbrains.annotations.Nullable;
import java.io.*;
import java.net.URL;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.Arrays;
@ -48,6 +48,8 @@ public class VersionManifest {
public static final String DOMAIN = "https://piston-meta.mojang.com/";
public static final String MANIFEST_URL = DOMAIN + "mc/game/version_manifest.json";
private static final int CONNECTION_TIMEOUT = 10000;
private static final Gson GSON = new GsonBuilder()
.registerTypeAdapter(LocalDateTime.class, new LocalDateTimeAdapter())
.create();
@ -71,7 +73,7 @@ public static VersionManifest getOrFetch() throws IOException {
public static VersionManifest fetch() throws IOException {
try (
InputStream in = new URL(MANIFEST_URL).openStream();
InputStream in = openInputStream(MANIFEST_URL);
Reader reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8))
) {
instance = GSON.fromJson(reader, VersionManifest.class);
@ -118,7 +120,7 @@ public static class Version implements Comparable<Version> {
public synchronized VersionDetail fetchDetail() throws IOException {
if (detail == null) {
try (
InputStream in = new URL(url).openStream();
InputStream in = openInputStream(url);
Reader reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8))
) {
detail = GSON.fromJson(reader, VersionDetail.class);
@ -153,6 +155,23 @@ public static class Download {
private String url;
private long size;
private String sha1;
public InputStream createInputStream() throws IOException {
return openInputStream(url);
}
}
private static InputStream openInputStream(String urlPath) throws IOException {
try {
URL downloadUrl = new URI(urlPath).toURL();
URLConnection connection = downloadUrl.openConnection();
connection.setConnectTimeout(CONNECTION_TIMEOUT);
connection.setReadTimeout(CONNECTION_TIMEOUT);
return connection.getInputStream();
} catch (URISyntaxException e) {
throw new IOException(e);
}
}
}