diff --git a/src/main/java/ch/fritteli/labyrinth/server/LabyrinthServer.java b/src/main/java/ch/fritteli/labyrinth/server/LabyrinthServer.java
index 09ed5fc..f0f0321 100644
--- a/src/main/java/ch/fritteli/labyrinth/server/LabyrinthServer.java
+++ b/src/main/java/ch/fritteli/labyrinth/server/LabyrinthServer.java
@@ -45,7 +45,7 @@ public class LabyrinthServer {
private void start() {
Runtime.getRuntime().addShutdownHook(new Thread(this::stop, "listener-stopper"));
this.undertow.start();
- log.info("Listeing on http://{}:{}", this.config.getAddress().getHostAddress(), this.config.getPort());
+ log.info("Listening on http://{}:{}", this.config.getAddress().getHostAddress(), this.config.getPort());
}
private void stop() {
@@ -53,48 +53,4 @@ public class LabyrinthServer {
this.undertow.stop();
log.info("Server stopped.");
}
-
-// private void handleRender(final HttpExchange exchange) {
-// this.executorService.submit(() -> {
-// 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();
-//
-// final Labyrinth labyrinth = SerializerDeserializer.deserialize(bytes);
-//
-// final OutputType output = exchange.getRequestHeaders()
-// .get("Accept")
-// .contains(OutputType.HTML.getContentType()) ?
-// 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();
-// } catch (Exception e) {
-// log.error("FSCK!", e);
-// } finally {
-// exchange.close();
-// }
-// });
-// }
}
diff --git a/src/main/java/ch/fritteli/labyrinth/server/handler/AbstractHttpHandler.java b/src/main/java/ch/fritteli/labyrinth/server/handler/AbstractHttpHandler.java
index 384ecc2..198c7a4 100644
--- a/src/main/java/ch/fritteli/labyrinth/server/handler/AbstractHttpHandler.java
+++ b/src/main/java/ch/fritteli/labyrinth/server/handler/AbstractHttpHandler.java
@@ -7,13 +7,17 @@ import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
+import java.time.Instant;
+import java.time.temporal.ChronoUnit;
import java.util.UUID;
@Slf4j
public abstract class AbstractHttpHandler implements HttpHandler {
@Override
public final void handleRequest(@NonNull final HttpServerExchange exchange) {
- try (final MDC.MDCCloseable mdc = MDC.putCloseable("correlationId", UUID.randomUUID().toString())) {
+ final Instant start = Instant.now();
+ try (final MDC.MDCCloseable closeable = MDC.putCloseable("correlationId", UUID.randomUUID().toString())) {
+
if (exchange.isInIoThread()) {
log.debug("Dispatching request");
exchange.dispatch(this);
@@ -27,6 +31,7 @@ public abstract class AbstractHttpHandler implements HttpHandler {
.getResponseSender()
.send(StatusCodes.INTERNAL_SERVER_ERROR_STRING);
}
+ log.debug("Completed request in {}ms.", start.until(Instant.now(), ChronoUnit.MILLIS));
}
}
diff --git a/src/main/java/ch/fritteli/labyrinth/server/handler/RenderHandler.java b/src/main/java/ch/fritteli/labyrinth/server/handler/RenderHandler.java
index a440b90..c5e47d9 100644
--- a/src/main/java/ch/fritteli/labyrinth/server/handler/RenderHandler.java
+++ b/src/main/java/ch/fritteli/labyrinth/server/handler/RenderHandler.java
@@ -1,17 +1,49 @@
package ch.fritteli.labyrinth.server.handler;
+import ch.fritteli.labyrinth.generator.model.Labyrinth;
+import ch.fritteli.labyrinth.generator.serialization.SerializerDeserializer;
+import ch.fritteli.labyrinth.server.OutputType;
import io.undertow.server.HttpHandler;
import io.undertow.server.HttpServerExchange;
+import io.undertow.util.Headers;
import io.undertow.util.StatusCodes;
+import io.vavr.control.Option;
+import lombok.extern.slf4j.Slf4j;
+import java.nio.ByteBuffer;
+
+@Slf4j
public class RenderHandler implements HttpHandler {
@Override
public void handleRequest(final HttpServerExchange exchange) {
+ log.debug("Handling render request");
+
if (exchange.isInIoThread()) {
exchange.dispatch(this);
return;
}
- exchange.setStatusCode(StatusCodes.NOT_IMPLEMENTED);
- exchange.getResponseSender().send("Rendering binary data is not implemented yet.");
+ exchange.getRequestReceiver().receiveFullBytes((httpServerExchange, bytes) -> {
+ final Labyrinth labyrinth = SerializerDeserializer.deserialize(bytes);
+ final OutputType output = Option.of(httpServerExchange.getRequestHeaders().get(Headers.ACCEPT))
+ .exists(values -> values.contains(OutputType.HTML.getContentType())) ?
+ OutputType.HTML :
+ OutputType.TEXT_PLAIN;
+ final byte[] render;
+ try {
+ render = output.render(labyrinth);
+ } catch (final Exception e) {
+ log.error("Error rendering binary labyrinth data", e);
+ httpServerExchange.setStatusCode(StatusCodes.INTERNAL_SERVER_ERROR)
+ .getResponseSender()
+ .send("Error rendering labyrinth: %s".formatted(e.getMessage()));
+ return;
+ }
+ httpServerExchange
+ .setStatusCode(StatusCodes.OK)
+ .getResponseHeaders()
+ .put(Headers.CONTENT_TYPE, output.getContentType());
+ httpServerExchange.getResponseSender()
+ .send(ByteBuffer.wrap(render));
+ });
}
}
diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml
index 6cec730..69dd770 100644
--- a/src/main/resources/logback.xml
+++ b/src/main/resources/logback.xml
@@ -13,5 +13,7 @@
+
+