Skip to content

Commit

Permalink
Improved redirects for the webserver
Browse files Browse the repository at this point in the history
  • Loading branch information
jonafanho committed Oct 29, 2024
1 parent d274fbf commit 9ae5964
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 14 deletions.
1 change: 1 addition & 0 deletions buildSrc/src/main/resources/website/src/main.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import "reflect-metadata";
import {bootstrapApplication} from "@angular/platform-browser";
import {AppComponent} from "./app/app.component";
import {provideAnimationsAsync} from "@angular/platform-browser/animations/async";
Expand Down
10 changes: 7 additions & 3 deletions src/main/java/org/mtr/core/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.mtr.core.data.Depot;
import org.mtr.core.generated.WebserverResources;
import org.mtr.core.servlet.*;
import org.mtr.core.simulation.Simulator;
import org.mtr.core.tool.Utilities;
Expand Down Expand Up @@ -43,15 +44,15 @@ public static void main(String[] args) {
final boolean threadedSimulation = Boolean.parseBoolean(args[i++]);
final String[] dimensions = new String[args.length - i];
System.arraycopy(args, i, dimensions, 0, dimensions.length);
final Main main = new Main(rootPath, webserverPort, threadedSimulation, dimensions);
final Main main = new Main(rootPath, webserverPort, threadedSimulation, null, dimensions);
main.readConsoleInput();
} catch (Exception e) {
printHelp();
LOGGER.error("", e);
}
}

public Main(Path rootPath, int webserverPort, boolean threadedSimulation, String... dimensions) {
public Main(Path rootPath, int webserverPort, boolean threadedSimulation, @Nullable Consumer<Webserver> additionalWebserverSetup, String... dimensions) {
final ObjectArrayList<Simulator> tempSimulators = new ObjectArrayList<>();

LOGGER.info("Loading files...");
Expand All @@ -63,9 +64,12 @@ public Main(Path rootPath, int webserverPort, boolean threadedSimulation, String

if (webserverPort > 0) {
webserver = new Webserver(webserverPort);
webserver.addServlet(new ServletHolder(new WebServlet()), "/");
webserver.addServlet(new ServletHolder(new WebServlet(WebserverResources::get, "/")), "/");
webserver.addServlet(new ServletHolder(new SystemMapServlet(simulators)), "/mtr/api/map/*");
webserver.addServlet(new ServletHolder(new OBAServlet(simulators)), "/oba/api/where/*");
if (additionalWebserverSetup != null) {
additionalWebserverSetup.accept(webserver);
}
webserver.start();
} else {
webserver = null;
Expand Down
1 change: 1 addition & 0 deletions src/main/java/org/mtr/core/servlet/HttpResponseStatus.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
public enum HttpResponseStatus {

OK(200, "OK"),
REDIRECT(301, "Redirect"),
BAD_REQUEST(400, "Bad Request"),
NOT_FOUND(404, "Not Found"),
INTERNAL_SERVER_ERROR(500, "Internal Server Error");
Expand Down
3 changes: 3 additions & 0 deletions src/main/java/org/mtr/core/servlet/ServletBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ public static void sendResponse(HttpServletResponse httpServletResponse, AsyncCo
final ByteBuffer byteBuffer = ByteBuffer.wrap(content.getBytes(StandardCharsets.UTF_8));
httpServletResponse.addHeader("Content-Type", contentType);
httpServletResponse.addHeader("Access-Control-Allow-Origin", "*");
if (httpResponseStatus == HttpResponseStatus.REDIRECT) {
httpServletResponse.addHeader("Location", content);
}
servletOutputStream.setWriteListener(new WriteListener() {
@Override
public void onWritePossible() {
Expand Down
30 changes: 20 additions & 10 deletions src/main/java/org/mtr/core/servlet/WebServlet.java
Original file line number Diff line number Diff line change
@@ -1,30 +1,40 @@
package org.mtr.core.servlet;

import org.mtr.core.generated.WebserverResources;
import org.mtr.libraries.javax.servlet.AsyncContext;
import org.mtr.libraries.javax.servlet.http.HttpServlet;
import org.mtr.libraries.javax.servlet.http.HttpServletRequest;
import org.mtr.libraries.javax.servlet.http.HttpServletResponse;

import java.util.function.Function;

public final class WebServlet extends HttpServlet {

private final Function<String, String> contentProvider;
private final String expectedPath;

public WebServlet(Function<String, String> contentProvider, String expectedPath) {
this.contentProvider = contentProvider;
this.expectedPath = expectedPath;
}

@Override
protected void doGet(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
final AsyncContext asyncContext = httpServletRequest.startAsync();
asyncContext.setTimeout(0);
getContent(httpServletResponse, asyncContext, httpServletRequest.getServletPath(), true);
}

private static void getContent(HttpServletResponse httpServletResponse, AsyncContext asyncContext, String path, boolean retry) {
final String content = WebserverResources.get(ServletBase.removeLastSlash(path));
if (content == null) {
if (retry) {
getContent(httpServletResponse, asyncContext, "index.html", false);
final String requestUri = httpServletRequest.getRequestURI();
if (requestUri.startsWith(expectedPath)) {
final String path = ServletBase.removeLastSlash(requestUri.replace(expectedPath, ""));
final String newPath = path.isEmpty() ? "index.html" : path;
final String content = contentProvider.apply(newPath);

if (content == null) {
ServletBase.sendResponse(httpServletResponse, asyncContext, expectedPath, "", HttpResponseStatus.REDIRECT);
} else {
ServletBase.sendResponse(httpServletResponse, asyncContext, "", "", HttpResponseStatus.NOT_FOUND);
ServletBase.sendResponse(httpServletResponse, asyncContext, content, ServletBase.getMimeType(newPath), HttpResponseStatus.OK);
}
} else {
ServletBase.sendResponse(httpServletResponse, asyncContext, content, ServletBase.getMimeType(path), HttpResponseStatus.OK);
ServletBase.sendResponse(httpServletResponse, asyncContext, expectedPath, "", HttpResponseStatus.REDIRECT);
}
}
}
2 changes: 1 addition & 1 deletion src/test/java/org/mtr/core/RuntimeTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class RuntimeTests implements TestUtilities {
@Test
public void createAndUpdateData() throws IOException {
FileUtils.deleteDirectory(TEST_DIRECTORY.toFile());
final Main main = new Main(TEST_DIRECTORY, PORT, true, "overworld");
final Main main = new Main(TEST_DIRECTORY, PORT, true, null, "overworld");

final Station station1 = new Station(TestUtilities.getDefaultSimulator());
station1.setName("Test 1");
Expand Down

0 comments on commit 9ae5964

Please sign in to comment.