From 3c2c71011574ee000dbe0b13b840a94b905d8834 Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Fri, 15 Sep 2017 17:11:45 +0300 Subject: [PATCH] Replaced Apache HttpClient implementation with base Java implementation of Post request. --- .../plan/systems/webserver/webapi/WebAPI.java | 77 +++++----- .../webserver/webapi/WebAPIManager.java | 4 + .../webapi/bukkit/InspectWebAPI.java | 4 +- .../webapi/universal/PingWebAPI.java | 2 +- .../plan/systems/webserver/WebAPITest.java | 39 +++++ Plan/test/test/java/utils/TestInit.java | 137 ++++++++++++++++++ 6 files changed, 220 insertions(+), 43 deletions(-) create mode 100644 Plan/test/main/java/com/djrapitops/plan/systems/webserver/WebAPITest.java diff --git a/Plan/src/main/java/com/djrapitops/plan/systems/webserver/webapi/WebAPI.java b/Plan/src/main/java/com/djrapitops/plan/systems/webserver/webapi/WebAPI.java index fe602a1c7..1bdea205a 100644 --- a/Plan/src/main/java/com/djrapitops/plan/systems/webserver/webapi/WebAPI.java +++ b/Plan/src/main/java/com/djrapitops/plan/systems/webserver/webapi/WebAPI.java @@ -10,19 +10,13 @@ import main.java.com.djrapitops.plan.api.exceptions.WebAPIConnectionFailExceptio import main.java.com.djrapitops.plan.api.exceptions.WebAPIException; import main.java.com.djrapitops.plan.systems.webserver.response.Response; import main.java.com.djrapitops.plan.utilities.MiscUtils; -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.HttpPost; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.message.BasicNameValuePair; +import java.io.DataOutputStream; import java.io.IOException; -import java.io.InputStream; -import java.io.UnsupportedEncodingException; -import java.util.*; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.Map; +import java.util.UUID; /** * @author Rsl1122 @@ -33,40 +27,43 @@ public abstract class WebAPI { public abstract Response onResponse(IPlan plugin, Map variables); - public String sendRequest(String address, UUID receiverUUID) throws WebAPIException { + public void sendRequest(String address, UUID receiverUUID) throws WebAPIException { Verify.nullCheck(address, receiverUUID); - HttpClient httpClient = HttpClients.createDefault(); - - HttpPost postRequest = new HttpPost(address + "/api/" + this.getClass().getSimpleName().toLowerCase()); - - List parameters = new ArrayList<>(); - String serverUUID = MiscUtils.getIPlan().getServerInfoManager().getServerUUID().toString(); - parameters.add(new BasicNameValuePair("sender", serverUUID)); - parameters.add(new BasicNameValuePair("key", receiverUUID.toString())); - for (Map.Entry entry : variables.entrySet()) { - parameters.add(new BasicNameValuePair(entry.getKey(), entry.getValue())); - } - try { - postRequest.setEntity(new UrlEncodedFormEntity(parameters, "ISO-8859-1")); - } catch (UnsupportedEncodingException e) { - throw new WebAPIException("Unsupported parameter encoding", e); - } + URL url = new URL(address + "/api/" + this.getClass().getSimpleName().toLowerCase()); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setDoOutput(true); + connection.setInstanceFollowRedirects(false); + connection.setRequestMethod("POST"); + connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); + connection.setRequestProperty("charset", "ISO-8859-1"); - try { - HttpResponse response = httpClient.execute(postRequest); - HttpEntity responseEntity = response.getEntity(); + StringBuilder parameters = new StringBuilder(); + String serverUUID = MiscUtils.getIPlan().getServerInfoManager().getServerUUID().toString(); + parameters.append("sender=").append(serverUUID).append("&"); + parameters.append("key=").append(receiverUUID.toString()); + for (Map.Entry entry : variables.entrySet()) { + parameters.append("&").append(entry.getKey()).append(entry.getValue()); + } + byte[] toSend = parameters.toString().getBytes(); + int length = toSend.length; - if (responseEntity != null) { - StringBuilder content = new StringBuilder(); - try (InputStream inputStream = responseEntity.getContent()) { - Scanner scanner = new Scanner(inputStream); - while (scanner.hasNextLine()) { - content.append(scanner.nextLine()); - } - } - return content.toString(); + connection.setRequestProperty("Content-Length", Integer.toString(length)); + + connection.setUseCaches(false); + try (DataOutputStream out = new DataOutputStream(connection.getOutputStream())) { + out.write(toSend); + } + + int responseCode = connection.getResponseCode(); + switch (responseCode) { + case 200: + break; + case 400: + throw new WebAPIException("Bad Request: " + url.toString() + "|" + parameters); + default: + throw new WebAPIException(url.toString() + "| Wrong response code " + responseCode); } } catch (IOException e) { throw new WebAPIConnectionFailException("API connection failed.", e); diff --git a/Plan/src/main/java/com/djrapitops/plan/systems/webserver/webapi/WebAPIManager.java b/Plan/src/main/java/com/djrapitops/plan/systems/webserver/webapi/WebAPIManager.java index 8bb617ca6..8277b3c40 100644 --- a/Plan/src/main/java/com/djrapitops/plan/systems/webserver/webapi/WebAPIManager.java +++ b/Plan/src/main/java/com/djrapitops/plan/systems/webserver/webapi/WebAPIManager.java @@ -25,6 +25,10 @@ public class WebAPIManager { registry.put(api.getClass().getSimpleName().toLowerCase(), api); } + public WebAPI getAPI(Class api) { + return getAPI(api.getSimpleName()); + } + public WebAPI getAPI(String apiName) { return registry.get(apiName.toLowerCase()); } diff --git a/Plan/src/main/java/com/djrapitops/plan/systems/webserver/webapi/bukkit/InspectWebAPI.java b/Plan/src/main/java/com/djrapitops/plan/systems/webserver/webapi/bukkit/InspectWebAPI.java index 1d142d8f9..1ba3392b3 100644 --- a/Plan/src/main/java/com/djrapitops/plan/systems/webserver/webapi/bukkit/InspectWebAPI.java +++ b/Plan/src/main/java/com/djrapitops/plan/systems/webserver/webapi/bukkit/InspectWebAPI.java @@ -33,8 +33,8 @@ public class InspectWebAPI extends WebAPI { return PageCache.loadPage("success", SuccessResponse::new); } - public String sendRequest(String address, UUID receiverUUID, UUID uuid) throws WebAPIException { + public void sendRequest(String address, UUID receiverUUID, UUID uuid) throws WebAPIException { addVariable("uuid", uuid.toString()); - return super.sendRequest(address, receiverUUID); + super.sendRequest(address, receiverUUID); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/systems/webserver/webapi/universal/PingWebAPI.java b/Plan/src/main/java/com/djrapitops/plan/systems/webserver/webapi/universal/PingWebAPI.java index 33e07f3b6..feb2e72f1 100644 --- a/Plan/src/main/java/com/djrapitops/plan/systems/webserver/webapi/universal/PingWebAPI.java +++ b/Plan/src/main/java/com/djrapitops/plan/systems/webserver/webapi/universal/PingWebAPI.java @@ -15,7 +15,7 @@ import java.util.Map; /** * @author Fuzzlemann */ -public class PingWebAPI implements WebAPI { +public class PingWebAPI extends WebAPI { @Override public Response onResponse(IPlan plugin, Map variables) { return PageCache.loadPage("success", SuccessResponse::new); diff --git a/Plan/test/main/java/com/djrapitops/plan/systems/webserver/WebAPITest.java b/Plan/test/main/java/com/djrapitops/plan/systems/webserver/WebAPITest.java new file mode 100644 index 000000000..4d32669e3 --- /dev/null +++ b/Plan/test/main/java/com/djrapitops/plan/systems/webserver/WebAPITest.java @@ -0,0 +1,39 @@ +/* + * Licence is provided in the jar as license.yml also here: + * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml + */ +package main.java.com.djrapitops.plan.systems.webserver; + +import main.java.com.djrapitops.plan.Plan; +import main.java.com.djrapitops.plan.api.exceptions.WebAPIException; +import main.java.com.djrapitops.plan.systems.webserver.webapi.WebAPI; +import main.java.com.djrapitops.plan.systems.webserver.webapi.universal.PingWebAPI; +import org.junit.Before; +import org.junit.Test; +import test.java.utils.TestInit; + +import static org.junit.Assert.assertTrue; + +/** + * //TODO Class Javadoc Comment + * + * @author Rsl1122 + */ +public class WebAPITest { + + private WebServer webServer; + + @Before + public void setUp() throws Exception { + TestInit.initEmptyLocale(); + webServer = new WebServer(null); + webServer.initServer(); + assertTrue(webServer.isEnabled()); + } + + @Test + public void testPingWebAPI() throws WebAPIException { + WebAPI api = webServer.getWebAPI().getAPI(PingWebAPI.class); + api.sendRequest(webServer.getAccessAddress(), Plan.getServerUUID()); + } +} \ No newline at end of file diff --git a/Plan/test/test/java/utils/TestInit.java b/Plan/test/test/java/utils/TestInit.java index dc676261f..5129d0d0d 100644 --- a/Plan/test/test/java/utils/TestInit.java +++ b/Plan/test/test/java/utils/TestInit.java @@ -19,13 +19,21 @@ import main.java.com.djrapitops.plan.systems.info.server.ServerInfoManager; import org.bukkit.ChatColor; import org.bukkit.OfflinePlayer; import org.bukkit.Server; +import org.bukkit.command.ConsoleCommandSender; import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.conversations.Conversation; +import org.bukkit.conversations.ConversationAbandonedEvent; +import org.bukkit.permissions.Permission; +import org.bukkit.permissions.PermissionAttachment; +import org.bukkit.permissions.PermissionAttachmentInfo; +import org.bukkit.plugin.Plugin; import org.powermock.api.mockito.PowerMockito; import java.io.File; import java.io.FileInputStream; import java.io.IOException; +import java.util.Set; import java.util.Timer; import java.util.TimerTask; import java.util.UUID; @@ -209,9 +217,138 @@ public class TestInit { when(mockServer.getMaxPlayers()).thenReturn(20); when(mockServer.getName()).thenReturn("Bukkit"); when(mockServer.getOfflinePlayers()).thenReturn(ops); + ConsoleCommandSender sender = mockServerCmdSender(); + when(mockServer.getConsoleSender()).thenReturn(sender); return mockServer; } + private ConsoleCommandSender mockServerCmdSender() { + return new ConsoleCommandSender() { + @Override + public void sendMessage(String s) { + System.out.println("Log: " + s); + } + + @Override + public void sendMessage(String[] strings) { + for (String string : strings) { + sendMessage(string); + } + + } + + @Override + public Server getServer() { + return null; + } + + @Override + public String getName() { + return null; + } + + @Override + public Spigot spigot() { + return null; + } + + @Override + public boolean isConversing() { + return false; + } + + @Override + public void acceptConversationInput(String s) { + + } + + @Override + public boolean beginConversation(Conversation conversation) { + return false; + } + + @Override + public void abandonConversation(Conversation conversation) { + + } + + @Override + public void abandonConversation(Conversation conversation, ConversationAbandonedEvent conversationAbandonedEvent) { + + } + + @Override + public void sendRawMessage(String s) { + + } + + @Override + public boolean isPermissionSet(String s) { + return false; + } + + @Override + public boolean isPermissionSet(Permission permission) { + return false; + } + + @Override + public boolean hasPermission(String s) { + return false; + } + + @Override + public boolean hasPermission(Permission permission) { + return false; + } + + @Override + public PermissionAttachment addAttachment(Plugin plugin, String s, boolean b) { + return null; + } + + @Override + public PermissionAttachment addAttachment(Plugin plugin) { + return null; + } + + @Override + public PermissionAttachment addAttachment(Plugin plugin, String s, boolean b, int i) { + return null; + } + + @Override + public PermissionAttachment addAttachment(Plugin plugin, int i) { + return null; + } + + @Override + public void removeAttachment(PermissionAttachment permissionAttachment) { + + } + + @Override + public void recalculatePermissions() { + + } + + @Override + public Set getEffectivePermissions() { + return null; + } + + @Override + public boolean isOp() { + return false; + } + + @Override + public void setOp(boolean b) { + + } + }; + } + private YamlConfiguration mockConfig() throws IOException, InvalidConfigurationException { File configFile = new File(getClass().getResource("/config.yml").getPath()); YamlConfiguration configuration = new YamlConfiguration();