From 3d6b4f6e2a5e2ab2c996355ecfec7316111ecaeb Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Tue, 2 Jan 2018 02:58:18 +0100 Subject: [PATCH] Added BridgePage for a HTTP tunnel @iiegit --- .classpath | 3 - .settings/org.eclipse.jdt.core.prefs | 100 ++++- pom.xml | 4 +- .../website/ButtonWebsiteModule.java | 1 + src/buttondevteam/website/io/IOHelper.java | 416 +++++++++--------- .../website/page/BridgePage.java | 92 ++++ 6 files changed, 403 insertions(+), 213 deletions(-) create mode 100644 src/buttondevteam/website/page/BridgePage.java diff --git a/.classpath b/.classpath index 8e97115..be86bf9 100644 --- a/.classpath +++ b/.classpath @@ -10,9 +10,6 @@ - - - diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs index 714351a..b45effd 100644 --- a/.settings/org.eclipse.jdt.core.prefs +++ b/.settings/org.eclipse.jdt.core.prefs @@ -1,5 +1,103 @@ eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled +org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore +org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull +org.eclipse.jdt.core.compiler.annotation.nonnull.secondary= +org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault +org.eclipse.jdt.core.compiler.annotation.nonnullbydefault.secondary= +org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable +org.eclipse.jdt.core.compiler.annotation.nullable.secondary= +org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 org.eclipse.jdt.core.compiler.compliance=1.8 -org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.problem.APILeak=warning +org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning +org.eclipse.jdt.core.compiler.problem.autoboxing=ignore +org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning +org.eclipse.jdt.core.compiler.problem.deadCode=warning +org.eclipse.jdt.core.compiler.problem.deprecation=warning +org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled +org.eclipse.jdt.core.compiler.problem.discouragedReference=warning +org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore +org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore +org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore +org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled +org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore +org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning +org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning +org.eclipse.jdt.core.compiler.problem.forbiddenReference=ignore +org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning +org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled +org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning +org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning +org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore +org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore +org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning +org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled +org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning +org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning +org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore +org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning +org.eclipse.jdt.core.compiler.problem.nonnullTypeVariableFromLegacyInvocation=warning +org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error +org.eclipse.jdt.core.compiler.problem.nullReference=warning +org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error +org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning +org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning +org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore +org.eclipse.jdt.core.compiler.problem.pessimisticNullAnalysisForFreeTypeVariables=warning +org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore +org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore +org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore +org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning +org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning +org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore +org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore +org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore +org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore +org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning +org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore +org.eclipse.jdt.core.compiler.problem.terminalDeprecation=warning +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentType=warning +org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentTypeStrict=disabled +org.eclipse.jdt.core.compiler.problem.unlikelyEqualsArgumentType=info +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled +org.eclipse.jdt.core.compiler.problem.unusedExceptionParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedImport=warning +org.eclipse.jdt.core.compiler.problem.unusedLabel=warning +org.eclipse.jdt.core.compiler.problem.unusedLocal=warning +org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning +org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning org.eclipse.jdt.core.compiler.source=1.8 diff --git a/pom.xml b/pom.xml index d9ed662..63f1ac6 100644 --- a/pom.xml +++ b/pom.xml @@ -88,8 +88,8 @@ org.spigotmc - spigot-api - 1.9.2-R0.1-SNAPSHOT + spigot + 1.12.2-R0.1-SNAPSHOT provided diff --git a/src/buttondevteam/website/ButtonWebsiteModule.java b/src/buttondevteam/website/ButtonWebsiteModule.java index 2b99f6e..0f1e1c4 100644 --- a/src/buttondevteam/website/ButtonWebsiteModule.java +++ b/src/buttondevteam/website/ButtonWebsiteModule.java @@ -125,6 +125,7 @@ public class ButtonWebsiteModule extends JavaPlugin { addPage(new LoginPage()); addPage(new ProfilePage()); addPage(new BuildNotificationsPage()); + addPage(new BridgePage()); TBMCCoreAPI.RegisterUserClass(WebUser.class); Bukkit.getScheduler().runTaskAsynchronously(this, () -> { this.getLogger().info("Starting webserver..."); diff --git a/src/buttondevteam/website/io/IOHelper.java b/src/buttondevteam/website/io/IOHelper.java index 723819c..77a6152 100644 --- a/src/buttondevteam/website/io/IOHelper.java +++ b/src/buttondevteam/website/io/IOHelper.java @@ -1,207 +1,209 @@ -package buttondevteam.website.io; - -import java.io.BufferedOutputStream; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; -import java.nio.charset.StandardCharsets; -import java.time.ZoneId; -import java.time.ZonedDateTime; -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; -import java.util.UUID; -import org.apache.commons.io.IOUtils; -import org.bukkit.Bukkit; - -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import com.sun.net.httpserver.HttpExchange; - -import buttondevteam.lib.player.ChromaGamerBase; -import buttondevteam.website.WebUser; - -public class IOHelper { - public static void SendResponse(Response resp) throws IOException { - SendResponse(resp.code, resp.content, resp.exchange); - } - - public static void SendResponse(int code, String content, HttpExchange exchange) throws IOException { - if (exchange.getRequestMethod().equalsIgnoreCase("HEAD")) { - exchange.sendResponseHeaders(code, 0); - exchange.getResponseBody().close(); - return; - } - try (BufferedOutputStream out = new BufferedOutputStream(exchange.getResponseBody())) { - try (ByteArrayInputStream bis = new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8))) { - try { - exchange.sendResponseHeaders(code, bis.available()); - } catch (IOException e) { - if (!e.getMessage().equals("headers already sent")) - throw e; // If an error occurs after sending the response headers send the error page even if the headers are for the original - } // This code will send *some page* (most likely an error page) with the original headers instead of failing to do anything - byte[] buffer = new byte[512]; - int count; - while ((count = bis.read(buffer)) != -1) { - out.write(buffer, 0, count); - } - } - } - exchange.getResponseBody().close(); - } - - public static String GetPOST(HttpExchange exchange) { - try { - if (exchange.getRequestBody().available() == 0) - return ""; - String content = IOUtils.toString(exchange.getRequestBody(), "UTF-8"); - return content; - } catch (Exception e) { - e.printStackTrace(); - return ""; - } - } - - public static JsonObject GetPOSTJSON(HttpExchange exchange) { - try { - String content = GetPOST(exchange); - if (content.length() == 0) - return null; - JsonElement e = new JsonParser().parse(content); - if (e == null) - return null; - JsonObject obj = e.getAsJsonObject(); - return obj; - } catch (Exception e) { - e.printStackTrace(); - return null; - } - } - - /** - * Sends login headers and sets the session id on the user - */ - public static void LoginUser(HttpExchange exchange, WebUser user) { - Bukkit.getLogger().fine("Logging in user: " + user); - user.sessionID().set(UUID.randomUUID()); - user.save(); - new Cookies(2).add(new Cookie("user_id", user.getUUID() + "")) - .add(new Cookie("session_id", user.sessionID().get().toString())).SendHeaders(exchange); - Bukkit.getLogger().fine("Logged in user."); - } - - public static void LogoutUser(HttpExchange exchange, WebUser user) { - user.sessionID().set(new UUID(0, 0)); - user.save(); - SendLogoutHeaders(exchange); - } - - private static void SendLogoutHeaders(HttpExchange exchange) { - String expiretime = "Sat, 19 Mar 2016 23:33:00 GMT"; - new Cookies(expiretime).add(new Cookie("user_id", "del")).add(new Cookie("session_id", "del")) - .SendHeaders(exchange); - } - - public static Response Redirect(String url, HttpExchange exchange) throws IOException { - exchange.getResponseHeaders().add("Location", url); - return new Response(303, "If you can see this, click here to continue", exchange); - } - - public static Cookies GetCookies(HttpExchange exchange) { - if (!exchange.getRequestHeaders().containsKey("Cookie")) - return new Cookies(); - Map map = new HashMap<>(); - for (String cheader : exchange.getRequestHeaders().get("Cookie")) { - String[] spl = cheader.split("\\;\\s*"); - for (String s : spl) { - String[] kv = s.split("\\="); - if (kv.length < 2) - continue; - map.put(kv[0], kv[1]); - } - } - if (!map.containsKey("expiretime")) - return new Cookies(); - Cookies cookies = null; - try { - cookies = new Cookies(map.get("expiretime")); - for (Entry item : map.entrySet()) - if (!item.getKey().equalsIgnoreCase("expiretime")) - cookies.put(item.getKey(), new Cookie(item.getKey(), item.getValue())); - } catch (Exception e) { - return new Cookies(); - } - return cookies; - } - - /** - * Get logged in user. It may also send logout headers if the cookies are invalid, or login headers to keep the user logged in. Make sure to save the user data. - * - * @param exchange - * @return The logged in user or null if not logged in. - * @throws IOException - */ - public static WebUser GetLoggedInUser(HttpExchange exchange) throws IOException { - Cookies cookies = GetCookies(exchange); - if (!cookies.containsKey("user_id") || !cookies.containsKey("session_id")) - return null; - WebUser user = ChromaGamerBase.getUser(cookies.get("user_id").getValue(), WebUser.class); - if (user != null && cookies.get("session_id") != null - && cookies.get("session_id").getValue().equals(user.sessionID().get().toString())) { - if (cookies.getExpireTimeParsed().minusYears(1).isBefore(ZonedDateTime.now(ZoneId.of("GMT")))) - LoginUser(exchange, user); - return user; - } else - SendLogoutHeaders(exchange); - return null; - } - - public static Map parseQueryString(HttpExchange exchange) { - String qs = exchange.getRequestURI().getRawQuery(); - Map result = new HashMap<>(); - if (qs == null) - return result; - - int last = 0, next, l = qs.length(); - while (last < l) { - next = qs.indexOf('&', last); - if (next == -1) - next = l; - - if (next > last) { - int eqPos = qs.indexOf('=', last); - try { - if (eqPos < 0 || eqPos > next) - result.put(URLDecoder.decode(qs.substring(last, next), "utf-8"), ""); - else - result.put(URLDecoder.decode(qs.substring(last, eqPos), "utf-8"), - URLDecoder.decode(qs.substring(eqPos + 1, next), "utf-8")); - } catch (UnsupportedEncodingException e) { - throw new RuntimeException(e); // will never happen, utf-8 support is mandatory for java - } - } - last = next + 1; - } - return result; - } - - public static HashMap GetPOSTKeyValues(HttpExchange exchange) { - try { - String[] content = GetPOST(exchange).split("\\&"); - HashMap vars = new HashMap<>(); - for (String var : content) { - String[] spl = var.split("\\="); - if (spl.length == 1) - vars.put(spl[0], ""); - else - vars.put(spl[0], URLDecoder.decode(spl[1], "utf-8")); - } - return vars; - } catch (Exception e) { - e.printStackTrace(); - return new HashMap<>(); - } - } -} +package buttondevteam.website.io; + +import java.io.BufferedOutputStream; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.UUID; +import org.apache.commons.io.IOUtils; +import org.bukkit.Bukkit; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.sun.net.httpserver.HttpExchange; + +import buttondevteam.lib.player.ChromaGamerBase; +import buttondevteam.website.WebUser; + +public class IOHelper { + public static void SendResponse(Response resp) throws IOException { + if (resp == null) + return; // Response is already sent + SendResponse(resp.code, resp.content, resp.exchange); + } + + public static void SendResponse(int code, String content, HttpExchange exchange) throws IOException { + if (exchange.getRequestMethod().equalsIgnoreCase("HEAD")) { + exchange.sendResponseHeaders(code, 0); + exchange.getResponseBody().close(); + return; + } + try (BufferedOutputStream out = new BufferedOutputStream(exchange.getResponseBody())) { + try (ByteArrayInputStream bis = new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8))) { + try { + exchange.sendResponseHeaders(code, bis.available()); + } catch (IOException e) { + if (!e.getMessage().equals("headers already sent")) + throw e; // If an error occurs after sending the response headers send the error page even if the headers are for the original + } // This code will send *some page* (most likely an error page) with the original headers instead of failing to do anything + byte[] buffer = new byte[512]; + int count; + while ((count = bis.read(buffer)) != -1) { + out.write(buffer, 0, count); + } + } + } + exchange.getResponseBody().close(); + } + + public static String GetPOST(HttpExchange exchange) { + try { + if (exchange.getRequestBody().available() == 0) + return ""; + String content = IOUtils.toString(exchange.getRequestBody(), "UTF-8"); + return content; + } catch (Exception e) { + e.printStackTrace(); + return ""; + } + } + + public static JsonObject GetPOSTJSON(HttpExchange exchange) { + try { + String content = GetPOST(exchange); + if (content.length() == 0) + return null; + JsonElement e = new JsonParser().parse(content); + if (e == null) + return null; + JsonObject obj = e.getAsJsonObject(); + return obj; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + /** + * Sends login headers and sets the session id on the user + */ + public static void LoginUser(HttpExchange exchange, WebUser user) { + Bukkit.getLogger().fine("Logging in user: " + user); + user.sessionID().set(UUID.randomUUID()); + user.save(); + new Cookies(2).add(new Cookie("user_id", user.getUUID() + "")) + .add(new Cookie("session_id", user.sessionID().get().toString())).SendHeaders(exchange); + Bukkit.getLogger().fine("Logged in user."); + } + + public static void LogoutUser(HttpExchange exchange, WebUser user) { + user.sessionID().set(new UUID(0, 0)); + user.save(); + SendLogoutHeaders(exchange); + } + + private static void SendLogoutHeaders(HttpExchange exchange) { + String expiretime = "Sat, 19 Mar 2016 23:33:00 GMT"; + new Cookies(expiretime).add(new Cookie("user_id", "del")).add(new Cookie("session_id", "del")) + .SendHeaders(exchange); + } + + public static Response Redirect(String url, HttpExchange exchange) throws IOException { + exchange.getResponseHeaders().add("Location", url); + return new Response(303, "If you can see this, click here to continue", exchange); + } + + public static Cookies GetCookies(HttpExchange exchange) { + if (!exchange.getRequestHeaders().containsKey("Cookie")) + return new Cookies(); + Map map = new HashMap<>(); + for (String cheader : exchange.getRequestHeaders().get("Cookie")) { + String[] spl = cheader.split("\\;\\s*"); + for (String s : spl) { + String[] kv = s.split("\\="); + if (kv.length < 2) + continue; + map.put(kv[0], kv[1]); + } + } + if (!map.containsKey("expiretime")) + return new Cookies(); + Cookies cookies = null; + try { + cookies = new Cookies(map.get("expiretime")); + for (Entry item : map.entrySet()) + if (!item.getKey().equalsIgnoreCase("expiretime")) + cookies.put(item.getKey(), new Cookie(item.getKey(), item.getValue())); + } catch (Exception e) { + return new Cookies(); + } + return cookies; + } + + /** + * Get logged in user. It may also send logout headers if the cookies are invalid, or login headers to keep the user logged in. Make sure to save the user data. + * + * @param exchange + * @return The logged in user or null if not logged in. + * @throws IOException + */ + public static WebUser GetLoggedInUser(HttpExchange exchange) throws IOException { + Cookies cookies = GetCookies(exchange); + if (!cookies.containsKey("user_id") || !cookies.containsKey("session_id")) + return null; + WebUser user = ChromaGamerBase.getUser(cookies.get("user_id").getValue(), WebUser.class); + if (user != null && cookies.get("session_id") != null + && cookies.get("session_id").getValue().equals(user.sessionID().get().toString())) { + if (cookies.getExpireTimeParsed().minusYears(1).isBefore(ZonedDateTime.now(ZoneId.of("GMT")))) + LoginUser(exchange, user); + return user; + } else + SendLogoutHeaders(exchange); + return null; + } + + public static Map parseQueryString(HttpExchange exchange) { + String qs = exchange.getRequestURI().getRawQuery(); + Map result = new HashMap<>(); + if (qs == null) + return result; + + int last = 0, next, l = qs.length(); + while (last < l) { + next = qs.indexOf('&', last); + if (next == -1) + next = l; + + if (next > last) { + int eqPos = qs.indexOf('=', last); + try { + if (eqPos < 0 || eqPos > next) + result.put(URLDecoder.decode(qs.substring(last, next), "utf-8"), ""); + else + result.put(URLDecoder.decode(qs.substring(last, eqPos), "utf-8"), + URLDecoder.decode(qs.substring(eqPos + 1, next), "utf-8")); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); // will never happen, utf-8 support is mandatory for java + } + } + last = next + 1; + } + return result; + } + + public static HashMap GetPOSTKeyValues(HttpExchange exchange) { + try { + String[] content = GetPOST(exchange).split("\\&"); + HashMap vars = new HashMap<>(); + for (String var : content) { + String[] spl = var.split("\\="); + if (spl.length == 1) + vars.put(spl[0], ""); + else + vars.put(spl[0], URLDecoder.decode(spl[1], "utf-8")); + } + return vars; + } catch (Exception e) { + e.printStackTrace(); + return new HashMap<>(); + } + } +} diff --git a/src/buttondevteam/website/page/BridgePage.java b/src/buttondevteam/website/page/BridgePage.java new file mode 100644 index 0000000..2d2b272 --- /dev/null +++ b/src/buttondevteam/website/page/BridgePage.java @@ -0,0 +1,92 @@ +package buttondevteam.website.page; + +import java.io.IOException; +import java.net.Socket; +import java.util.HashMap; +import java.util.Map; + +import org.apache.commons.io.IOUtils; +import org.bukkit.Bukkit; + +import com.sun.net.httpserver.HttpExchange; + +import buttondevteam.website.io.Response; + +public class BridgePage extends Page { + private Map connections = new HashMap<>(); + + @Override + public String GetName() { + return "bridge"; + } + + @Override + public Response handlePage(HttpExchange exchange) { + String method = exchange.getRequestMethod().toUpperCase(); + String id = getConnID(exchange); + if (id == null) + return new Response(400, "No ID", exchange); + try { + Socket s; + switch (method) { + case "POST": + if (connections.containsKey(id)) + connections.get(id).close(); + Socket socket = new Socket("localhost", Bukkit.getPort()); + socket.setKeepAlive(true); + socket.setTcpNoDelay(true); + connections.put(id, socket); + return new Response(201, "", exchange); + case "PUT": + s = getSocket(exchange); + if (s == null) + return new Response(400, "No connection", exchange); + IOUtils.copy(exchange.getRequestBody(), s.getOutputStream()); + return new Response(200, "OK", exchange); + case "GET": + s = getSocket(exchange); + if (s == null) + return new Response(400, "No connection", exchange); + IOUtils.copy(s.getInputStream(), exchange.getResponseBody()); + exchange.getResponseBody().close(); // TODO: Keep open? + return null; // Response already sen + case "DELETE": + closeSocket(exchange); + return new Response(200, "OK", exchange); + default: + return new Response(403, "Unknown request", exchange); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private Socket getSocket(HttpExchange exchange) { + String id = getConnID(exchange); + if (id == null) + return null; + return connections.get(id); + } + + private String getConnID(HttpExchange exchange) { + String path = exchange.getRequestURI().getPath(); + if (path == null) + return null; + String[] spl = path.split("/"); + if (spl.length < 2) + return null; + return spl[spl.length - 1]; + } + + private void closeSocket(HttpExchange exchange) { + Socket socket = getSocket(exchange); + if (socket == null) + return; + try { + socket.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } + connections.values().remove(socket); + } +}