LibJF/libjf-base/src/main/java/io/gitlab/jfronny/libjf/HttpUtils.java

163 lines
6.2 KiB
Java

package io.gitlab.jfronny.libjf;
import io.gitlab.jfronny.commons.serialize.gson.api.v1.GsonHolders;
import java.io.*;
import java.lang.reflect.Type;
import java.net.*;
import java.net.http.*;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Optional;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @deprecated User the commons HttpUtils instead
*/
@Deprecated
public class HttpUtils {
private static final HttpClient CLIENT = HttpClient.newBuilder().followRedirects(HttpClient.Redirect.ALWAYS).build();
private enum Method {
GET, POST
}
public static class Request {
private static final Pattern CURSEFORGE_API = Pattern.compile("(?:http(s)?://)?addons-ecs\\.forgesvc\\.net/api/+");
private final String url;
private final HttpRequest.Builder builder;
private Method method;
private int sent = 0;
public Request(Method method, String url) throws URISyntaxException {
this.url = url.replace(" ", "%20");
this.builder = HttpRequest.newBuilder()
.uri(new URI(this.url))
.header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36");
this.method = method;
}
public Request bearer(String token) {
builder.header("Authorization", "Bearer " + token);
return this;
}
public Request header(String name, String value) {
builder.header(name, value);
return this;
}
public Request bodyString(String string) {
builder.header("Content-Type", "text/plain");
builder.method(method.name(), HttpRequest.BodyPublishers.ofString(string));
method = null;
return this;
}
public Request bodyForm(String string) {
builder.header("Content-Type", "application/x-www-form-urlencoded");
builder.method(method.name(), HttpRequest.BodyPublishers.ofString(string));
method = null;
return this;
}
public Request bodyForm(Map<String, String> entries) {
return bodyForm(entries.entrySet()
.stream()
.map(entry -> URLEncoder.encode(entry.getKey(), StandardCharsets.UTF_8) + '=' + URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8))
.collect(Collectors.joining("&")));
}
public Request bodyJson(String string) {
builder.header("Content-Type", "application/json");
builder.method(method.name(), HttpRequest.BodyPublishers.ofString(string));
method = null;
return this;
}
public Request bodyJson(Object object) {
builder.header("Content-Type", "application/json");
builder.method(method.name(), HttpRequest.BodyPublishers.ofString(GsonHolders.API.getGson().toJson(object)));
method = null;
return this;
}
private <T> T _send(String accept, HttpResponse.BodyHandler<T> responseBodyHandler) throws IOException {
sent++;
if (sent > 3) throw new IOException("Attempted third redirect, stopping");
builder.header("Accept", accept);
if (method != null) builder.method(method.name(), HttpRequest.BodyPublishers.noBody());
HttpResponse<T> res;
try {
res = CLIENT.send(builder.build(), responseBodyHandler);
} catch (InterruptedException e) {
throw new IOException("Could not send request", e);
}
if (res.statusCode() == 200) return res.body();
Optional<String> location = res.headers().firstValue("location");
// Redirect
if (location.isPresent() && (res.statusCode() == 302 || res.statusCode() == 307) && method == Method.GET) {
try {
return HttpUtils.get(location.get())._send(accept, responseBodyHandler);
} catch (URISyntaxException e) {
throw new IOException("Could not follow redirect", e);
}
}
// CurseForge serverside error
if (CURSEFORGE_API.matcher(url).matches() && res.statusCode() >= 500 && res.statusCode() < 600) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new IOException("Could not sleep before resending request" + e);
}
return _send(accept, responseBodyHandler);
}
throw new IOException("Unexpected return method: " + res.statusCode() + " (URL=" + url + ")");
}
public void send() throws IOException {
_send("*/*", HttpResponse.BodyHandlers.discarding());
}
public InputStream sendInputStream() throws IOException {
return _send("*/*", HttpResponse.BodyHandlers.ofInputStream());
}
public String sendString() throws IOException {
return _send("*/*", HttpResponse.BodyHandlers.ofString());
}
public Stream<String> sendLines() throws IOException {
return _send("*/*", HttpResponse.BodyHandlers.ofLines());
}
public <T> T sendJson(Type type) throws IOException {
InputStream in = _send("application/json", HttpResponse.BodyHandlers.ofInputStream());
return in == null ? null : GsonHolders.API.getGson().fromJson(new InputStreamReader(in), type);
}
private String getString(Object a) throws IOException {
if (a instanceof InputStream s) return new String(s.readAllBytes());
if (a instanceof String s) return s;
if (a instanceof Stream s) return ((Stream<String>)s).collect(Collectors.joining());
return "";
}
}
public static Request get(String url) throws URISyntaxException {
return new Request(Method.GET, url);
}
public static Request post(String url) throws URISyntaxException {
return new Request(Method.POST, url);
}
}