From d1910ce5cdbf2ca771db24d861fd1bd74b37e009 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Prante?= Date: Thu, 23 Mar 2023 17:38:16 +0100 Subject: [PATCH] add prefix mode: router can manage a known prefix for a path, useful for web application hooks --- .../xbib/net/http/server/BaseHttpService.java | 5 +++-- .../resource/ClassLoaderResourceHandler.java | 18 +++++++++--------- .../server/resource/FileResourceHandler.java | 2 +- .../server/resource/HtmlTemplateResource.java | 2 +- .../resource/HtmlTemplateResourceHandler.java | 10 +++++----- .../net/http/server/route/BaseHttpRouter.java | 2 +- .../server/route/BaseHttpRouterBuilder.java | 9 +++++++++ .../http/server/route/HttpRouterBuilder.java | 2 ++ .../server/session/IncomingSessionHandler.java | 4 ++-- .../server/session/OutgoingSessionHandler.java | 16 ++++++++++++---- .../template/groovy/DefaultMarkupTemplate.java | 10 ++++++++-- 11 files changed, 53 insertions(+), 27 deletions(-) diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/BaseHttpService.java b/net-http-server/src/main/java/org/xbib/net/http/server/BaseHttpService.java index d9d606a..ff2dd08 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/BaseHttpService.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/BaseHttpService.java @@ -76,18 +76,19 @@ public class BaseHttpService implements HttpService { } BaseHttpService endpoint = (BaseHttpService) o; return Objects.equals(builder.methods, endpoint.builder.methods) && + Objects.equals(builder.prefix, endpoint.builder.prefix) && Objects.equals(builder.pathSpec, endpoint.builder.pathSpec) && Objects.equals(builder.handlers, endpoint.builder.handlers); } @Override public int hashCode() { - return Objects.hash(builder.methods, builder.pathSpec, builder.handlers); + return Objects.hash(builder.methods, builder.prefix, builder.pathSpec, builder.handlers); } @Override public String toString() { - return "BaseHttpService[methods=" + builder.methods + ",path=" + builder.pathSpec + ",handler=" + builder.handlers + "]"; + return "BaseHttpService[methods=" + builder.methods + ",prefix" + builder.prefix + ",path=" + builder.pathSpec + ",handler=" + builder.handlers + "]"; } } diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/resource/ClassLoaderResourceHandler.java b/net-http-server/src/main/java/org/xbib/net/http/server/resource/ClassLoaderResourceHandler.java index 4f3899c..70acc5f 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/resource/ClassLoaderResourceHandler.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/resource/ClassLoaderResourceHandler.java @@ -18,15 +18,15 @@ public class ClassLoaderResourceHandler extends AbstractResourceHandler { private final ClassLoader classLoader; - private final String prefix; + private final String resourcePrefix; public ClassLoaderResourceHandler(ClassLoader classLoader) { this(classLoader, null); } - public ClassLoaderResourceHandler(ClassLoader classLoader, String prefix) { + public ClassLoaderResourceHandler(ClassLoader classLoader, String resourcePrefix) { this.classLoader = classLoader; - this.prefix = prefix; + this.resourcePrefix = resourcePrefix; } @Override @@ -74,11 +74,11 @@ public class ClassLoaderResourceHandler extends AbstractResourceHandler { private URL url; - ClassLoaderResource(HttpServerContext httpServerContext) throws IOException { - String requestPath = httpServerContext.request().getRequestPath().substring(1); - this.mimeType = mimeTypeService.getContentType(requestPath); - this.resourcePath = requestPath.startsWith("/") ? requestPath.substring(1) : requestPath; - String path = prefix != null ? (prefix.endsWith("/") ? prefix : prefix + "/") : "/"; + protected ClassLoaderResource(HttpServerContext httpServerContext) throws IOException { + String contextPath = httpServerContext.getContextPath(); + this.mimeType = mimeTypeService.getContentType(contextPath); + this.resourcePath = contextPath.startsWith("/") ? contextPath.substring(1) : contextPath; + String path = resourcePrefix != null ? (resourcePrefix.endsWith("/") ? resourcePrefix : resourcePrefix + "/") : "/"; path = resourcePath.startsWith("/") ? path + resourcePath.substring(1) : path + resourcePath; String normalizedPath = PathNormalizer.normalize(resourcePath); if (normalizedPath.startsWith("/")) { @@ -88,7 +88,7 @@ public class ClassLoaderResourceHandler extends AbstractResourceHandler { this.name = normalizedPath; this.baseName = basename(name); this.suffix = suffix(name); - logger.log(Level.FINER, "trying: path=" + path + " classLoader=" + classLoader); + logger.log(Level.FINER, "trying: path = " + path + " normalizedPath = " + normalizedPath); java.net.URL url = classLoader.getResource(path); if (url != null) { this.url = URL.create(url.toString()); diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/resource/FileResourceHandler.java b/net-http-server/src/main/java/org/xbib/net/http/server/resource/FileResourceHandler.java index acce251..5315e0e 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/resource/FileResourceHandler.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/resource/FileResourceHandler.java @@ -39,7 +39,7 @@ public class FileResourceHandler extends AbstractResourceHandler { protected Resource createResource(HttpServerContext httpServerContext) throws IOException { String pathSpec = httpServerContext.attributes().containsKey("templatePath") ? (String) httpServerContext.attributes().get("templatePath") : - pathNameOfResource != null ? pathNameOfResource : httpServerContext.httpRequest().getRequestPath(); + pathNameOfResource != null ? pathNameOfResource : httpServerContext.getContextPath(); if (pathSpec == null || pathSpec.isEmpty()) { throw new IllegalArgumentException("path must not be null or empty"); } diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/resource/HtmlTemplateResource.java b/net-http-server/src/main/java/org/xbib/net/http/server/resource/HtmlTemplateResource.java index d73160e..f00f73b 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/resource/HtmlTemplateResource.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/resource/HtmlTemplateResource.java @@ -47,7 +47,7 @@ public class HtmlTemplateResource implements HttpServerResource { String indexFileName = templateResourceHandler.getIndexFileName(); Application application = httpServerContext.attributes().get(Application.class, "application"); this.negotiateLocale = application.getSettings().getAsBoolean("negotiateLocale", false); - Path root = templateResourceHandler.getPrefix(); + Path root = templateResourceHandler.getRoot(); root = root != null ? root : application.getHome(); if (root == null) { throw new IllegalArgumentException("no home path set for template resource resolving"); diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/resource/HtmlTemplateResourceHandler.java b/net-http-server/src/main/java/org/xbib/net/http/server/resource/HtmlTemplateResourceHandler.java index d292238..de2ded2 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/resource/HtmlTemplateResourceHandler.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/resource/HtmlTemplateResourceHandler.java @@ -8,16 +8,16 @@ import java.nio.file.Path; public class HtmlTemplateResourceHandler extends AbstractResourceHandler { - protected final Path prefix; + protected final Path root; protected final String suffix; protected final String indexFileName; - public HtmlTemplateResourceHandler(Path prefix, + public HtmlTemplateResourceHandler(Path root, String suffix, String indexFileName) { - this.prefix = prefix; + this.root = root; this.suffix = suffix; this.indexFileName = indexFileName; } @@ -47,8 +47,8 @@ public class HtmlTemplateResourceHandler extends AbstractResourceHandler { return 0; } - public Path getPrefix() { - return prefix; + public Path getRoot() { + return root; } public String getSuffix() { diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/route/BaseHttpRouter.java b/net-http-server/src/main/java/org/xbib/net/http/server/route/BaseHttpRouter.java index a99e853..66b5b34 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/route/BaseHttpRouter.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/route/BaseHttpRouter.java @@ -100,7 +100,7 @@ public class BaseHttpRouter implements HttpRouter { requestBuilder.setRequestPath(extractPath(requestBuilder.getRequestURI())); HttpRoute httpRoute = new BaseHttpRoute(httpDomain.getAddress(), Set.of(requestBuilder.getMethod()), - "", + builder.prefix, requestBuilder.getRequestPath(), true); httpRouteResolver.resolve(httpRoute, httpRouteResolverResults::add); diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/route/BaseHttpRouterBuilder.java b/net-http-server/src/main/java/org/xbib/net/http/server/route/BaseHttpRouterBuilder.java index b7bd1a9..2ab0567 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/route/BaseHttpRouterBuilder.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/route/BaseHttpRouterBuilder.java @@ -18,11 +18,14 @@ import org.xbib.net.http.server.handler.VersionNotSupportedHandler; public class BaseHttpRouterBuilder implements HttpRouterBuilder { + protected String prefix; + protected final Collection domains; protected final Map handlers; protected BaseHttpRouterBuilder() { + prefix = ""; domains = new ArrayList<>(); handlers = new HashMap<>(); handlers.put(400, new BadRequestHandler()); @@ -34,6 +37,12 @@ public class BaseHttpRouterBuilder implements HttpRouterBuilder { handlers.put(505, new VersionNotSupportedHandler()); } + @Override + public BaseHttpRouterBuilder setPrefix(String prefix) { + this.prefix = prefix; + return this; + } + @Override public BaseHttpRouterBuilder setHandler(Integer code, HttpHandler httpHandler) { handlers.put(code, httpHandler); diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/route/HttpRouterBuilder.java b/net-http-server/src/main/java/org/xbib/net/http/server/route/HttpRouterBuilder.java index 64bf6c5..7b9a8b8 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/route/HttpRouterBuilder.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/route/HttpRouterBuilder.java @@ -5,6 +5,8 @@ import org.xbib.net.http.server.HttpHandler; public interface HttpRouterBuilder { + HttpRouterBuilder setPrefix(String prefix); + HttpRouterBuilder setHandler(Integer code, HttpHandler httpHandler); HttpRouterBuilder addDomain(HttpDomain domain); diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/session/IncomingSessionHandler.java b/net-http-server/src/main/java/org/xbib/net/http/server/session/IncomingSessionHandler.java index 690acea..539245d 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/session/IncomingSessionHandler.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/session/IncomingSessionHandler.java @@ -158,10 +158,10 @@ public class IncomingSessionHandler implements HttpHandler { if (m == null) { return userProfile; } - if (m.containsKey(sessionUserName)) { + if (sessionUserName != null && m.containsKey(sessionUserName)) { userProfile.setUserId((String) m.get(sessionUserName)); } - if (m.containsKey(sessionEffectiveUserName)) { + if (sessionEffectiveUserName != null && m.containsKey(sessionEffectiveUserName)) { userProfile.setEffectiveUserId((String) m.get(sessionEffectiveUserName)); } if (session != null && userProfile.getUserId() != null) { diff --git a/net-http-server/src/main/java/org/xbib/net/http/server/session/OutgoingSessionHandler.java b/net-http-server/src/main/java/org/xbib/net/http/server/session/OutgoingSessionHandler.java index 832accd..5fc5cb5 100644 --- a/net-http-server/src/main/java/org/xbib/net/http/server/session/OutgoingSessionHandler.java +++ b/net-http-server/src/main/java/org/xbib/net/http/server/session/OutgoingSessionHandler.java @@ -107,8 +107,12 @@ public class OutgoingSessionHandler implements HttpHandler { try { if (userProfile != null) { logger.log(Level.FINE, "user profile present: " + userProfile); - session.put(sessionUserName, userProfile.getUserId()); - session.put(sessionEffectiveUserName, userProfile.getEffectiveUserId()); + if (sessionUserName != null) { + session.put(sessionUserName, userProfile.getUserId()); + } + if (sessionEffectiveUserName != null) { + session.put(sessionEffectiveUserName, userProfile.getEffectiveUserId()); + } } sessionCodec.write(session.id(), session); Cookie cookie = encodeCookie(session, host, path); @@ -141,8 +145,12 @@ public class OutgoingSessionHandler implements HttpHandler { return createEmptyCookie(host, path); } Map map = new HashMap<>(); - map.put(sessionUserName, session.get(sessionUserName)); - map.put(sessionEffectiveUserName, session.get(sessionEffectiveUserName)); + if (sessionUserName != null) { + map.put(sessionUserName, session.get(sessionUserName)); + } + if (sessionEffectiveUserName != null) { + map.put(sessionEffectiveUserName, session.get(sessionEffectiveUserName)); + } String payload = CookieSignatureUtil.toString(map); String sig = CookieSignatureUtil.hmac(payload, sessionSecret, sessionCookieAlgorithm); String cookieValue = String.join(":", id, payload, sig); diff --git a/net-http-template-groovy/src/main/java/org/xbib/net/http/template/groovy/DefaultMarkupTemplate.java b/net-http-template-groovy/src/main/java/org/xbib/net/http/template/groovy/DefaultMarkupTemplate.java index 6e1c337..1db90bf 100644 --- a/net-http-template-groovy/src/main/java/org/xbib/net/http/template/groovy/DefaultMarkupTemplate.java +++ b/net-http-template-groovy/src/main/java/org/xbib/net/http/template/groovy/DefaultMarkupTemplate.java @@ -113,8 +113,14 @@ public abstract class DefaultMarkupTemplate extends BaseTemplate { } public String urlProto(String rel, boolean absolute) { - URL url = request.getServerURL().resolve(rel); - logger.log(Level.FINE, "server URL = " + request.getServerURL() + " rel = " + rel + " --> " + url); + String prefix = application.getSettings().get("web.prefix", "/"); + if (!prefix.endsWith("/")) { + prefix = prefix + "/"; + } + URL url = request.getServerURL().resolve(prefix).resolve(rel); + logger.log(Level.FINE, "server base URL = " + request.getServerURL() + + " prefix = " + prefix + + " rel = " + rel + " --> " + url); return absolute ? url.toExternalForm() : toOrigin(url); }