This is an automated email from the ASF dual-hosted git repository. michaelo pushed a commit to branch mark-forwarded-request/8.5.x in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit 2eeb813dad2bcda58959b6eeea468d41f998f57b Author: Michael Osipov <micha...@apache.org> AuthorDate: Tue Jul 9 14:59:09 2019 +0200 Mark request as forwarded in RemoteIpValve/RemoteIpFilter --- java/org/apache/catalina/Globals.java | 10 ++++++++ .../apache/catalina/filters/RemoteIpFilter.java | 4 +++ java/org/apache/catalina/valves/RemoteIpValve.java | 4 +++ java/org/apache/coyote/Constants.java | 8 ++++++ .../catalina/filters/TestRemoteIpFilter.java | 23 +++++++++++++++++ .../apache/catalina/valves/TestRemoteIpValve.java | 30 ++++++++++++++++++++++ webapps/docs/changelog.xml | 7 +++++ 7 files changed, 86 insertions(+) diff --git a/java/org/apache/catalina/Globals.java b/java/org/apache/catalina/Globals.java index 8801724..edf91a0 100644 --- a/java/org/apache/catalina/Globals.java +++ b/java/org/apache/catalina/Globals.java @@ -199,6 +199,16 @@ public final class Globals { org.apache.coyote.Constants.REMOTE_ADDR_ATTRIBUTE; + /** + * The request attribute set by the RemoteIpFilter, RemoteIpValve (and may + * be set by other similar components) that identifies this request has been + * forwarded via one or more proxies. The value should be {@code java.lang.Boolean}. + * Absence shall be treated as {@code false}. + */ + public static final String FORWARDED_REQUEST_ATTRIBUTE = + org.apache.coyote.Constants.FORWARDED_REQUEST_ATTRIBUTE; + + public static final String ASYNC_SUPPORTED_ATTR = "org.apache.catalina.ASYNC_SUPPORTED"; diff --git a/java/org/apache/catalina/filters/RemoteIpFilter.java b/java/org/apache/catalina/filters/RemoteIpFilter.java index 20b4abd..f416f60 100644 --- a/java/org/apache/catalina/filters/RemoteIpFilter.java +++ b/java/org/apache/catalina/filters/RemoteIpFilter.java @@ -85,6 +85,8 @@ import org.apache.juli.logging.LogFactory; * <code>protocolHeaderHttpsValue</code> configuration parameter (default <code>https</code>) then <code>request.isSecure = true</code>, * <code>request.scheme = https</code> and <code>request.serverPort = 443</code>. Note that 443 can be overwritten with the * <code>$httpsServerPort</code> configuration parameter.</li> + * <li>Mark the request with the attribute {@link Globals#FORWARDED_REQUEST_ATTRIBUTE} and value {@code Boolean.TRUE} to indicate + * that this request has been forwarded by one or more proxies.</li> * </ul> * <table border="1"> * <caption>Configuration parameters</caption> @@ -860,6 +862,8 @@ public class RemoteIpFilter implements Filter { } } + request.setAttribute(Globals.FORWARDED_REQUEST_ATTRIBUTE, Boolean.TRUE); + if (log.isDebugEnabled()) { log.debug("Incoming request " + request.getRequestURI() + " with originalRemoteAddr '" + request.getRemoteAddr() + "', originalRemoteHost='" + request.getRemoteHost() + "', originalSecure='" + request.isSecure() diff --git a/java/org/apache/catalina/valves/RemoteIpValve.java b/java/org/apache/catalina/valves/RemoteIpValve.java index 145b095..9e78c0f 100644 --- a/java/org/apache/catalina/valves/RemoteIpValve.java +++ b/java/org/apache/catalina/valves/RemoteIpValve.java @@ -64,6 +64,8 @@ import org.apache.tomcat.util.http.MimeHeaders; * <code>protocolHeaderHttpsValue</code> configuration parameter (default <code>https</code>) then <code>request.isSecure = true</code>, * <code>request.scheme = https</code> and <code>request.serverPort = 443</code>. Note that 443 can be overwritten with the * <code>$httpsServerPort</code> configuration parameter.</li> + * <li>Mark the request with the attribute {@link Globals#FORWARDED_REQUEST_ATTRIBUTE} and value {@code Boolean.TRUE} to indicate + * that this request has been forwarded by one or more proxies.</li> * </ul> * <table border="1"> * <caption>Configuration parameters</caption> @@ -651,6 +653,8 @@ public class RemoteIpValve extends ValveBase { } } + request.setAttribute(Globals.FORWARDED_REQUEST_ATTRIBUTE, Boolean.TRUE); + if (log.isDebugEnabled()) { log.debug("Incoming request " + request.getRequestURI() + " with originalRemoteAddr '" + originalRemoteAddr + "', originalRemoteHost='" + originalRemoteHost + "', originalSecure='" + originalSecure + "', originalScheme='" diff --git a/java/org/apache/coyote/Constants.java b/java/org/apache/coyote/Constants.java index 9de194d..58fa1e5 100644 --- a/java/org/apache/coyote/Constants.java +++ b/java/org/apache/coyote/Constants.java @@ -111,4 +111,12 @@ public final class Constants { * the X-Forwarded-For HTTP header. */ public static final String REMOTE_ADDR_ATTRIBUTE = "org.apache.tomcat.remoteAddr"; + + /** + * The request attribute set by the RemoteIpFilter, RemoteIpValve (and may + * be set by other similar components) that identifies this request has been + * forwarded via one or more proxies. The value should be {@code java.lang.Boolean}. + * Absence shall be treated as {@code false}. + */ + public static final String FORWARDED_REQUEST_ATTRIBUTE = "org.apache.tomcat.forwardedRequest"; } diff --git a/test/org/apache/catalina/filters/TestRemoteIpFilter.java b/test/org/apache/catalina/filters/TestRemoteIpFilter.java index acfc881..e8323e9 100644 --- a/test/org/apache/catalina/filters/TestRemoteIpFilter.java +++ b/test/org/apache/catalina/filters/TestRemoteIpFilter.java @@ -42,6 +42,7 @@ import org.junit.Test; import org.apache.catalina.AccessLog; import org.apache.catalina.Context; +import org.apache.catalina.Globals; import org.apache.catalina.LifecycleException; import org.apache.catalina.connector.Connector; import org.apache.catalina.connector.Request; @@ -625,6 +626,28 @@ public class TestRemoteIpFilter extends TomcatBaseTest { actualRequest.getAttribute(AccessLog.REMOTE_HOST_ATTRIBUTE)); } + @Test + public void testRequestForwarded() throws Exception { + // PREPARE + FilterDef filterDef = new FilterDef(); + filterDef.addInitParameter("protocolHeader", "x-forwarded-proto"); + filterDef.addInitParameter("remoteIpHeader", "x-my-forwarded-for"); + filterDef.addInitParameter("httpServerPort", "8080"); + + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setRemoteAddr("192.168.0.10"); + request.setHeader("x-my-forwarded-for", "140.211.11.130"); + request.setHeader("x-forwarded-proto", "http"); + + // TEST + HttpServletRequest actualRequest = testRemoteIpFilter(filterDef, request).getRequest(); + + // VERIFY + Assert.assertEquals("org.apache.tomcat.forwardedRequest", + Boolean.TRUE, + actualRequest.getAttribute(Globals.FORWARDED_REQUEST_ATTRIBUTE)); + } + /* * Test {@link RemoteIpFilter} in Tomcat standalone server */ diff --git a/test/org/apache/catalina/valves/TestRemoteIpValve.java b/test/org/apache/catalina/valves/TestRemoteIpValve.java index 1778b5a..21d79d3 100644 --- a/test/org/apache/catalina/valves/TestRemoteIpValve.java +++ b/test/org/apache/catalina/valves/TestRemoteIpValve.java @@ -27,6 +27,7 @@ import org.junit.Assert; import org.junit.Test; import org.apache.catalina.AccessLog; +import org.apache.catalina.Globals; import org.apache.catalina.connector.Request; import org.apache.catalina.connector.Response; @@ -980,6 +981,35 @@ public class TestRemoteIpValve { request.getAttribute(AccessLog.REMOTE_HOST_ATTRIBUTE)); } + @Test + public void testRequestForwarded() throws Exception { + + // PREPARE + RemoteIpValve remoteIpValve = new RemoteIpValve(); + remoteIpValve.setRemoteIpHeader("x-forwarded-for"); + remoteIpValve.setProtocolHeader("x-forwarded-proto"); + RemoteAddrAndHostTrackerValve remoteAddrAndHostTrackerValve = new RemoteAddrAndHostTrackerValve(); + remoteIpValve.setNext(remoteAddrAndHostTrackerValve); + + Request request = new MockRequest(); + request.setCoyoteRequest(new org.apache.coyote.Request()); + // client ip + request.setRemoteAddr("192.168.0.10"); + request.setRemoteHost("192.168.0.10"); + request.getCoyoteRequest().getMimeHeaders().addValue("x-forwarded-for").setString("140.211.11.130"); + // protocol + request.setServerPort(8080); + request.getCoyoteRequest().scheme().setString("http"); + + // TEST + remoteIpValve.invoke(request, null); + + // VERIFY + Assert.assertEquals("org.apache.tomcat.forwardedRequest", + Boolean.TRUE, + request.getAttribute(Globals.FORWARDED_REQUEST_ATTRIBUTE)); + } + private void assertArrayEquals(String[] expected, String[] actual) { if (expected == null) { Assert.assertNull(actual); diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index d9d75bc..cb2e02d 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -45,6 +45,13 @@ issues do not "pop up" wrt. others). --> <section name="Tomcat 8.5.44 (markt)" rtext="in development"> + <subsection name="Catalina"> + <changelog> + <add> + <bug>XXX</bug>: Mark request as forwarded in RemoteIpValve/RemoteIpFilter (michaelo) + </add> + </changelog> + </subsection> <subsection name="Other"> <changelog> <update> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org