Skip to content

Commit d29e07e

Browse files
committed
Dedicated methods for attempted downloads
1 parent e51483d commit d29e07e

File tree

1 file changed

+112
-78
lines changed

1 file changed

+112
-78
lines changed

download-utils/src/main/java/net/minecraftforge/util/download/DownloadUtils.java

Lines changed: 112 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,19 @@
1515

1616
import java.io.ByteArrayOutputStream;
1717
import java.io.File;
18+
import java.io.FileNotFoundException;
1819
import java.io.IOException;
1920
import java.io.InputStream;
2021
import java.net.HttpURLConnection;
21-
import java.net.MalformedURLException;
2222
import java.net.URI;
2323
import java.net.URISyntaxException;
2424
import java.net.URL;
2525
import java.net.URLConnection;
2626
import java.nio.charset.StandardCharsets;
2727
import java.nio.file.Files;
2828
import java.nio.file.StandardCopyOption;
29+
import java.util.ArrayList;
30+
import java.util.List;
2931

3032
public final class DownloadUtils {
3133
private static final TypeAdapter<String> STRING = new TypeAdapter<String>() {
@@ -42,6 +44,7 @@ public String read(JsonReader in) throws IOException {
4244
}
4345
return in.nextString();
4446
}
47+
4548
@Override
4649
public void write(JsonWriter out, String value) throws IOException {
4750
out.value(value);
@@ -69,114 +72,145 @@ public String read(final JsonReader in) throws IOException {
6972
})
7073
.create();
7174

72-
private static @Nullable URLConnection getConnection(String address) {
75+
private static final int TIMEOUT = 5 * 1000;
76+
private static final int MAX_REDIRECTS = 3;
77+
78+
private static URLConnection getConnection(String address) throws IOException {
7379
URI uri;
74-
URL url;
7580
try {
7681
uri = new URI(address);
77-
url = uri.toURL();
78-
} catch (MalformedURLException | URISyntaxException e) {
79-
Log.error("Malformed URL: " + address);
80-
e.printStackTrace(Log.ERROR);
81-
return null;
82+
} catch (URISyntaxException e) {
83+
throw new IOException(e);
8284
}
85+
URL url = uri.toURL();
8386

84-
try {
85-
int timeout = 5 * 1000;
86-
int max_redirects = 3;
87-
88-
URLConnection con = null;
89-
for (int x = 0; x < max_redirects; x++) {
90-
con = url.openConnection();
91-
con.setConnectTimeout(timeout);
92-
con.setReadTimeout(timeout);
93-
94-
if (con instanceof HttpURLConnection) {
95-
HttpURLConnection hcon = (HttpURLConnection) con;
96-
hcon.setRequestProperty("User-Agent", "MinecraftMaven");
97-
hcon.setRequestProperty("accept", "application/json");
98-
hcon.setInstanceFollowRedirects(false);
99-
100-
int res = hcon.getResponseCode();
101-
if (res == HttpURLConnection.HTTP_MOVED_PERM || res == HttpURLConnection.HTTP_MOVED_TEMP) {
102-
String location = hcon.getHeaderField("Location");
103-
hcon.disconnect();
104-
if (x == max_redirects - 1) {
105-
Log.error("Invalid number of redirects: " + location);
106-
return null;
107-
} else {
108-
Log.debug("Following redirect: " + location);
109-
uri = uri.resolve(location);
110-
url = uri.toURL();
111-
}
112-
} else if (res == 404) {
113-
// File not found
114-
return null;
115-
} else {
116-
break;
117-
}
87+
List<String> redirections = new ArrayList<>();
88+
URLConnection con;
89+
for (int redirects = 0; ; redirects++) {
90+
con = url.openConnection();
91+
con.setConnectTimeout(TIMEOUT);
92+
con.setReadTimeout(TIMEOUT);
93+
94+
if (!(con instanceof HttpURLConnection)) break;
95+
96+
HttpURLConnection hcon = (HttpURLConnection) con;
97+
hcon.setRequestProperty("User-Agent", "MinecraftMaven");
98+
hcon.setRequestProperty("accept", "application/json");
99+
hcon.setInstanceFollowRedirects(false);
100+
101+
int res = hcon.getResponseCode();
102+
if (res == HttpURLConnection.HTTP_MOVED_PERM || res == HttpURLConnection.HTTP_MOVED_TEMP) {
103+
String location = hcon.getHeaderField("Location");
104+
redirections.add(location);
105+
hcon.disconnect();
106+
107+
if (redirects == MAX_REDIRECTS - 1) {
108+
throw new IOException(String.format(
109+
"Too many redirects: %s -- redirections: [%s]",
110+
address, String.join(", ", redirections)
111+
));
118112
} else {
119-
break;
113+
Log.debug("Following redirect: " + location);
114+
uri = uri.resolve(location);
115+
url = uri.toURL();
120116
}
117+
} else if (res == 404) {
118+
throw new FileNotFoundException("Returned 404: " + address);
119+
} else {
120+
break;
121121
}
122-
return con;
123-
} catch (IOException e) {
124-
Log.error("Failed to establish connection to " + address);
125-
e.printStackTrace(Log.ERROR);
126-
return null;
127122
}
123+
124+
return con;
128125
}
129126

130127
/**
131128
* Downloads a string from the given URL, effectively acting as {@code curl}.
132129
*
133130
* @param url The URL to download from
131+
* @return The downloaded string
132+
* @throws IOException If the download failed
133+
*/
134+
public static String downloadString(String url) throws IOException {
135+
URLConnection connection = getConnection(url);
136+
try (InputStream stream = connection.getInputStream();
137+
ByteArrayOutputStream out = new ByteArrayOutputStream();
138+
) {
139+
byte[] buf = new byte[1024];
140+
int n;
141+
while ((n = stream.read(buf)) > 0) {
142+
out.write(buf, 0, n);
143+
}
144+
145+
return new String(out.toByteArray(), StandardCharsets.UTF_8);
146+
}
147+
}
148+
149+
/**
150+
* Downloads a string from the given URL, effectively acting as {@code curl}.
151+
* <p>Returns {@code null} on failure.</p>
152+
*
153+
* @param url The URL to download from
134154
* @return The downloaded string, or {@code null} if the download failed
135155
*/
136-
public static @Nullable String downloadString(String url) {
156+
public static @Nullable String tryDownloadString(boolean silent, String url) {
137157
try {
138-
URLConnection connection = getConnection(url);
139-
if (connection != null) {
140-
try (InputStream stream = connection.getInputStream();
141-
ByteArrayOutputStream out = new ByteArrayOutputStream();
142-
) {
143-
byte[] buf = new byte[1024];
144-
int n;
145-
while ((n = stream.read(buf)) > 0) {
146-
out.write(buf, 0, n);
147-
}
148-
149-
return new String(out.toByteArray(), StandardCharsets.UTF_8);
150-
}
151-
}
158+
return downloadString(url);
152159
} catch (IOException e) {
153-
Log.warn("Failed to download " + url);
154-
e.printStackTrace(Log.WARN);
160+
if (!silent) {
161+
Log.warn("Failed to download " + url);
162+
e.printStackTrace(Log.WARN);
163+
}
164+
165+
return null;
155166
}
156-
return null;
157167
}
158168

159169
/**
160170
* Downloads a file from the given URL into the target file, effectively acting as {@code wget}.
161171
*
162172
* @param target The file to download to
163173
* @param url The URL to download from
174+
* @throws IOException If the download failed
175+
*/
176+
public static void downloadFile(File target, String url) throws IOException {
177+
downloadFile(false, target, url);
178+
}
179+
180+
/**
181+
* Downloads a file from the given URL into the target file, effectively acting as {@code wget}.
182+
*
183+
* @param silent If no log messages should be sent
184+
* @param target The file to download to
185+
* @param url The URL to download from
186+
* @throws IOException If the download failed
187+
*/
188+
public static void downloadFile(boolean silent, File target, String url) throws IOException {
189+
if (!silent) Log.quiet("Downloading " + url);
190+
191+
URLConnection connection = getConnection(url);
192+
Files.createDirectories(target.toPath().getParent());
193+
Files.copy(connection.getInputStream(), target.toPath(), StandardCopyOption.REPLACE_EXISTING);
194+
}
195+
196+
/**
197+
* Attempts to download a file from the given URL into the target file, effectively acting as {@code wget}.
198+
*
199+
* @param target The file to download to
200+
* @param url The URL to download from
164201
* @return {@code true} if the download was successful
165202
*/
166-
public static boolean downloadFile(File target, String url) {
203+
public static boolean tryDownloadFile(boolean silent, File target, String url) {
167204
try {
168-
Files.createDirectories(target.toPath().getParent());
169-
Log.quiet("Downloading " + url);
170-
171-
URLConnection connection = getConnection(url);
172-
if (connection != null) {
173-
Files.copy(connection.getInputStream(), target.toPath(), StandardCopyOption.REPLACE_EXISTING);
174-
return true;
175-
}
205+
downloadFile(silent, target, url);
206+
return true;
176207
} catch (IOException e) {
177-
Log.warn("Failed to download " + url);
178-
e.printStackTrace(Log.WARN);
208+
if (!silent) {
209+
Log.warn("Failed to download " + url);
210+
e.printStackTrace(Log.WARN);
211+
}
212+
213+
return false;
179214
}
180-
return false;
181215
}
182216
}

0 commit comments

Comments
 (0)