From cd29c6fe7508b1b9c3ac8e226e39ec7c327837a7 Mon Sep 17 00:00:00 2001 From: Manuel Friedli Date: Fri, 12 Feb 2021 02:44:32 +0100 Subject: [PATCH] Render binary data uploaded to /render via POST. --- labyrinth-server.iml | 2 +- pom.xml | 2 +- .../labyrinth/server/LabyrinthServer.java | 61 ++++++++++++++++++- 3 files changed, 61 insertions(+), 4 deletions(-) diff --git a/labyrinth-server.iml b/labyrinth-server.iml index 8d460f3..9a37eeb 100644 --- a/labyrinth-server.iml +++ b/labyrinth-server.iml @@ -12,7 +12,7 @@ - + diff --git a/pom.xml b/pom.xml index b18d2cf..3a3f0b1 100644 --- a/pom.xml +++ b/pom.xml @@ -18,7 +18,7 @@ ch.fritteli.labyrinth labyrinth-generator - 0.0.1 + 0.0.2-SNAPSHOT io.vavr diff --git a/src/main/java/ch/fritteli/labyrinth/server/LabyrinthServer.java b/src/main/java/ch/fritteli/labyrinth/server/LabyrinthServer.java index bcb6bd4..7ffb589 100644 --- a/src/main/java/ch/fritteli/labyrinth/server/LabyrinthServer.java +++ b/src/main/java/ch/fritteli/labyrinth/server/LabyrinthServer.java @@ -4,10 +4,16 @@ import ch.fritteli.labyrinth.generator.model.Labyrinth; import ch.fritteli.labyrinth.generator.renderer.html.HTMLRenderer; import ch.fritteli.labyrinth.generator.renderer.pdf.PDFRenderer; import ch.fritteli.labyrinth.generator.renderer.text.TextRenderer; +import ch.fritteli.labyrinth.generator.serialization.SerializerDeserializer; import com.sun.net.httpserver.Headers; import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpServer; -import io.vavr.collection.*; +import io.vavr.collection.HashMap; +import io.vavr.collection.HashSet; +import io.vavr.collection.List; +import io.vavr.collection.Map; +import io.vavr.collection.Set; +import io.vavr.collection.Stream; import io.vavr.control.Option; import io.vavr.control.Try; import lombok.Getter; @@ -28,7 +34,12 @@ public class LabyrinthServer { public LabyrinthServer(@NonNull final ServerConfig config) throws IOException { this.httpServer = HttpServer.create(new InetSocketAddress(config.getAddress(), config.getPort()), 5); + this.httpServer.createContext("/", exchange -> { + exchange.getResponseHeaders().add("Location", "/create"); + exchange.sendResponseHeaders(302, -1); + }); this.httpServer.createContext("/create", this::handleCreate); + this.httpServer.createContext("/render", this::handleRender); } public static Option createAndStartServer() { @@ -131,6 +142,51 @@ public class LabyrinthServer { exchange.close(); } + private void handleRender(final HttpExchange exchange) throws IOException { + try { + log.debug("Handling request to {}", exchange.getRequestURI()); + final String requestMethod = exchange.getRequestMethod(); + if (!requestMethod.equals("POST")) { + exchange.getResponseBody().close(); + exchange.sendResponseHeaders(405, -1); + return; + } + final byte[] bytes = exchange.getRequestBody().readAllBytes(); + @NonNull final Labyrinth labyrinth; + try { + labyrinth = SerializerDeserializer.deserialize(bytes); + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + + OutputType output = exchange.getRequestHeaders() + .get("Accept") + .contains("text/html") ? + OutputType.HTML : + OutputType.TEXT_PLAIN; + final byte[] render; + final Headers responseHeaders = exchange.getResponseHeaders(); + try { + render = output.render(labyrinth); + } catch (Exception e) { + responseHeaders.add("Content-type", "text/plain; charset=UTF-8"); + exchange.sendResponseHeaders(500, 0); + final OutputStream responseBody = exchange.getResponseBody(); + responseBody.write(("Error: " + e).getBytes(StandardCharsets.UTF_8)); + responseBody.flush(); + return; + } + responseHeaders.add("Content-type", output.getContentType()); + exchange.sendResponseHeaders(200, 0); + final OutputStream responseBody = exchange.getResponseBody(); + responseBody.write(render); + responseBody.flush(); + } finally { + exchange.close(); + } + } + private enum RequestParameter { WIDTH("w", "width"), HEIGHT("h", "height"), @@ -154,7 +210,8 @@ public class LabyrinthServer { private enum OutputType { TEXT_PLAIN("text/plain; charset=UTF-8", labyrinth -> TextRenderer.newInstance().render(labyrinth).getBytes(StandardCharsets.UTF_8), "t", "text"), HTML("text/html", labyrinth -> HTMLRenderer.newInstance().render(labyrinth).getBytes(StandardCharsets.UTF_8), "h", "html"), - PDF("application/pdf", labyrinth -> PDFRenderer.newInstance().render(labyrinth), "p", "pdf"); + PDF("application/pdf", labyrinth -> PDFRenderer.newInstance().render(labyrinth), "p", "pdf"), + BINARY("application/octet-stream", SerializerDeserializer::serialize, "b", "binary"); @Getter @NonNull private final String contentType;