Issue #3782 X-Forwarded-Port can be remote or local
Added option for X-Forwarded-Port to be remote or local with default being local. Signed-off-by: Greg Wilkins <gregw@webtide.com>
This commit is contained in:
parent
345750f9fd
commit
9cf8cf3c0d
|
@ -12,6 +12,7 @@
|
|||
<Set name="forwardedProtoHeader"><Property name="jetty.httpConfig.forwardedProtoHeader" default="X-Forwarded-Proto"/></Set>
|
||||
<Set name="forwardedForHeader"><Property name="jetty.httpConfig.forwardedForHeader" default="X-Forwarded-For"/></Set>
|
||||
<Set name="forwardedPortHeader"><Property name="jetty.httpConfig.forwardedPortHeader" default="X-Forwarded-Port"/></Set>
|
||||
<Set name="forwardedPortHeaderRemote"><Property name="jetty.httpConfig.forwardedPortHeaderRemote" default="false"/></Set>
|
||||
<Set name="forwardedHttpsHeader"><Property name="jetty.httpConfig.forwardedHttpsHeader" default="X-Proxied-Https"/></Set>
|
||||
<Set name="forwardedSslSessionIdHeader"><Property name="jetty.httpConfig.forwardedSslSessionIdHeader" default="Proxy-ssl-id" /></Set>
|
||||
<Set name="forwardedCipherSuiteHeader"><Property name="jetty.httpConfig.forwardedCipherSuiteHeader" default="Proxy-auth-cert"/></Set>
|
||||
|
|
|
@ -24,6 +24,7 @@ etc/jetty-http-forwarded.xml
|
|||
# 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
|
||||
|
|
|
@ -73,6 +73,7 @@ public class ForwardedRequestCustomizer implements Customizer
|
|||
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";
|
||||
|
@ -251,6 +252,16 @@ public class ForwardedRequestCustomizer implements Customizer
|
|||
}
|
||||
}
|
||||
|
||||
public boolean isForwardedPortHeaderRemote()
|
||||
{
|
||||
return _forwardedPortHeaderRemote;
|
||||
}
|
||||
|
||||
public void setForwardedPortHeaderRemote(boolean forwardedPortHeaderRemote)
|
||||
{
|
||||
_forwardedPortHeaderRemote = forwardedPortHeaderRemote;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the forwardedProtoHeader.
|
||||
*
|
||||
|
@ -447,8 +458,6 @@ public class ForwardedRequestCustomizer implements Customizer
|
|||
size += 128;
|
||||
_handles = new ArrayTrie<>(size);
|
||||
|
||||
_handles.put(HttpHeader.HOST.toString(), lookup.findVirtual(Forwarded.class, "handleHttpHost", type));
|
||||
|
||||
if (_forwardedCipherSuiteHeader != null && !_handles.put(_forwardedCipherSuiteHeader, lookup.findVirtual(Forwarded.class, "handleCipherSuite", type)))
|
||||
continue;
|
||||
if (_forwardedSslSessionIdHeader != null && !_handles.put(_forwardedSslSessionIdHeader, lookup.findVirtual(Forwarded.class, "handleSslSessionId", type)))
|
||||
|
@ -484,14 +493,22 @@ public class ForwardedRequestCustomizer implements Customizer
|
|||
}
|
||||
}
|
||||
|
||||
private static class XHostPort extends HostPort
|
||||
private static class PossiblyPartialHostPort extends HostPort
|
||||
{
|
||||
XHostPort(String authority)
|
||||
PossiblyPartialHostPort(String authority)
|
||||
{
|
||||
super(authority);
|
||||
}
|
||||
|
||||
XHostPort(String host, int port)
|
||||
protected PossiblyPartialHostPort(String host, int port)
|
||||
{
|
||||
super(host, port);
|
||||
}
|
||||
}
|
||||
|
||||
private static class PortSetHostPort extends PossiblyPartialHostPort
|
||||
{
|
||||
PortSetHostPort(String host, int port)
|
||||
{
|
||||
super(host, port);
|
||||
}
|
||||
|
@ -514,7 +531,6 @@ public class ForwardedRequestCustomizer implements Customizer
|
|||
String _proto;
|
||||
HostPort _for;
|
||||
HostPort _host;
|
||||
HostPort _httpHost;
|
||||
|
||||
public Forwarded(Request request, HttpConfiguration config)
|
||||
{
|
||||
|
@ -525,13 +541,6 @@ public class ForwardedRequestCustomizer implements Customizer
|
|||
_host = _forcedHost.getHostPort();
|
||||
}
|
||||
|
||||
public void handleHttpHost(HttpField field)
|
||||
{
|
||||
_httpHost = new HostPort(field.getValue());
|
||||
if (_host != null && _host instanceof XHostPort && "unknown".equals(_host.getHost()))
|
||||
_host = new XHostPort(_httpHost.getHost(), _host.getPort());
|
||||
}
|
||||
|
||||
public void handleCipherSuite(HttpField field)
|
||||
{
|
||||
_request.setAttribute("javax.servlet.request.cipher_suite", field.getValue());
|
||||
|
@ -554,16 +563,24 @@ public class ForwardedRequestCustomizer implements Customizer
|
|||
|
||||
public void handleHost(HttpField field)
|
||||
{
|
||||
if (_host==null)
|
||||
_host = new XHostPort(getLeftMost(field.getValue()));
|
||||
else if (_host instanceof XHostPort && "unknown".equals(_host.getHost()))
|
||||
_host = new XHostPort(getLeftMost(field.getValue()), _host.getPort());
|
||||
if (!_forwardedPortHeaderRemote && !StringUtil.isEmpty(_forwardedPortHeader))
|
||||
{
|
||||
if (_host == null)
|
||||
_host = new PossiblyPartialHostPort(getLeftMost(field.getValue()));
|
||||
else if (_for instanceof PortSetHostPort)
|
||||
_host = new HostPort(HostPort.normalizeHost(getLeftMost(field.getValue())), _host.getPort());
|
||||
}
|
||||
else if (_host==null)
|
||||
{
|
||||
_host = new HostPort(getLeftMost(field.getValue()));
|
||||
}
|
||||
}
|
||||
|
||||
public void handleServer(HttpField field)
|
||||
{
|
||||
if (_proxyAsAuthority && _host==null)
|
||||
_host = new XHostPort(getLeftMost(field.getValue()));
|
||||
if (_proxyAsAuthority)
|
||||
return;
|
||||
handleHost(field);
|
||||
}
|
||||
|
||||
public void handleProto(HttpField field)
|
||||
|
@ -574,21 +591,35 @@ public class ForwardedRequestCustomizer implements Customizer
|
|||
|
||||
public void handleFor(HttpField field)
|
||||
{
|
||||
if (_for==null)
|
||||
_for = new XHostPort(getLeftMost(field.getValue()));
|
||||
else if (_for instanceof XHostPort && "unknown".equals(_for.getHost()))
|
||||
_for = new XHostPort(HostPort.normalizeHost(getLeftMost(field.getValue())),_for.getPort());
|
||||
if (_forwardedPortHeaderRemote && !StringUtil.isEmpty(_forwardedPortHeader))
|
||||
{
|
||||
if (_for == null)
|
||||
_for = new PossiblyPartialHostPort(getLeftMost(field.getValue()));
|
||||
else if (_for instanceof PortSetHostPort)
|
||||
_for = new HostPort(HostPort.normalizeHost(getLeftMost(field.getValue())), _for.getPort());
|
||||
}
|
||||
else if (_for == null)
|
||||
{
|
||||
_for = new HostPort(getLeftMost(field.getValue()));
|
||||
}
|
||||
}
|
||||
|
||||
public void handlePort(HttpField field)
|
||||
{
|
||||
if (_host == null)
|
||||
if (_forwardedPortHeaderRemote)
|
||||
{
|
||||
String hostname = _httpHost != null ? _httpHost.getHost() : "unknown";
|
||||
_host = new XHostPort(hostname, field.getIntValue());
|
||||
if (_for == null)
|
||||
_for = new PortSetHostPort(_request.getRemoteHost(), field.getIntValue());
|
||||
else if (_for instanceof PossiblyPartialHostPort && _for.getPort() <= 0)
|
||||
_for = new HostPort(HostPort.normalizeHost(_for.getHost()), field.getIntValue());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_host == null)
|
||||
_host = new PortSetHostPort(_request.getServerName(), field.getIntValue());
|
||||
else if (_host instanceof PossiblyPartialHostPort && _host.getPort() <= 0)
|
||||
_host = new HostPort(HostPort.normalizeHost(_host.getHost()), field.getIntValue());
|
||||
}
|
||||
else if (_host instanceof XHostPort && _host.getPort()<=0)
|
||||
_host = new XHostPort(HostPort.normalizeHost(_host.getHost()), field.getIntValue());
|
||||
}
|
||||
|
||||
public void handleHttps(HttpField field)
|
||||
|
@ -616,19 +647,19 @@ public class ForwardedRequestCustomizer implements Customizer
|
|||
break;
|
||||
if (value.startsWith("_") || "unknown".equals(value))
|
||||
break;
|
||||
if (_host == null || _host instanceof XHostPort)
|
||||
if (_host == null || !(_host instanceof Rfc7239HostPort))
|
||||
_host = new Rfc7239HostPort(value);
|
||||
break;
|
||||
case "for":
|
||||
if (value.startsWith("_") || "unknown".equals(value))
|
||||
break;
|
||||
if (_for == null || _for instanceof XHostPort)
|
||||
if (_for == null || !(_for instanceof Rfc7239HostPort))
|
||||
_for = new Rfc7239HostPort(value);
|
||||
break;
|
||||
case "host":
|
||||
if (value.startsWith("_") || "unknown".equals(value))
|
||||
break;
|
||||
if (_host == null || _host instanceof XHostPort)
|
||||
if (_host == null || !(_host instanceof Rfc7239HostPort))
|
||||
_host = new Rfc7239HostPort(value);
|
||||
break;
|
||||
case "proto":
|
||||
|
|
|
@ -560,6 +560,31 @@ public class ForwardedRequestCustomizerTest
|
|||
assertThat("requestURL", _requestURL.get(), is("http://myhost:4444/"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Resetting the server port via a forwarding header
|
||||
*/
|
||||
@Test
|
||||
public void testRemote_Port_For() throws Exception
|
||||
{
|
||||
_customizer.setForwardedPortHeaderRemote(true);
|
||||
HttpTester.Response response = HttpTester.parseResponse(
|
||||
_connector.getResponse(
|
||||
"GET / HTTP/1.1\n" +
|
||||
"Host: myhost\n" +
|
||||
"X-Forwarded-Port: 4444\n" +
|
||||
"X-Forwarded-For: 192.168.1.200\n" +
|
||||
"\n"));
|
||||
assertThat("status", response.getStatus(), is(200));
|
||||
assertThat("scheme", _scheme.get(), is("http"));
|
||||
assertThat("serverName", _serverName.get(), is("myhost"));
|
||||
assertThat("serverPort", _serverPort.get(), is(80));
|
||||
assertThat("remoteAddr", _remoteAddr.get(), is("192.168.1.200"));
|
||||
assertThat("remotePort", _remotePort.get(), is(4444));
|
||||
assertThat("requestURL", _requestURL.get(), is("http://myhost/"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test setting the server Port before the "Host" header has been seen.
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue