I have a small command-line program that I wrote for re-downloading files from a server in bulk. It works flawlessly in Windows, but doesn't seem to work in macOS.
Here is the error I receive:
Download failed: java.io.IOException: Server returned HTTP response code: 403 for URL:
https://cdn.modrinth.com/data/P7dR8mSH/versions/0.56.3 1.19/fabric-api-0.56.3+1.19.jar
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1914)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1512)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:268)
at java.net.URL.openStream(URL.java:1092)
at main.downloadUsingNIO(main.java:37)
at main.main(main.java:20)
Relevant code:
private static void downloadUsingNIO(String urlStr, String file) throws IOException {
URL url = new URL(urlStr);
ReadableByteChannel rbc = Channels.newChannel(url.openStream());
FileOutputStream fos = new FileOutputStream(file);
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
fos.close();
rbc.close();
}
Usage:
downloadUsingNIO(URLOFFILE, WHERETOSAVEANDTOWHATFILE);
Other information:
- Both windows and macos accounts used are the primary administrator accounts.
- running the jar with elevated permissions through "sudo java -jar " does not fix it.
- The file is downloadable in safari with the same link.
- The download works with "curl -o thing.jar "
- Tried Apache Commons.IO, didn't do anything as it uses the same code underneath (the stacktrace was the same)
Thank you for the answers, this is the code that I used to fix the issue:
private static void downloadUsingNIO(String Strurl, String path) throws IOException {
final URLConnection connection = new URL(Strurl).openConnection();
connection.addRequestProperty("User-Agent",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Firefox/102.0");
final int contentLength = connection.getContentLength();
final File end = new File(path);
if (end.exists()) {
final URLConnection savedFileConnection = end.toURI().toURL().openConnection();
if (savedFileConnection.getContentLength() == contentLength) {
return;
}
} else {
final File dir = end.getParentFile();
if (!dir.exists())
dir.mkdirs();
}
final ReadableByteChannel rbc = Channels.newChannel(connection.getInputStream());
final FileOutputStream fos = new FileOutputStream(end);
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
fos.close();
return;
}
CodePudding user response:
With high probably, the HTTP server doesn't like the Java default user agent header, which is being sent - or it's absence; use another client. This can easily be validated by comparing the server logs. https://datatracker.ietf.org/doc/html/rfc7231#section-6.5.3
The point is, that neither NIO Channel
nor URL
permit setting that header.