From fd9eef60dfaefbd4a54a80777e60fe913a56e08a Mon Sep 17 00:00:00 2001 From: Brian Matzon Date: Thu, 25 Sep 2025 10:37:58 +0200 Subject: [PATCH 1/2] Expose clientIdentifier generation as a function and expose a setter to modify it as needed --- .../valves/CrawlerSessionManagerValve.java | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/java/org/apache/catalina/valves/CrawlerSessionManagerValve.java b/java/org/apache/catalina/valves/CrawlerSessionManagerValve.java index 0c3eaca6276f..5c4e3a6a3759 100644 --- a/java/org/apache/catalina/valves/CrawlerSessionManagerValve.java +++ b/java/org/apache/catalina/valves/CrawlerSessionManagerValve.java @@ -22,6 +22,7 @@ import java.util.Enumeration; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Function; import java.util.regex.Pattern; import jakarta.servlet.ServletException; @@ -60,6 +61,8 @@ public class CrawlerSessionManagerValve extends ValveBase { private boolean isContextAware = true; + private Function clientIdentifierFunction = this::getClientIdentifier; + /** * Specifies a default constructor so async support can be configured. @@ -163,6 +166,14 @@ public void setContextAware(boolean isContextAware) { this.isContextAware = isContextAware; } + /** + * Specify the clientIdentifier function that will be used to identify unique clients. The default is to use + * the client IP address, optionally combined with the host name and context name + * @param clientIdentifierFunction + */ + public void setClientIdentifierFunction(Function clientIdentifierFunction) { + this.clientIdentifierFunction = clientIdentifierFunction; + } @Override protected void initInternal() throws LifecycleException { @@ -185,7 +196,7 @@ public void invoke(Request request, Response response) throws IOException, Servl boolean isBot = false; String sessionId = null; String clientIp = request.getRemoteAddr(); - String clientIdentifier = getClientIdentifier(host, request.getContext(), clientIp); + String clientIdentifier = clientIdentifierFunction.apply(request); if (log.isTraceEnabled()) { log.trace(request.hashCode() + ": ClientIdentifier=" + clientIdentifier + ", RequestedSessionId=" + @@ -263,8 +274,11 @@ public void invoke(Request request, Response response) throws IOException, Servl } } + private String getClientIdentifier(Request request) { + return getClientIdentifierDefault(request.getHost(), request.getContext(), request.getRemoteAddr()); + } - private String getClientIdentifier(Host host, Context context, String clientIp) { + private String getClientIdentifierDefault(Host host, Context context, String clientIp) { StringBuilder result = new StringBuilder(clientIp); if (isHostAware) { result.append('-').append(host.getName()); From e88ebb284126048211af3518a7dac8cf3c4fb7bb Mon Sep 17 00:00:00 2001 From: Brian Matzon Date: Thu, 25 Sep 2025 13:46:08 +0200 Subject: [PATCH 2/2] Drop getClientIdentifierDefault and refactor existing getClientIdentifier to use request parameter --- .../catalina/valves/CrawlerSessionManagerValve.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/java/org/apache/catalina/valves/CrawlerSessionManagerValve.java b/java/org/apache/catalina/valves/CrawlerSessionManagerValve.java index 5c4e3a6a3759..8b63297b7933 100644 --- a/java/org/apache/catalina/valves/CrawlerSessionManagerValve.java +++ b/java/org/apache/catalina/valves/CrawlerSessionManagerValve.java @@ -275,14 +275,11 @@ public void invoke(Request request, Response response) throws IOException, Servl } private String getClientIdentifier(Request request) { - return getClientIdentifierDefault(request.getHost(), request.getContext(), request.getRemoteAddr()); - } - - private String getClientIdentifierDefault(Host host, Context context, String clientIp) { - StringBuilder result = new StringBuilder(clientIp); + StringBuilder result = new StringBuilder(request.getRemoteAddr()); if (isHostAware) { - result.append('-').append(host.getName()); + result.append('-').append(request.getHost().getName()); } + Context context = request.getContext(); if (isContextAware && context != null) { result.append(context.getName()); }