feature/undertow #4
6 changed files with 202 additions and 191 deletions
|
@ -1,10 +1,11 @@
|
||||||
package ch.fritteli.labyrinth.server;
|
package ch.fritteli.labyrinth.server;
|
||||||
|
|
||||||
import ch.fritteli.labyrinth.generator.model.Labyrinth;
|
import ch.fritteli.labyrinth.server.handler.CreateHandler;
|
||||||
import ch.fritteli.labyrinth.generator.serialization.SerializerDeserializer;
|
import ch.fritteli.labyrinth.server.undertow_playground.LanyrinthRenderHandler;
|
||||||
import com.sun.net.httpserver.Headers;
|
import io.undertow.Undertow;
|
||||||
import com.sun.net.httpserver.HttpExchange;
|
import io.undertow.server.RoutingHandler;
|
||||||
import com.sun.net.httpserver.HttpServer;
|
import io.undertow.server.handlers.RedirectHandler;
|
||||||
|
import io.undertow.util.StatusCodes;
|
||||||
import io.vavr.collection.HashMap;
|
import io.vavr.collection.HashMap;
|
||||||
import io.vavr.collection.HashSet;
|
import io.vavr.collection.HashSet;
|
||||||
import io.vavr.collection.Map;
|
import io.vavr.collection.Map;
|
||||||
|
@ -16,28 +17,13 @@ import lombok.NonNull;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.SynchronousQueue;
|
|
||||||
import java.util.concurrent.ThreadPoolExecutor;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class LabyrinthServer {
|
public class LabyrinthServer {
|
||||||
@NonNull
|
@NonNull
|
||||||
private final HttpServer httpServer;
|
private final Undertow undertow;
|
||||||
@NonNull
|
|
||||||
private final ExecutorService executorService = new ThreadPoolExecutor(0,
|
|
||||||
1_000,
|
|
||||||
5,
|
|
||||||
TimeUnit.SECONDS,
|
|
||||||
new SynchronousQueue<>()
|
|
||||||
);
|
|
||||||
|
|
||||||
public static Option<LabyrinthServer> createAndStartServer() {
|
public static Option<LabyrinthServer> createAndStartServer() {
|
||||||
final Option<LabyrinthServer> serverOption = Try.of(ServerConfig::init)
|
final Option<LabyrinthServer> serverOption = Try.of(ServerConfig::init)
|
||||||
|
@ -51,147 +37,106 @@ public class LabyrinthServer {
|
||||||
return serverOption;
|
return serverOption;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LabyrinthServer(@NonNull final ServerConfig config) throws IOException {
|
public LabyrinthServer(@NonNull final ServerConfig config) {
|
||||||
this.httpServer = HttpServer.create(new InetSocketAddress(config.getAddress(), config.getPort()), 5);
|
log.info("Starting Server at http://{}:{}/", config.getAddress().getHostAddress(), config.getPort());
|
||||||
this.httpServer.createContext("/", new StaticResourcesFileHandler(this.executorService));
|
final RoutingHandler routingHandler = new RoutingHandler().get("/", new RedirectHandler("/create/text"))
|
||||||
this.httpServer.createContext("/create", this::handleCreate);
|
.get("/create", new RedirectHandler("/create/text"))
|
||||||
this.httpServer.createContext("/render", this::handleRender);
|
.get("/create/{output}", new CreateHandler())
|
||||||
|
.post("/render", new LanyrinthRenderHandler())
|
||||||
|
.setFallbackHandler(exchange -> {
|
||||||
|
exchange.setStatusCode(StatusCodes.NOT_FOUND)
|
||||||
|
.getResponseSender()
|
||||||
|
.send("Resource %s not found".formatted(
|
||||||
|
exchange.getRequestURI()));
|
||||||
|
});
|
||||||
|
this.undertow = Undertow.builder()
|
||||||
|
.addHttpListener(config.getPort(), config.getAddress().getHostAddress())
|
||||||
|
.setHandler(routingHandler)
|
||||||
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void start() {
|
public void start() {
|
||||||
Runtime.getRuntime().addShutdownHook(new Thread(this::stop, "listener-stopper"));
|
Runtime.getRuntime().addShutdownHook(new Thread(this::stop, "listener-stopper"));
|
||||||
this.httpServer.start();
|
this.undertow.start();
|
||||||
log.info("Listening on http://{}:{}",
|
Try.of(() -> (InetSocketAddress) this.undertow.getListenerInfo().get(0).getAddress())
|
||||||
this.httpServer.getAddress().getHostString(),
|
.onFailure(e -> log.warn("Started server, unable to determine listeing address/port."))
|
||||||
this.httpServer.getAddress().getPort()
|
.forEach(address -> log.info("Listening on http://{}:{}", address.getHostString(), address.getPort()));
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleCreate(HttpExchange exchange) {
|
|
||||||
this.executorService.submit(() -> {
|
|
||||||
log.debug("Handling request to {}", exchange.getRequestURI());
|
|
||||||
try {
|
|
||||||
final String requestMethod = exchange.getRequestMethod();
|
|
||||||
if (!requestMethod.equals("GET")) {
|
|
||||||
exchange.getResponseBody().close();
|
|
||||||
exchange.sendResponseHeaders(405, -1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final Map<RequestParameter, String> requestParams = this.parseQueryString(exchange.getRequestURI()
|
|
||||||
.getQuery());
|
|
||||||
final int width = this.getOrDefault(requestParams.get(RequestParameter.WIDTH), Integer::valueOf, 5);
|
|
||||||
final int height = this.getOrDefault(requestParams.get(RequestParameter.HEIGHT), Integer::valueOf, 7);
|
|
||||||
final Option<Long> idOption = requestParams.get(RequestParameter.ID)
|
|
||||||
.toTry()
|
|
||||||
.map(Long::valueOf)
|
|
||||||
.toOption();
|
|
||||||
final Option<OutputType> outputOption = requestParams.get(RequestParameter.OUTPUT)
|
|
||||||
.flatMap(OutputType::ofString);
|
|
||||||
final Headers responseHeaders = exchange.getResponseHeaders();
|
|
||||||
final AtomicBoolean needsRedirect = new AtomicBoolean(false);
|
|
||||||
final long id = idOption.onEmpty(() -> needsRedirect.set(true)).getOrElse(System::nanoTime);
|
|
||||||
final OutputType output = outputOption.onEmpty(() -> needsRedirect.set(true))
|
|
||||||
.getOrElse(OutputType.HTML);
|
|
||||||
if (needsRedirect.get()) {
|
|
||||||
responseHeaders.add("Location",
|
|
||||||
"create?width=" + width + "&height=" + height + "&output=" + output.toString() +
|
|
||||||
"&id=" + id
|
|
||||||
);
|
|
||||||
exchange.sendResponseHeaders(302, -1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final byte[] render;
|
|
||||||
try {
|
|
||||||
final Labyrinth labyrinth = new Labyrinth(width, height, id);
|
|
||||||
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.getMessage()).getBytes(StandardCharsets.UTF_8));
|
|
||||||
responseBody.flush();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
responseHeaders.add("Content-type", output.getContentType());
|
|
||||||
if (output.isAttachment()) {
|
|
||||||
responseHeaders.add("Content-disposition", String.format(
|
|
||||||
"attachment; filename=\"labyrinth-%dx%d-%d.%s\"",
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
id,
|
|
||||||
output.getFileExtension()
|
|
||||||
));
|
|
||||||
}
|
|
||||||
exchange.sendResponseHeaders(200, 0);
|
|
||||||
final OutputStream responseBody = exchange.getResponseBody();
|
|
||||||
responseBody.write(render);
|
|
||||||
responseBody.flush();
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("FSCK!", e);
|
|
||||||
} finally {
|
|
||||||
exchange.close();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stop() {
|
public void stop() {
|
||||||
log.info("Stopping server ...");
|
log.info("Stopping server ...");
|
||||||
this.httpServer.stop(5);
|
this.undertow.stop();
|
||||||
this.executorService.shutdown();
|
|
||||||
try {
|
|
||||||
if (!this.executorService.awaitTermination(5, TimeUnit.SECONDS)) {
|
|
||||||
log.warn("Timeout occurred while awaiting termination of executor service");
|
|
||||||
}
|
|
||||||
} catch (final InterruptedException e) {
|
|
||||||
log.error("Failed to await termination of executor service", e);
|
|
||||||
}
|
|
||||||
log.info("Server stopped.");
|
log.info("Server stopped.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// private void handleCreate(HttpExchange exchange) {
|
||||||
|
// this.executorService.submit(() -> {
|
||||||
|
// log.debug("Handling request to {}", exchange.getRequestURI());
|
||||||
|
// try {
|
||||||
|
// final String requestMethod = exchange.getRequestMethod();
|
||||||
|
// if (!requestMethod.equals("GET")) {
|
||||||
|
// exchange.getResponseBody().close();
|
||||||
|
// exchange.sendResponseHeaders(405, -1);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// final Map<RequestParameter, String> requestParams = this.parseQueryString(exchange.getRequestURI()
|
||||||
|
// .getQuery());
|
||||||
|
// final int width = this.getOrDefault(requestParams.get(RequestParameter.WIDTH), Integer::valueOf, 5);
|
||||||
|
// final int height = this.getOrDefault(requestParams.get(RequestParameter.HEIGHT), Integer::valueOf, 7);
|
||||||
|
// final Option<Long> idOption = requestParams.get(RequestParameter.ID)
|
||||||
|
// .toTry()
|
||||||
|
// .map(Long::valueOf)
|
||||||
|
// .toOption();
|
||||||
|
// final Option<OutputType> outputOption = requestParams.get(RequestParameter.OUTPUT)
|
||||||
|
// .flatMap(OutputType::ofString);
|
||||||
|
// final Headers responseHeaders = exchange.getResponseHeaders();
|
||||||
|
// final AtomicBoolean needsRedirect = new AtomicBoolean(false);
|
||||||
|
// final long id = idOption.onEmpty(() -> needsRedirect.set(true)).getOrElse(System::nanoTime);
|
||||||
|
// final OutputType output = outputOption.onEmpty(() -> needsRedirect.set(true))
|
||||||
|
// .getOrElse(OutputType.HTML);
|
||||||
|
// if (needsRedirect.get()) {
|
||||||
|
// responseHeaders.add("Location",
|
||||||
|
// "create?width=" + width + "&height=" + height + "&output=" + output
|
||||||
|
// .toString() +
|
||||||
|
// "&id=" + id
|
||||||
|
// );
|
||||||
|
// exchange.sendResponseHeaders(302, -1);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// final byte[] render;
|
||||||
|
// try {
|
||||||
|
// final Labyrinth labyrinth = new Labyrinth(width, height, id);
|
||||||
|
// 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.getMessage()).getBytes(StandardCharsets.UTF_8));
|
||||||
|
// responseBody.flush();
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// responseHeaders.add("Content-type", output.getContentType());
|
||||||
|
// if (output.isAttachment()) {
|
||||||
|
// responseHeaders.add("Content-disposition", String.format(
|
||||||
|
// "attachment; filename=\"labyrinth-%dx%d-%d.%s\"",
|
||||||
|
// width,
|
||||||
|
// height,
|
||||||
|
// id,
|
||||||
|
// output.getFileExtension()
|
||||||
|
// ));
|
||||||
|
// }
|
||||||
|
// exchange.sendResponseHeaders(200, 0);
|
||||||
|
// final OutputStream responseBody = exchange.getResponseBody();
|
||||||
|
// responseBody.write(render);
|
||||||
|
// responseBody.flush();
|
||||||
|
// } catch (Exception e) {
|
||||||
|
// log.error("FSCK!", e);
|
||||||
|
// } finally {
|
||||||
|
// exchange.close();
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
private Map<RequestParameter, String> parseQueryString(@Nullable final String query) {
|
private Map<RequestParameter, String> parseQueryString(@Nullable final String query) {
|
||||||
if (query == null) {
|
if (query == null) {
|
||||||
|
@ -218,15 +163,59 @@ public class LabyrinthServer {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private RequestParameter normalizeParameterName(final String paramName) {
|
||||||
|
return RequestParameter.parseName(paramName).get();
|
||||||
|
}
|
||||||
|
|
||||||
private <T> T getOrDefault(@NonNull final Option<String> input,
|
private <T> T getOrDefault(@NonNull final Option<String> input,
|
||||||
@NonNull final Function<String, T> mapper,
|
@NonNull final Function<String, T> mapper,
|
||||||
@Nullable final T defaultValue) {
|
@Nullable final T defaultValue) {
|
||||||
return input.toTry().map(mapper).getOrElse(defaultValue);
|
return input.toTry().map(mapper).getOrElse(defaultValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
private RequestParameter normalizeParameterName(final String paramName) {
|
// private void handleRender(final HttpExchange exchange) {
|
||||||
return RequestParameter.parseName(paramName).get();
|
// 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();
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
private enum RequestParameter {
|
private enum RequestParameter {
|
||||||
WIDTH("w", "width"),
|
WIDTH("w", "width"),
|
||||||
|
|
|
@ -1,21 +1,18 @@
|
||||||
package ch.fritteli.labyrinth.server;
|
package ch.fritteli.labyrinth.server;
|
||||||
|
|
||||||
import ch.fritteli.labyrinth.server.undertow_playground.UndertowPlayground;
|
|
||||||
import io.undertow.Undertow;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class Main {
|
public class Main {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
// LabyrinthServer.createAndStartServer()
|
LabyrinthServer.createAndStartServer().onEmpty(() -> log.error("Failed to create server. Stopping."));
|
||||||
// .onEmpty(() -> log.error("Failed to create server. Stopping."));
|
|
||||||
|
|
||||||
final ServerConfig config = ServerConfig.init();
|
// final ServerConfig config = ServerConfig.init();
|
||||||
log.info("Starting Server at http://{}:{}/", config.getAddress().getHostAddress(), config.getPort());
|
// log.info("Starting Server at http://{}:{}/", config.getAddress().getHostAddress(), config.getPort());
|
||||||
Undertow.builder()
|
// Undertow.builder()
|
||||||
.addHttpListener(config.getPort(), config.getAddress().getHostAddress())
|
// .addHttpListener(config.getPort(), config.getAddress().getHostAddress())
|
||||||
.setHandler(UndertowPlayground.r)
|
// .setHandler(UndertowPlayground.r)
|
||||||
.build()
|
// .build()
|
||||||
.start();
|
// .start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
package ch.fritteli.labyrinth.server.handler;
|
||||||
|
|
||||||
|
import io.undertow.server.HttpHandler;
|
||||||
|
import io.undertow.server.HttpServerExchange;
|
||||||
|
import io.undertow.util.StatusCodes;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public abstract class AbstractHttpHandler implements HttpHandler {
|
||||||
|
@Override
|
||||||
|
public final void handleRequest(final HttpServerExchange exchange) {
|
||||||
|
if (exchange.isInIoThread()) {
|
||||||
|
exchange.dispatch(this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
this.handle(exchange);
|
||||||
|
} catch (@NonNull final Exception e) {
|
||||||
|
log.error("Error handling request", e);
|
||||||
|
exchange.setStatusCode(StatusCodes.INTERNAL_SERVER_ERROR)
|
||||||
|
.getResponseSender()
|
||||||
|
.send(StatusCodes.INTERNAL_SERVER_ERROR_STRING);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void handle(@NonNull final HttpServerExchange exchange) throws Exception;
|
||||||
|
}
|
|
@ -1,12 +1,14 @@
|
||||||
package ch.fritteli.labyrinth.server.undertow_playground;
|
package ch.fritteli.labyrinth.server.handler;
|
||||||
|
|
||||||
import ch.fritteli.labyrinth.generator.model.Labyrinth;
|
import ch.fritteli.labyrinth.generator.model.Labyrinth;
|
||||||
import ch.fritteli.labyrinth.server.OutputType;
|
import ch.fritteli.labyrinth.server.OutputType;
|
||||||
import io.undertow.server.HttpHandler;
|
import ch.fritteli.labyrinth.server.handler.AbstractHttpHandler;
|
||||||
|
import ch.fritteli.labyrinth.server.undertow_playground.UndertowPlayground;
|
||||||
import io.undertow.server.HttpServerExchange;
|
import io.undertow.server.HttpServerExchange;
|
||||||
import io.undertow.util.Headers;
|
import io.undertow.util.Headers;
|
||||||
import io.undertow.util.HttpString;
|
import io.undertow.util.HttpString;
|
||||||
import io.vavr.control.Option;
|
import io.vavr.control.Option;
|
||||||
|
import lombok.NonNull;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
@ -15,13 +17,9 @@ import java.util.Map;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
class LabyrinthHttpHandler implements HttpHandler {
|
public class CreateHandler extends AbstractHttpHandler {
|
||||||
@Override
|
@Override
|
||||||
public void handleRequest(HttpServerExchange exchange) throws Exception {
|
protected void handle(@NonNull final HttpServerExchange exchange) throws Exception {
|
||||||
if (exchange.isInIoThread()) {
|
|
||||||
exchange.dispatch(this);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final Map<String, Deque<String>> queryParameters = exchange.getQueryParameters();
|
final Map<String, Deque<String>> queryParameters = exchange.getQueryParameters();
|
||||||
final Option<String> output = UndertowPlayground.getFirstOption(queryParameters, "output");
|
final Option<String> output = UndertowPlayground.getFirstOption(queryParameters, "output");
|
||||||
final Option<Integer> width = UndertowPlayground.getIntOption(queryParameters, "width");
|
final Option<Integer> width = UndertowPlayground.getIntOption(queryParameters, "width");
|
|
@ -0,0 +1,17 @@
|
||||||
|
package ch.fritteli.labyrinth.server.undertow_playground;
|
||||||
|
|
||||||
|
import io.undertow.server.HttpHandler;
|
||||||
|
import io.undertow.server.HttpServerExchange;
|
||||||
|
import io.undertow.util.StatusCodes;
|
||||||
|
|
||||||
|
public class LanyrinthRenderHandler implements HttpHandler {
|
||||||
|
@Override
|
||||||
|
public void handleRequest(final HttpServerExchange exchange) {
|
||||||
|
if (exchange.isInIoThread()) {
|
||||||
|
exchange.dispatch(this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
exchange.setStatusCode(StatusCodes.NOT_IMPLEMENTED);
|
||||||
|
exchange.getResponseSender().send("Rendering binary data is not implemented yet.");
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,24 +14,6 @@ import java.util.Map;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class UndertowPlayground {
|
public class UndertowPlayground {
|
||||||
public static final RoutingHandler r = new RoutingHandler().get("/create/{output}", new LabyrinthHttpHandler()).post("/render", new HttpHandler() {
|
|
||||||
@Override
|
|
||||||
public void handleRequest(final HttpServerExchange exchange) {
|
|
||||||
if (exchange.isInIoThread()) {
|
|
||||||
exchange.dispatch(this);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
exchange.getResponseSender().send("TODO: read body, render stuff");
|
|
||||||
}
|
|
||||||
}).setFallbackHandler(new HttpHandler() {
|
|
||||||
@Override
|
|
||||||
public void handleRequest(HttpServerExchange exchange) throws Exception {
|
|
||||||
exchange.getResponseSender().send("Request: " + exchange.getRequestURI());
|
|
||||||
final HeaderValues strings = exchange.getRequestHeaders().get(Headers.ACCEPT);
|
|
||||||
strings.peekFirst();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public static Option<Integer> getIntOption(@NonNull final Map<String, Deque<String>> queryParams,
|
public static Option<Integer> getIntOption(@NonNull final Map<String, Deque<String>> queryParams,
|
||||||
@NonNull final String paramName) {
|
@NonNull final String paramName) {
|
||||||
|
|
Loading…
Reference in a new issue