diff --git a/pom.xml b/pom.xml index 6aed107..41b66f8 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ xyz.etztech EtzCore - 1.2 + 1.3 @@ -26,11 +26,6 @@ spigot-api 1.13.1-R0.1-SNAPSHOT - - org.apache.httpcomponents - httpclient - 4.5.5 - diff --git a/src/main/java/xyz/etztech/core/maven/MavenLoader.java b/src/main/java/xyz/etztech/core/maven/MavenLoader.java index ae5f986..bb66c07 100644 --- a/src/main/java/xyz/etztech/core/maven/MavenLoader.java +++ b/src/main/java/xyz/etztech/core/maven/MavenLoader.java @@ -4,6 +4,7 @@ package xyz.etztech.core.maven; import org.bukkit.plugin.java.JavaPlugin; import java.io.File; +import java.io.InputStream; import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoader; @@ -58,7 +59,9 @@ public final class MavenLoader { name, repository)); URL url = getURL(group, artifact, version, repository); - Files.copy(url.openStream(), jarFile.toPath()); + try (InputStream in = url.openStream()) { + Files.copy(in, jarFile.toPath()); + } } catch (Exception e) { e.printStackTrace(); diff --git a/src/main/java/xyz/etztech/core/web/CoreResponse.java b/src/main/java/xyz/etztech/core/web/CoreResponse.java index 0f651b1..b99bb5d 100644 --- a/src/main/java/xyz/etztech/core/web/CoreResponse.java +++ b/src/main/java/xyz/etztech/core/web/CoreResponse.java @@ -52,6 +52,14 @@ public class CoreResponse { } } + public JsonObject getJson() { + return json; + } + + public void setJson(JsonObject json) { + this.json = json; + } + public Boolean getStatus() { return status; } diff --git a/src/main/java/xyz/etztech/core/web/CoreWeb.java b/src/main/java/xyz/etztech/core/web/CoreWeb.java index 520232a..c3da8ee 100644 --- a/src/main/java/xyz/etztech/core/web/CoreWeb.java +++ b/src/main/java/xyz/etztech/core/web/CoreWeb.java @@ -1,35 +1,32 @@ package xyz.etztech.core.web; import org.apache.commons.lang.StringUtils; -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.NameValuePair; -import org.apache.http.client.HttpClient; -import org.apache.http.client.entity.UrlEncodedFormEntity; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.message.BasicNameValuePair; import org.bukkit.Bukkit; -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; import org.bukkit.scheduler.BukkitScheduler; -import java.io.BufferedReader; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; +import java.io.*; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.*; import java.util.logging.Logger; public class CoreWeb { - private static final BukkitScheduler schedule = Bukkit.getScheduler(); + private static BukkitScheduler schedule = null; private static final Logger logger = Logger.getLogger("Minecraft"); + static { + try { + schedule = Bukkit.getScheduler(); + } catch (Exception ex) { + logger.warning("Could not get scheduler. Is this running outside Minecraft?"); + } + } + /** * @param plugin The calling plugin * @param url The URL to call @@ -37,15 +34,8 @@ public class CoreWeb { */ public static void asyncGet(final Plugin plugin, final String url, final Map data) { schedule.runTaskAsynchronously(plugin, () -> { - ArrayList query = new ArrayList<>(); - for (String key : data.keySet()) { - query.add(key + "=" + data.get(key)); - } - String dataQuery = StringUtils.join(query, "&"); try { - HttpClient client = HttpClients.createDefault(); - HttpGet get = new HttpGet(url + "?" + dataQuery); - client.execute(get); + HTTP(url, HttpMethod.GET, data); } catch (Exception ex) { logger.warning("GET request failed. (" + url + ")"); } @@ -61,29 +51,12 @@ public class CoreWeb { */ public static void asyncGetCallback(final Plugin plugin, final String url, final Map data, final ICallback callback) { schedule.runTaskAsynchronously(plugin, () -> { - StringBuilder result = new StringBuilder(); - ArrayList query = new ArrayList<>(); - for (String key : data.keySet()) { - query.add(key + "=" + data.get(key)); - } - String dataQuery = StringUtils.join(query, "&"); try { - HttpClient client = HttpClients.createDefault(); - HttpGet get = new HttpGet(url + "?" + dataQuery); - HttpResponse response = client.execute(get); - HttpEntity entity = response.getEntity(); - - InputStream input = entity.getContent(); - BufferedReader in = new BufferedReader(new InputStreamReader(input)); - String inputLine; - while ((inputLine = in.readLine()) != null) { - result.append(inputLine); - } - input.close(); + String result = HTTP(url, HttpMethod.GET, data); + callback.invoke(result); } catch (Exception ex) { logger.warning("GET request failed. (" + url + ")"); } - callback.invoke(result.toString()); }); } @@ -95,14 +68,7 @@ public class CoreWeb { public static void asyncPost(final Plugin plugin, final String url, final Map data) { schedule.runTaskAsynchronously(plugin, () -> { try { - HttpClient client = HttpClients.createDefault(); - HttpPost post = new HttpPost(url); - List params = new ArrayList<>(); - for (String key : data.keySet()) { - params.add(new BasicNameValuePair(key, data.get(key))); - } - post.setEntity(new UrlEncodedFormEntity(params, "UTF-8")); - client.execute(post); + HTTP(url, HttpMethod.POST, data); } catch (Exception ex) { logger.warning("POST request failed. (" + url + ")"); } @@ -118,29 +84,48 @@ public class CoreWeb { */ public static void asyncPostCallback(final Plugin plugin, final String url, final Map data, final ICallback callback) { schedule.runTaskAsynchronously(plugin, () -> { - StringBuilder result = new StringBuilder(); try { - HttpClient client = HttpClients.createDefault(); - HttpPost post = new HttpPost(url); - List params = new ArrayList<>(); - for (String key : data.keySet()) { - params.add(new BasicNameValuePair(key, data.get(key))); - } - post.setEntity(new UrlEncodedFormEntity(params, "UTF-8")); - HttpResponse response = client.execute(post); - HttpEntity entity = response.getEntity(); - - InputStream input = entity.getContent(); - BufferedReader in = new BufferedReader(new InputStreamReader(input)); - String inputLine; - while ((inputLine = in.readLine()) != null) { - result.append(inputLine); - } - input.close(); + String result = HTTP(url, HttpMethod.POST, data); + callback.invoke(result); } catch (Exception ex) { logger.warning("POST request failed. (" + url + ")"); } - callback.invoke(result.toString()); }); } + + public enum HttpMethod { + GET, POST + } + + + public static String HTTP(String endpoint, HttpMethod method, Map data) throws Exception { + if (method == HttpMethod.POST) { + MultipartUtility request = new MultipartUtility(endpoint, "utf-8"); + for (String key : data.keySet()) { + request.addFormField(key, data.get(key)); + } + return request.finish(); + } + // Set up data + StringJoiner sj = new StringJoiner("&"); + for(Map.Entry entry : data.entrySet()) + sj.add(URLEncoder.encode(entry.getKey(), "UTF-8") + "=" + + URLEncoder.encode(entry.getValue(), "UTF-8")); + + // Set up URL + endpoint += "?" + sj.toString(); + URL url = new URL(endpoint); + HttpURLConnection http = (HttpURLConnection) url.openConnection(); + StringBuilder result = new StringBuilder(); + BufferedReader in = new BufferedReader(new InputStreamReader(http.getInputStream())); + String inputLine; + while ((inputLine = in.readLine()) != null) { + result.append(inputLine); + } + http.disconnect(); + return result.toString(); + } + + + } diff --git a/src/main/java/xyz/etztech/core/web/MultipartUtility.java b/src/main/java/xyz/etztech/core/web/MultipartUtility.java new file mode 100644 index 0000000..a2ec448 --- /dev/null +++ b/src/main/java/xyz/etztech/core/web/MultipartUtility.java @@ -0,0 +1,144 @@ +package xyz.etztech.core.web; + +import java.io.BufferedReader; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLConnection; +import java.util.ArrayList; +import java.util.List; + + +public class MultipartUtility { + private final String boundary; + private static final String LINE_FEED = "\r\n"; + private HttpURLConnection httpConn; + private String charset; + private OutputStream outputStream; + private PrintWriter writer; + + /** + * This constructor initializes a new HTTP POST request with content type + * is set to multipart/form-data + * @param requestURL + * @param charset + * @throws IOException + */ + public MultipartUtility(String requestURL, String charset) + throws IOException { + this.charset = charset; + + // creates a unique boundary based on time stamp + boundary = "===" + System.currentTimeMillis() + "==="; + + URL url = new URL(requestURL); + httpConn = (HttpURLConnection) url.openConnection(); + httpConn.setUseCaches(false); + httpConn.setDoOutput(true); // indicates POST method + httpConn.setDoInput(true); + httpConn.setRequestProperty("Content-Type", + "multipart/form-data; boundary=" + boundary); + httpConn.setRequestProperty("User-Agent", "EtzCore Agent"); + outputStream = httpConn.getOutputStream(); + writer = new PrintWriter(new OutputStreamWriter(outputStream, charset), + true); + } + + /** + * Adds a form field to the request + * @param name field name + * @param value field value + */ + public void addFormField(String name, String value) { + writer.append("--" + boundary).append(LINE_FEED); + writer.append("Content-Disposition: form-data; name=\"" + name + "\"") + .append(LINE_FEED); + writer.append("Content-Type: text/plain; charset=" + charset).append( + LINE_FEED); + writer.append(LINE_FEED); + writer.append(value).append(LINE_FEED); + writer.flush(); + } + + /** + * Adds a upload file section to the request + * @param fieldName name attribute in + * @param uploadFile a File to be uploaded + * @throws IOException + */ + public void addFilePart(String fieldName, File uploadFile) + throws IOException { + String fileName = uploadFile.getName(); + writer.append("--" + boundary).append(LINE_FEED); + writer.append( + "Content-Disposition: form-data; name=\"" + fieldName + + "\"; filename=\"" + fileName + "\"") + .append(LINE_FEED); + writer.append( + "Content-Type: " + + URLConnection.guessContentTypeFromName(fileName)) + .append(LINE_FEED); + writer.append("Content-Transfer-Encoding: binary").append(LINE_FEED); + writer.append(LINE_FEED); + writer.flush(); + + FileInputStream inputStream = new FileInputStream(uploadFile); + byte[] buffer = new byte[4096]; + int bytesRead = -1; + while ((bytesRead = inputStream.read(buffer)) != -1) { + outputStream.write(buffer, 0, bytesRead); + } + outputStream.flush(); + inputStream.close(); + + writer.append(LINE_FEED); + writer.flush(); + } + + /** + * Adds a header field to the request. + * @param name - name of the header field + * @param value - value of the header field + */ + public void addHeaderField(String name, String value) { + writer.append(name + ": " + value).append(LINE_FEED); + writer.flush(); + } + + /** + * Completes the request and receives response from the server. + * @return a String as response. + * @throws IOException Non-OK status + */ + public String finish() throws IOException { + StringBuilder response = new StringBuilder(); + + writer.append(LINE_FEED).flush(); + writer.append("--" + boundary + "--").append(LINE_FEED); + writer.close(); + + // checks server's status code first + int status = httpConn.getResponseCode(); + if (status < 300) { // 2xx generally considered OK + BufferedReader reader = new BufferedReader(new InputStreamReader( + httpConn.getInputStream())); + String line = null; + while ((line = reader.readLine()) != null) { + response.append(line); + } + reader.close(); + httpConn.disconnect(); + } else { + throw new IOException("Server returned non-OK status: " + status); + } + + return response.toString(); + } +}