package io.gitlab.jfronny.inceptum.common; import io.gitlab.jfronny.commons.HashUtils; import io.gitlab.jfronny.commons.HttpUtils; import io.gitlab.jfronny.commons.throwable.ThrowingFunction; import io.gitlab.jfronny.commons.throwable.ThrowingSupplier; import java.io.IOException; import java.io.InputStream; import java.net.URISyntaxException; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.util.Map; public class Net { private static final ObjectCache OBJECT_CACHE = new ObjectCache(MetaHolder.CACHE_DIR); public static byte[] downloadData(String url) throws IOException, URISyntaxException { try (InputStream is = HttpUtils.get(url).sendInputStream()) { return is.readAllBytes(); } } public static byte[] downloadData(String url, String sha1) throws IOException, URISyntaxException { byte[] buf = downloadData(url); if (sha1 == null) return buf; if (!HashUtils.sha1(buf).equals(sha1)) throw new IOException("Invalid hash"); return buf; } public static T downloadObject(String url, ThrowingFunction func) throws IOException { return downloadObject(url, func, true); } public static T downloadObject(String url, ThrowingFunction func, boolean cache) throws IOException { return downloadObject(url, () -> HttpUtils.get(url).sendString(), func, cache); } public static T downloadObject(String url, ThrowingFunction func, String apiKey) throws IOException { return downloadObject(url, () -> downloadStringAuthenticated(url, apiKey), func, true); } public static T downloadObject(String url, String sha1, ThrowingFunction func) throws IOException { return downloadObject(url, sha1, func, true); } public static T downloadObject(String url, String sha1, ThrowingFunction func, boolean cache) throws IOException { return downloadObject(url, () -> downloadString(url, sha1), func, cache); } private static T downloadObject(String url, ThrowingSupplier sourceString, ThrowingFunction func, boolean cache) throws IOException { try { ThrowingSupplier builder = () -> func.apply(sourceString.get()); return cache ? OBJECT_CACHE.get(HashUtils.sha1(url.getBytes(StandardCharsets.UTF_8)), sourceString, func) : builder.get(); } catch (Exception e) { throw new IOException("Could not download object and no cache exists", e); } } public static String buildUrl(String host, String url, Map params) { StringBuilder res = new StringBuilder(host); if (res.toString().endsWith("/")) res = new StringBuilder(res.substring(0, res.length() - 1)); if (url.startsWith("/")) res.append(url); else res.append("/").append(url); int i = 0; for (Map.Entry entry : params.entrySet()) { res.append(i++ == 0 ? '?' : '&') .append(URLEncoder.encode(entry.getKey(), StandardCharsets.UTF_8)) .append('=') .append(URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8)); } return res.toString(); } public static String downloadString(String url) throws IOException, URISyntaxException { return HttpUtils.get(url).sendString(); } public static String downloadString(String url, String sha1) throws IOException, URISyntaxException { return new String(downloadData(url, sha1), StandardCharsets.UTF_8); } public static String downloadStringAuthenticated(String url, String apiKey) throws IOException, URISyntaxException { return HttpUtils.get(url).header("x-api-key", apiKey).sendString(); } public static void downloadFile(String url, Path path) throws IOException, URISyntaxException { if (!Files.exists(path.getParent())) Files.createDirectories(path.getParent()); Files.write(path, downloadData(url)); } public static void downloadFile(String url, String sha1, Path path) throws IOException, URISyntaxException { if (!Files.exists(path.getParent())) Files.createDirectories(path.getParent()); Files.write(path, downloadData(url, sha1)); } }