add prefix mode: router can manage a known prefix for a path, useful for web application hooks

This commit is contained in:
Jörg Prante 2023-03-23 17:38:16 +01:00
parent e488ed9d5a
commit d1910ce5cd
11 changed files with 53 additions and 27 deletions

View file

@ -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 + "]";
}
}

View file

@ -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());

View file

@ -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");
}

View file

@ -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");

View file

@ -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() {

View file

@ -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);

View file

@ -18,11 +18,14 @@ import org.xbib.net.http.server.handler.VersionNotSupportedHandler;
public class BaseHttpRouterBuilder implements HttpRouterBuilder {
protected String prefix;
protected final Collection<HttpDomain> domains;
protected final Map<Integer, HttpHandler> 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);

View file

@ -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);

View file

@ -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) {

View file

@ -107,9 +107,13 @@ public class OutgoingSessionHandler implements HttpHandler {
try {
if (userProfile != null) {
logger.log(Level.FINE, "user profile present: " + userProfile);
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);
if (cookie != null) {
@ -141,8 +145,12 @@ public class OutgoingSessionHandler implements HttpHandler {
return createEmptyCookie(host, path);
}
Map<String, Object> map = new HashMap<>();
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);

View file

@ -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);
}