Bug fixes

This commit is contained in:
UnlegitDqrk
2026-02-08 22:33:31 +01:00
parent e9c06f571f
commit fe11dd7701
6 changed files with 242 additions and 128 deletions

View File

@@ -16,59 +16,68 @@ import java.nio.charset.StandardCharsets;
import java.util.Map;
/**
* Dispatches Java WebPages using @Route annotation.
* Dispatches Java WebPages using {@code @Route} annotation.
*
* <p>This dispatcher relies on {@link JavaRouteRegistry} for route-to-source mapping
* and uses {@link JavaPageCache} to compile/load classes from the content tree.
*/
public final class JavaPageDispatcher {
private static final JavaRouteRegistry ROUTES = new JavaRouteRegistry();
private static final JavaPageCache CACHE = new JavaPageCache();
private JavaPageDispatcher() {
}
/**
* Attempts to dispatch a request to a Java WebPage.
*
* @param client connected client
* @param server protocol web server
* @param request request packet
* @return response packet or {@code null} if no Java route matches and static file handling should proceed
* @throws Exception on unexpected failures
*/
public static WebResponsePacket dispatch(
CustomConnectedClient client,
ProtocolWebServer server,
WebRequestPacket request
) throws Exception {
if (request.getPath() == null) return null;
if (request == null || request.getPath() == null) {
return null;
}
String route = request.getPath();
if (!route.startsWith("/")) route = "/" + route;
if (!route.startsWith("/")) {
route = "/" + route;
}
File contentRoot = server.getContentFolder();
ROUTES.refreshIfNeeded(contentRoot);
JavaRouteRegistry.RouteLookupResult found = ROUTES.find(route);
// If no @Route match, still detect "requested a .java-backed path by filename"
// (legacy behavior): if a matching *.java exists, compile/load but return error.
if (found == null) {
String p = route.startsWith("/") ? route.substring(1) : route;
File javaFile = new File(contentRoot, p + ".java");
if (javaFile.exists() && javaFile.isFile()) {
// Compile/load but do not serve.
new JavaPageCache().getOrCompile(javaFile);
return error(501, "Java class exists but has no @Route: " + route);
}
return null; // not a Java route -> let file server handle it
return null;
}
// If it has @Route but is not a WebPage, compile/load but return error.
if (!found.routable()) {
long contentLm = ROUTES.currentContentLastModified(contentRoot);
JavaPageCache.LoadedClass loaded = CACHE.getOrCompile(contentRoot, found.sourceFile(), contentLm);
Class<?> clazz = loaded.clazz();
// Verify that the loaded class is actually routable.
if (!WebPage.class.isAssignableFrom(clazz)) {
return error(500, "Class has @Route but is not a WebPage: " + found.fqcn());
}
// Load and execute
Class<?> clazz = Class.forName(found.fqcn());
Object instance = clazz.getDeclaredConstructor().newInstance();
if (!(instance instanceof WebPage page)) {
return error(500, "Routed class is not a WebPage: " + found.fqcn());
}
WebPage page = (WebPage) instance;
WebHasher hasher = (server instanceof WebServer ws) ? ws.getHasher() : null;
if (hasher == null) return error(500, "WebHasher missing on server instance.");
if (hasher == null) {
return error(500, "WebHasher missing on server instance.");
}
WebPageContext ctx = new WebPageContext(client, server, request, new RequestParams(request), hasher);
return page.handle(ctx);
@@ -82,4 +91,4 @@ public final class JavaPageDispatcher {
msg.getBytes(StandardCharsets.UTF_8)
);
}
}
}