diff --git a/jetty-server/src/main/config/etc/jetty-http-forwarded.xml b/jetty-server/src/main/config/etc/jetty-http-forwarded.xml index 8d0047cc54d..2c843733c2a 100644 --- a/jetty-server/src/main/config/etc/jetty-http-forwarded.xml +++ b/jetty-server/src/main/config/etc/jetty-http-forwarded.xml @@ -6,13 +6,13 @@ + - diff --git a/jetty-server/src/main/config/modules/http-forwarded.mod b/jetty-server/src/main/config/modules/http-forwarded.mod index 7e6545a5902..e6303cd992e 100644 --- a/jetty-server/src/main/config/modules/http-forwarded.mod +++ b/jetty-server/src/main/config/modules/http-forwarded.mod @@ -16,15 +16,21 @@ etc/jetty-http-forwarded.xml [ini-template] ### ForwardedRequestCustomizer Configuration +## If true, only the RFC7239 Forwarded header is accepted # jetty.httpConfig.forwardedOnly=false + +## if true, the proxy address obtained from X-Forwarded-Server or RFC7239 is used as the request authority. # jetty.httpConfig.forwardedProxyAsAuthority=false + +## if true, the X-Forwarded-Port header applies to the authority, else it applies to the remote client address +# jetty.httpConfig.forwardedPortAsAuthority=true + # jetty.httpConfig.forwardedHeader=Forwarded # jetty.httpConfig.forwardedHostHeader=X-Forwarded-Host # jetty.httpConfig.forwardedServerHeader=X-Forwarded-Server # jetty.httpConfig.forwardedProtoHeader=X-Forwarded-Proto # jetty.httpConfig.forwardedForHeader=X-Forwarded-For # jetty.httpConfig.forwardedPortHeader=X-Forwarded-Port -# jetty.httpConfig.forwardedPortHeaderRemote=false # jetty.httpConfig.forwardedHttpsHeader=X-Proxied-Https # jetty.httpConfig.forwardedSslSessionIdHeader=Proxy-ssl-id # jetty.httpConfig.forwardedCipherSuiteHeader=Proxy-auth-cert diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ForwardedRequestCustomizer.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ForwardedRequestCustomizer.java index 171384bd672..141af6eaaf4 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/ForwardedRequestCustomizer.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ForwardedRequestCustomizer.java @@ -67,17 +67,17 @@ public class ForwardedRequestCustomizer implements Customizer private static final Logger LOG = Log.getLogger(ForwardedRequestCustomizer.class); private HostPortHttpField _forcedHost; + private boolean _proxyAsAuthority = false; + private boolean _forwardedPortAsAuthority = true; private String _forwardedHeader = HttpHeader.FORWARDED.toString(); private String _forwardedHostHeader = HttpHeader.X_FORWARDED_HOST.toString(); private String _forwardedServerHeader = HttpHeader.X_FORWARDED_SERVER.toString(); private String _forwardedProtoHeader = HttpHeader.X_FORWARDED_PROTO.toString(); private String _forwardedForHeader = HttpHeader.X_FORWARDED_FOR.toString(); private String _forwardedPortHeader = HttpHeader.X_FORWARDED_PORT.toString(); - private boolean _forwardedPortHeaderRemote = false; private String _forwardedHttpsHeader = "X-Proxied-Https"; private String _forwardedCipherSuiteHeader = "Proxy-auth-cert"; private String _forwardedSslSessionIdHeader = "Proxy-ssl-id"; - private boolean _proxyAsAuthority = false; private boolean _sslIsSecure = true; private Trie _handles; @@ -252,14 +252,23 @@ public class ForwardedRequestCustomizer implements Customizer } } - public boolean isForwardedPortHeaderRemote() + /** + * @return if true, the X-Forwarded-Port header applies to the authority, + * else it applies to the remote client address + */ + public boolean getForwardedPortAsAuthority() { - return _forwardedPortHeaderRemote; + return _forwardedPortAsAuthority; } - public void setForwardedPortHeaderRemote(boolean forwardedPortHeaderRemote) + /** + * Set if the X-Forwarded-Port header will be used for Authority + * @param forwardedPortAsAuthority if true, the X-Forwarded-Port header applies to the authority, + * else it applies to the remote client address + */ + public void setForwardedPortAsAuthority(boolean forwardedPortAsAuthority) { - _forwardedPortHeaderRemote = forwardedPortHeaderRemote; + _forwardedPortAsAuthority = forwardedPortAsAuthority; } /** @@ -563,7 +572,7 @@ public class ForwardedRequestCustomizer implements Customizer public void handleHost(HttpField field) { - if (!_forwardedPortHeaderRemote && !StringUtil.isEmpty(_forwardedPortHeader)) + if (_forwardedPortAsAuthority && !StringUtil.isEmpty(_forwardedPortHeader)) { if (_host == null) _host = new PossiblyPartialHostPort(getLeftMost(field.getValue())); @@ -591,7 +600,7 @@ public class ForwardedRequestCustomizer implements Customizer public void handleFor(HttpField field) { - if (_forwardedPortHeaderRemote && !StringUtil.isEmpty(_forwardedPortHeader)) + if (!_forwardedPortAsAuthority && !StringUtil.isEmpty(_forwardedPortHeader)) { if (_for == null) _for = new PossiblyPartialHostPort(getLeftMost(field.getValue())); @@ -606,7 +615,7 @@ public class ForwardedRequestCustomizer implements Customizer public void handlePort(HttpField field) { - if (_forwardedPortHeaderRemote) + if (!_forwardedPortAsAuthority) { if (_for == null) _for = new PortSetHostPort(_request.getRemoteHost(), field.getIntValue()); @@ -647,7 +656,7 @@ public class ForwardedRequestCustomizer implements Customizer break; if (value.startsWith("_") || "unknown".equals(value)) break; - if (_host == null || !(_host instanceof Rfc7239HostPort)) + if (_proxyAsAuthority && (_host == null || !(_host instanceof Rfc7239HostPort))) _host = new Rfc7239HostPort(value); break; case "for": diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ForwardedRequestCustomizerTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ForwardedRequestCustomizerTest.java index 61181da2efc..c5537eaa2e0 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/ForwardedRequestCustomizerTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ForwardedRequestCustomizerTest.java @@ -568,7 +568,7 @@ public class ForwardedRequestCustomizerTest @Test public void testRemote_Port_For() throws Exception { - _customizer.setForwardedPortHeaderRemote(true); + _customizer.setForwardedPortAsAuthority(false); HttpTester.Response response = HttpTester.parseResponse( _connector.getResponse( "GET / HTTP/1.1\n" +