Allow overriding RestfulServer's contextPath (#6113)
* Move IncomingRequestAddressStrategy::determineServletContextPath into IServerAddressStrategy to permit overriding (#6038) * add changelog * add contributor as developer --------- Co-authored-by: Alex Kopp <akopp@athenahealth.com> Co-authored-by: juan.marchionatto <juan.marchionatto@smilecdr.com>
This commit is contained in:
parent
e07684474f
commit
5f9b40e3f5
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
type: add
|
||||
issue: 6038
|
||||
title: "Allow overriding RestfulServer's contextPath determination by overriding IServerAddressStrategy.
|
||||
Thanks to Alex Kopp (@alexrkopp) for the contribution!"
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1047,7 +1047,7 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
|
|||
String requestFullPath = StringUtils.defaultString(theRequest.getRequestURI());
|
||||
String servletPath = StringUtils.defaultString(theRequest.getServletPath());
|
||||
StringBuffer requestUrl = theRequest.getRequestURL();
|
||||
String servletContextPath = IncomingRequestAddressStrategy.determineServletContextPath(theRequest, this);
|
||||
String servletContextPath = myServerAddressStrategy.determineServletContextPath(theRequest, this);
|
||||
|
||||
/*
|
||||
* Just for debugging..
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Server Framework
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2024 Smile CDR, Inc.
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
package ca.uhn.fhir.rest.server;
|
||||
|
||||
import jakarta.servlet.ServletContext;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class IServerAddressStrategyTest {
|
||||
|
||||
@Mock
|
||||
private RestfulServer server;
|
||||
|
||||
@Mock
|
||||
private ServletContext servletContext;
|
||||
|
||||
@Mock
|
||||
private HttpServletRequest request;
|
||||
|
||||
private final IServerAddressStrategy strategy = new IServerAddressStrategy() {
|
||||
@Override
|
||||
public String determineServerBase(ServletContext theServletContext, HttpServletRequest theRequest) {
|
||||
return "";
|
||||
}
|
||||
};
|
||||
|
||||
@Test
|
||||
public void testDetermineServletContextPath_UsesServletContext() {
|
||||
when(server.getServletContext()).thenReturn(servletContext);
|
||||
when(servletContext.getMajorVersion()).thenReturn(3);
|
||||
when(servletContext.getContextPath()).thenReturn("/servlet/context");
|
||||
String result = strategy.determineServletContextPath(request, server);
|
||||
assertEquals("/servlet/context", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDetermineServletContextPath_DoesNotUseServletContext() {
|
||||
when(server.getServletContext()).thenReturn(servletContext);
|
||||
when(servletContext.getMajorVersion()).thenReturn(2);
|
||||
when(request.getContextPath()).thenReturn("/request/context");
|
||||
assertEquals("/request/context", strategy.determineServletContextPath(request, server));
|
||||
|
||||
when(server.getServletContext()).thenReturn(null);
|
||||
assertEquals("/request/context", strategy.determineServletContextPath(request, server));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue