From 0a65657d1622e7b15aa331df34be1d14c8977a4b Mon Sep 17 00:00:00 2001 From: Alex Kopp Date: Mon, 24 Jun 2024 18:27:29 -0400 Subject: [PATCH] Move IncomingRequestAddressStrategy::determineServletContextPath into IServerAddressStrategy to permit overriding (#6038) --- .../rest/server/IServerAddressStrategy.java | 32 +++++++++ .../IncomingRequestAddressStrategy.java | 31 -------- .../uhn/fhir/rest/server/RestfulServer.java | 2 +- .../server/IServerAddressStrategyTest.java | 70 +++++++++++++++++++ 4 files changed, 103 insertions(+), 32 deletions(-) create mode 100644 hapi-fhir-server/src/test/java/ca/uhn/fhir/rest/server/IServerAddressStrategyTest.java diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/IServerAddressStrategy.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/IServerAddressStrategy.java index 339f15f77d9..e11d94e61e1 100644 --- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/IServerAddressStrategy.java +++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/IServerAddressStrategy.java @@ -21,6 +21,7 @@ package ca.uhn.fhir.rest.server; import jakarta.servlet.ServletContext; import jakarta.servlet.http.HttpServletRequest; +import org.apache.commons.lang3.StringUtils; /** * Provides the server base for a given incoming request. This can be used to account for @@ -32,4 +33,35 @@ public interface IServerAddressStrategy { * Determine the server base for a given request */ String determineServerBase(ServletContext theServletContext, HttpServletRequest theRequest); + + /** + * Determines the servlet's context path. + * + * This is here to try and deal with the wide variation in servers and what they return. + * + * getServletContext().getContextPath() is supposed to return the path to the specific servlet we are deployed as but it's not available everywhere. On some servers getServletContext() can return + * null (old Jetty seems to suffer from this, see hapi-fhir-base-test-mindeps-server) and on other old servers (Servlet 2.4) getServletContext().getContextPath() doesn't even exist. + * + * theRequest.getContextPath() returns the context for the specific incoming request. It should be available everywhere, but it's likely to be less predicable if there are multiple servlet mappings + * pointing to the same servlet, so we don't favour it. This is possibly not the best strategy (maybe we should just always use theRequest.getContextPath()?) but so far people seem happy with this + * behaviour across a wide variety of platforms. + * + * If you are having troubles on a given platform/configuration and want to suggest a change or even report incompatibility here, we'd love to hear about it. + */ + default String determineServletContextPath(HttpServletRequest theRequest, RestfulServer server) { + String retVal; + if (server.getServletContext() != null) { + if (server.getServletContext().getMajorVersion() >= 3 + || (server.getServletContext().getMajorVersion() > 2 + && server.getServletContext().getMinorVersion() >= 5)) { + retVal = server.getServletContext().getContextPath(); + } else { + retVal = theRequest.getContextPath(); + } + } else { + retVal = theRequest.getContextPath(); + } + retVal = StringUtils.defaultString(retVal); + return retVal; + } } diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/IncomingRequestAddressStrategy.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/IncomingRequestAddressStrategy.java index 98a30e941c3..66fd7b6ce62 100644 --- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/IncomingRequestAddressStrategy.java +++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/IncomingRequestAddressStrategy.java @@ -104,35 +104,4 @@ public class IncomingRequestAddressStrategy implements IServerAddressStrategy { public void setServletPath(String theServletPath) { myServletPath = theServletPath; } - - /** - * Determines the servlet's context path. - * - * This is here to try and deal with the wide variation in servers and what they return. - * - * getServletContext().getContextPath() is supposed to return the path to the specific servlet we are deployed as but it's not available everywhere. On some servers getServletContext() can return - * null (old Jetty seems to suffer from this, see hapi-fhir-base-test-mindeps-server) and on other old servers (Servlet 2.4) getServletContext().getContextPath() doesn't even exist. - * - * theRequest.getContextPath() returns the context for the specific incoming request. It should be available everywhere, but it's likely to be less predicable if there are multiple servlet mappings - * pointing to the same servlet, so we don't favour it. This is possibly not the best strategy (maybe we should just always use theRequest.getContextPath()?) but so far people seem happy with this - * behavour across a wide variety of platforms. - * - * If you are having troubles on a given platform/configuration and want to suggest a change or even report incompatibility here, we'd love to hear about it. - */ - public static String determineServletContextPath(HttpServletRequest theRequest, RestfulServer server) { - String retVal; - if (server.getServletContext() != null) { - if (server.getServletContext().getMajorVersion() >= 3 - || (server.getServletContext().getMajorVersion() > 2 - && server.getServletContext().getMinorVersion() >= 5)) { - retVal = server.getServletContext().getContextPath(); - } else { - retVal = theRequest.getContextPath(); - } - } else { - retVal = theRequest.getContextPath(); - } - retVal = StringUtils.defaultString(retVal); - return retVal; - } } diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/RestfulServer.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/RestfulServer.java index b0d329fea2b..842ef245e80 100644 --- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/RestfulServer.java +++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/RestfulServer.java @@ -1047,7 +1047,7 @@ public class RestfulServer extends HttpServlet implements IRestfulServer