package games.strategy.engine.framework.map.download; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.nio.channels.Channels; import java.nio.channels.ReadableByteChannel; import java.util.HashMap; import java.util.Map; import java.util.Optional; import games.strategy.debug.ClientLogger; public class DownloadUtils { private static Map<URL, Integer> downloadLengthCache = new HashMap<>(); static Optional<Integer> getDownloadLength(URL url) { if (!downloadLengthCache.containsKey(url)) { Optional<Integer> length = getDownloadLengthWithoutCache(url); if (length.isPresent()) { downloadLengthCache.put(url, length.get()); } else { return Optional.empty(); } } return Optional.of(downloadLengthCache.get(url)); } private static Optional<Integer> getDownloadLengthWithoutCache(URL url) { try { HttpURLConnection httpConn = (HttpURLConnection) url.openConnection(); int responseCode = httpConn.getResponseCode(); // always check HTTP response code first if (responseCode == HttpURLConnection.HTTP_OK) { int length = httpConn.getContentLength(); if (length <= 0) { return Optional.empty(); } else { return Optional.of(httpConn.getContentLength()); } } else { ClientLogger.logQuietly("Unexpected response code: " + responseCode); return Optional.empty(); } } catch (IOException e) { ClientLogger.logQuietly("Failed to connect to: " + url + ", to get download size. Ignoring this error and will " + "not display the map download size on the UI.", e); return Optional.empty(); } } public static URL toURL(String url) { try { return new URL(url); } catch (MalformedURLException e) { throw new IllegalStateException("Invalid URL: " + url, e); } } public static void downloadFile(URL url, File targetFile) throws IOException { FileOutputStream fos = new FileOutputStream(targetFile); url = getUrlFollowingRedirects(url); ReadableByteChannel rbc = Channels.newChannel(url.openStream()); fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); fos.close(); } public static void downloadFile(String urlString, File targetFile) throws IOException { downloadFile(getUrlFollowingRedirects(urlString), targetFile); } private static URL getUrlFollowingRedirects(String possibleRedirectionUrl) throws IOException { URL url = new URL(possibleRedirectionUrl); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); int status = conn.getResponseCode(); if (status == HttpURLConnection.HTTP_MOVED_TEMP || status == HttpURLConnection.HTTP_MOVED_PERM || status == HttpURLConnection.HTTP_SEE_OTHER) { // update the URL if we were redirected url = new URL(conn.getHeaderField("Location")); } return url; } private static URL getUrlFollowingRedirects(URL url) throws IOException { HttpURLConnection conn = (HttpURLConnection) url.openConnection(); int status = conn.getResponseCode(); if (status == HttpURLConnection.HTTP_MOVED_TEMP || status == HttpURLConnection.HTTP_MOVED_PERM || status == HttpURLConnection.HTTP_SEE_OTHER) { // update the URL if we were redirected url = new URL(conn.getHeaderField("Location")); } return url; } }