Merge remote-tracking branch 'origin/jetty-9.4.x' into jetty-10.0.x

Signed-off-by: Greg Wilkins <gregw@webtide.com>
This commit is contained in:
Greg Wilkins 2019-06-17 17:51:39 +02:00
commit 965be32bda
7 changed files with 565 additions and 324 deletions

View File

@ -0,0 +1,4 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[depend]
alpn-impl/alpn-9

View File

@ -33,6 +33,13 @@
</exclusion> </exclusion>
</exclusions> </exclusions>
</dependency> </dependency>
<!-- avoid depending on a range dependency from a transitive dependency -->
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-core</artifactId>
<version>1.0.1</version>
<scope>compile</scope>
</dependency>
<dependency> <dependency>
<groupId>com.google.auto.value</groupId> <groupId>com.google.auto.value</groupId>
<artifactId>auto-value</artifactId> <artifactId>auto-value</artifactId>

View File

@ -6,6 +6,7 @@
<New class="org.eclipse.jetty.server.ForwardedRequestCustomizer"> <New class="org.eclipse.jetty.server.ForwardedRequestCustomizer">
<Set name="forwardedOnly"><Property name="jetty.httpConfig.forwardedOnly" default="false"/></Set> <Set name="forwardedOnly"><Property name="jetty.httpConfig.forwardedOnly" default="false"/></Set>
<Set name="proxyAsAuthority"><Property name="jetty.httpConfig.forwardedProxyAsAuthority" default="false"/></Set> <Set name="proxyAsAuthority"><Property name="jetty.httpConfig.forwardedProxyAsAuthority" default="false"/></Set>
<Set name="forwardedPortAsAuthority"><Property name="jetty.httpConfig.forwardedPortAsAuthority" default="true"/></Set>
<Set name="forwardedHeader"><Property name="jetty.httpConfig.forwardedHeader" default="Forwarded"/></Set> <Set name="forwardedHeader"><Property name="jetty.httpConfig.forwardedHeader" default="Forwarded"/></Set>
<Set name="forwardedHostHeader"><Property name="jetty.httpConfig.forwardedHostHeader" default="X-Forwarded-Host"/></Set> <Set name="forwardedHostHeader"><Property name="jetty.httpConfig.forwardedHostHeader" default="X-Forwarded-Host"/></Set>
<Set name="forwardedServerHeader"><Property name="jetty.httpConfig.forwardedServerHeader" default="X-Forwarded-Server"/></Set> <Set name="forwardedServerHeader"><Property name="jetty.httpConfig.forwardedServerHeader" default="X-Forwarded-Server"/></Set>

View File

@ -16,8 +16,15 @@ etc/jetty-http-forwarded.xml
[ini-template] [ini-template]
### ForwardedRequestCustomizer Configuration ### ForwardedRequestCustomizer Configuration
## If true, only the RFC7239 Forwarded header is accepted
# jetty.httpConfig.forwardedOnly=false # 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 # 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.forwardedHeader=Forwarded
# jetty.httpConfig.forwardedHostHeader=X-Forwarded-Host # jetty.httpConfig.forwardedHostHeader=X-Forwarded-Host
# jetty.httpConfig.forwardedServerHeader=X-Forwarded-Server # jetty.httpConfig.forwardedServerHeader=X-Forwarded-Server

View File

@ -22,7 +22,6 @@ import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType; import java.lang.invoke.MethodType;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import javax.servlet.ServletRequest; import javax.servlet.ServletRequest;
import org.eclipse.jetty.http.HostPortHttpField; import org.eclipse.jetty.http.HostPortHttpField;
@ -68,6 +67,8 @@ public class ForwardedRequestCustomizer implements Customizer
private static final Logger LOG = Log.getLogger(ForwardedRequestCustomizer.class); private static final Logger LOG = Log.getLogger(ForwardedRequestCustomizer.class);
private HostPortHttpField _forcedHost; private HostPortHttpField _forcedHost;
private boolean _proxyAsAuthority = false;
private boolean _forwardedPortAsAuthority = true;
private String _forwardedHeader = HttpHeader.FORWARDED.toString(); private String _forwardedHeader = HttpHeader.FORWARDED.toString();
private String _forwardedHostHeader = HttpHeader.X_FORWARDED_HOST.toString(); private String _forwardedHostHeader = HttpHeader.X_FORWARDED_HOST.toString();
private String _forwardedServerHeader = HttpHeader.X_FORWARDED_SERVER.toString(); private String _forwardedServerHeader = HttpHeader.X_FORWARDED_SERVER.toString();
@ -77,7 +78,6 @@ public class ForwardedRequestCustomizer implements Customizer
private String _forwardedHttpsHeader = "X-Proxied-Https"; private String _forwardedHttpsHeader = "X-Proxied-Https";
private String _forwardedCipherSuiteHeader = "Proxy-auth-cert"; private String _forwardedCipherSuiteHeader = "Proxy-auth-cert";
private String _forwardedSslSessionIdHeader = "Proxy-ssl-id"; private String _forwardedSslSessionIdHeader = "Proxy-ssl-id";
private boolean _proxyAsAuthority = false;
private boolean _sslIsSecure = true; private boolean _sslIsSecure = true;
private Trie<MethodHandle> _handles; private Trie<MethodHandle> _handles;
@ -252,6 +252,25 @@ public class ForwardedRequestCustomizer implements Customizer
} }
} }
/**
* @return if true, the X-Forwarded-Port header applies to the authority,
* else it applies to the remote client address
*/
public boolean getForwardedPortAsAuthority()
{
return _forwardedPortAsAuthority;
}
/**
* 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)
{
_forwardedPortAsAuthority = forwardedPortAsAuthority;
}
/** /**
* Get the forwardedProtoHeader. * Get the forwardedProtoHeader.
* *
@ -481,14 +500,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); 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); super(host, port);
} }
@ -543,14 +570,24 @@ public class ForwardedRequestCustomizer implements Customizer
public void handleHost(HttpField field) public void handleHost(HttpField field)
{ {
if (_host==null) if (_forwardedPortAsAuthority && !StringUtil.isEmpty(_forwardedPortHeader))
_host = new XHostPort(getLeftMost(field.getValue())); {
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) public void handleServer(HttpField field)
{ {
if (_proxyAsAuthority && _host==null) if (_proxyAsAuthority)
_host = new XHostPort(getLeftMost(field.getValue())); return;
handleHost(field);
} }
public void handleProto(HttpField field) public void handleProto(HttpField field)
@ -561,18 +598,35 @@ public class ForwardedRequestCustomizer implements Customizer
public void handleFor(HttpField field) public void handleFor(HttpField field)
{ {
if (_for==null) if (!_forwardedPortAsAuthority && !StringUtil.isEmpty(_forwardedPortHeader))
_for = new XHostPort(getLeftMost(field.getValue())); {
else if (_for instanceof XHostPort && "unknown".equals(_for.getHost())) if (_for == null)
_for = new XHostPort(HostPort.normalizeHost(getLeftMost(field.getValue())),_for.getPort()); _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) public void handlePort(HttpField field)
{ {
if (_for == null) if (!_forwardedPortAsAuthority)
_for = new XHostPort("unknown", field.getIntValue()); {
else if (_for instanceof XHostPort && _for.getPort()<=0) if (_for == null)
_for = new XHostPort(HostPort.normalizeHost(_for.getHost()), field.getIntValue()); _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());
}
} }
public void handleHttps(HttpField field) public void handleHttps(HttpField field)
@ -600,19 +654,19 @@ public class ForwardedRequestCustomizer implements Customizer
break; break;
if (value.startsWith("_") || "unknown".equals(value)) if (value.startsWith("_") || "unknown".equals(value))
break; break;
if (_host == null || _host instanceof XHostPort) if (_proxyAsAuthority && (_host == null || !(_host instanceof Rfc7239HostPort)))
_host = new Rfc7239HostPort(value); _host = new Rfc7239HostPort(value);
break; break;
case "for": case "for":
if (value.startsWith("_") || "unknown".equals(value)) if (value.startsWith("_") || "unknown".equals(value))
break; break;
if (_for == null || _for instanceof XHostPort) if (_for == null || !(_for instanceof Rfc7239HostPort))
_for = new Rfc7239HostPort(value); _for = new Rfc7239HostPort(value);
break; break;
case "host": case "host":
if (value.startsWith("_") || "unknown".equals(value)) if (value.startsWith("_") || "unknown".equals(value))
break; break;
if (_host == null || _host instanceof XHostPort) if (_host == null || !(_host instanceof Rfc7239HostPort))
_host = new Rfc7239HostPort(value); _host = new Rfc7239HostPort(value);
break; break;
case "proto": case "proto":

View File

@ -19,25 +19,20 @@
package org.eclipse.jetty.server; package org.eclipse.jetty.server;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.MimeTypes; import org.eclipse.jetty.http.HttpTester;
import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.util.IO;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.hamcrest.Matchers.is;
import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
@ -46,10 +41,15 @@ public class ForwardedRequestCustomizerTest
private Server _server; private Server _server;
private LocalConnector _connector; private LocalConnector _connector;
private RequestHandler _handler; private RequestHandler _handler;
final Deque<String> _results = new ArrayDeque<>();
final AtomicBoolean _wasSecure = new AtomicBoolean(false); final AtomicBoolean _wasSecure = new AtomicBoolean(false);
final AtomicReference<String> _sslSession = new AtomicReference<>(); final AtomicReference<String> _sslSession = new AtomicReference<>();
final AtomicReference<String> _sslCertificate = new AtomicReference<>(); final AtomicReference<String> _sslCertificate = new AtomicReference<>();
final AtomicReference<String> _scheme = new AtomicReference<>();
final AtomicReference<String> _serverName = new AtomicReference<>();
final AtomicReference<Integer> _serverPort = new AtomicReference<>();
final AtomicReference<String> _remoteAddr = new AtomicReference<>();
final AtomicReference<Integer> _remotePort = new AtomicReference<>();
final AtomicReference<String> _requestURL = new AtomicReference<>();
ForwardedRequestCustomizer _customizer; ForwardedRequestCustomizer _customizer;
@ -62,27 +62,24 @@ public class ForwardedRequestCustomizerTest
http.getHttpConfiguration().setRequestHeaderSize(512); http.getHttpConfiguration().setRequestHeaderSize(512);
http.getHttpConfiguration().setResponseHeaderSize(512); http.getHttpConfiguration().setResponseHeaderSize(512);
http.getHttpConfiguration().setOutputBufferSize(2048); http.getHttpConfiguration().setOutputBufferSize(2048);
http.getHttpConfiguration().addCustomizer(_customizer=new ForwardedRequestCustomizer()); http.getHttpConfiguration().addCustomizer(_customizer = new ForwardedRequestCustomizer());
_connector = new LocalConnector(_server,http); _connector = new LocalConnector(_server, http);
_server.addConnector(_connector); _server.addConnector(_connector);
_handler = new RequestHandler(); _handler = new RequestHandler();
_server.setHandler(_handler); _server.setHandler(_handler);
_handler._checker = new RequestTester() _handler._checker = (request, response) ->
{ {
@Override _wasSecure.set(request.isSecure());
public boolean check(HttpServletRequest request,HttpServletResponse response) _sslSession.set(String.valueOf(request.getAttribute("javax.servlet.request.ssl_session_id")));
{ _sslCertificate.set(String.valueOf(request.getAttribute("javax.servlet.request.cipher_suite")));
_wasSecure.set(request.isSecure()); _scheme.set(request.getScheme());
_sslSession.set(String.valueOf(request.getAttribute("javax.servlet.request.ssl_session_id"))); _serverName.set(request.getServerName());
_sslCertificate.set(String.valueOf(request.getAttribute("javax.servlet.request.cipher_suite"))); _serverPort.set(request.getServerPort());
_results.add(request.getScheme()); _remoteAddr.set(request.getRemoteAddr());
_results.add(request.getServerName()); _remotePort.set(request.getRemotePort());
_results.add(Integer.toString(request.getServerPort())); _requestURL.set(request.getRequestURL().toString());
_results.add(request.getRemoteAddr()); return true;
_results.add(Integer.toString(request.getRemotePort()));
return true;
}
}; };
_server.start(); _server.start();
@ -92,158 +89,214 @@ public class ForwardedRequestCustomizerTest
public void destroy() throws Exception public void destroy() throws Exception
{ {
_server.stop(); _server.stop();
_server.join();
} }
@Test @Test
public void testHostIpv4() throws Exception public void testHostIpv4() throws Exception
{ {
String response=_connector.getResponse( HttpTester.Response response = HttpTester.parseResponse(
"GET / HTTP/1.1\n"+ _connector.getResponse(
"Host: 1.2.3.4:2222\n"+ "GET / HTTP/1.1\n" +
"\n"); "Host: 1.2.3.4:2222\n" +
assertThat(response, Matchers.containsString("200 OK")); "\n"));
assertEquals("http",_results.poll()); assertThat("status", response.getStatus(), is(200));
assertEquals("1.2.3.4",_results.poll()); assertThat("scheme", _scheme.get(), is("http"));
assertEquals("2222",_results.poll()); assertThat("serverName", _serverName.get(), is("1.2.3.4"));
assertEquals("0.0.0.0",_results.poll()); assertThat("serverPort", _serverPort.get(), is(2222));
assertEquals("0",_results.poll()); assertThat("requestURL", _requestURL.get(), is("http://1.2.3.4:2222/"));
} }
@Test @Test
public void testHostIpv6() throws Exception public void testHostIpv6() throws Exception
{ {
String response=_connector.getResponse( HttpTester.Response response = HttpTester.parseResponse(
"GET / HTTP/1.1\n"+ _connector.getResponse(
"Host: [::1]:2222\n"+ "GET / HTTP/1.1\n" +
"\n"); "Host: [::1]:2222\n" +
assertThat(response, Matchers.containsString("200 OK")); "\n"));
assertEquals("http",_results.poll()); assertThat("status", response.getStatus(), is(200));
assertEquals("[::1]",_results.poll()); assertThat("scheme", _scheme.get(), is("http"));
assertEquals("2222",_results.poll()); assertThat("serverName", _serverName.get(), is("[::1]"));
assertEquals("0.0.0.0",_results.poll()); assertThat("serverPort", _serverPort.get(), is(2222));
assertEquals("0",_results.poll()); assertThat("requestURL", _requestURL.get(), is("http://[::1]:2222/"));
} }
@Test @Test
public void testURIIpv4() throws Exception public void testURIIpv4() throws Exception
{ {
String response=_connector.getResponse( HttpTester.Response response = HttpTester.parseResponse(
"GET http://1.2.3.4:2222/ HTTP/1.1\n"+ _connector.getResponse(
"Host: wrong\n"+ "GET http://1.2.3.4:2222/ HTTP/1.1\n" +
"\n"); "Host: wrong\n" +
assertThat(response, Matchers.containsString("200 OK")); "\n"));
assertEquals("http",_results.poll()); assertThat("status", response.getStatus(), is(200));
assertEquals("1.2.3.4",_results.poll()); assertThat("scheme", _scheme.get(), is("http"));
assertEquals("2222",_results.poll()); assertThat("serverName", _serverName.get(), is("1.2.3.4"));
assertEquals("0.0.0.0",_results.poll()); assertThat("serverPort", _serverPort.get(), is(2222));
assertEquals("0",_results.poll()); assertThat("requestURL", _requestURL.get(), is("http://1.2.3.4:2222/"));
} }
@Test @Test
public void testURIIpv6() throws Exception public void testURIIpv6() throws Exception
{ {
String response=_connector.getResponse( HttpTester.Response response = HttpTester.parseResponse(
"GET http://[::1]:2222/ HTTP/1.1\n"+ _connector.getResponse(
"Host: wrong\n"+ "GET http://[::1]:2222/ HTTP/1.1\n" +
"\n"); "Host: wrong\n" +
assertThat(response, Matchers.containsString("200 OK")); "\n"));
assertEquals("http",_results.poll()); assertThat("status", response.getStatus(), is(200));
assertEquals("[::1]",_results.poll()); assertThat("scheme", _scheme.get(), is("http"));
assertEquals("2222",_results.poll()); assertThat("serverName", _serverName.get(), is("[::1]"));
assertEquals("0.0.0.0",_results.poll()); assertThat("serverPort", _serverPort.get(), is(2222));
assertEquals("0",_results.poll()); assertThat("requestURL", _requestURL.get(), is("http://[::1]:2222/"));
} }
/**
* <a href="https://tools.ietf.org/html/rfc7239#section-4">RFC 7239: Section 4</a>
*
* Examples of syntax.
*/
@Test @Test
public void testRFC7239_Examples_4() throws Exception public void testRFC7239_Examples_4() throws Exception
{ {
String response=_connector.getResponse( HttpTester.Response response = HttpTester.parseResponse(
"GET / HTTP/1.1\n"+ _connector.getResponse(
"Host: myhost\n"+ "GET / HTTP/1.1\n" +
"Forwarded: for=\"_gazonk\"\n"+ "Host: myhost\n" +
"Forwarded: For=\"[2001:db8:cafe::17]:4711\"\n"+ "Forwarded: for=\"_gazonk\"\n" +
"Forwarded: for=192.0.2.60;proto=http;by=203.0.113.43\n"+ "Forwarded: For=\"[2001:db8:cafe::17]:4711\"\n" +
"Forwarded: for=192.0.2.43, for=198.51.100.17\n"+ "Forwarded: for=192.0.2.60;proto=http;by=203.0.113.43\n" +
"\n"); "Forwarded: for=192.0.2.43, for=198.51.100.17\n" +
assertThat(response, Matchers.containsString("200 OK")); "\n"));
assertEquals("http",_results.poll()); assertThat("status", response.getStatus(), is(200));
assertEquals("myhost",_results.poll()); assertThat("scheme", _scheme.get(), is("http"));
assertEquals("80",_results.poll()); assertThat("serverName", _serverName.get(), is("myhost"));
assertEquals("[2001:db8:cafe::17]",_results.poll()); assertThat("serverPort", _serverPort.get(), is(80));
assertEquals("4711",_results.poll()); assertThat("remoteAddr", _remoteAddr.get(), is("[2001:db8:cafe::17]"));
assertThat("remotePort", _remotePort.get(), is(4711));
assertThat("requestURL", _requestURL.get(), is("http://myhost/"));
} }
/**
* <a href="https://tools.ietf.org/html/rfc7239#section-7.1">RFC 7239: Section 7.1</a>
*
* Examples of syntax with regards to HTTP header fields
*/
@Test @Test
public void testRFC7239_Examples_7_1() throws Exception public void testRFC7239_Examples_7_1() throws Exception
{ {
_connector.getResponse( // Without spaces
"GET / HTTP/1.1\n"+ HttpTester.Response response1 = HttpTester.parseResponse(
"Host: myhost\n"+ _connector.getResponse(
"Forwarded: for=192.0.2.43,for=\"[2001:db8:cafe::17]\",for=unknown\n"+ "GET / HTTP/1.1\n" +
"\n"); "Host: myhost\n" +
_connector.getResponse( "Forwarded: for=192.0.2.43,for=\"[2001:db8:cafe::17]\",for=unknown\n" +
"GET / HTTP/1.1\n"+ "\n"));
"Host: myhost\n"+
"Forwarded: for=192.0.2.43, for=\"[2001:db8:cafe::17]\", for=unknown\n"+
"\n");
_connector.getResponse(
"GET / HTTP/1.1\n"+
"Host: myhost\n"+
"Forwarded: for=192.0.2.43\n"+
"Forwarded: for=\"[2001:db8:cafe::17]\", for=unknown\n"+
"\n");
assertEquals("http",_results.poll()); assertThat("status", response1.getStatus(), is(200));
assertEquals("myhost",_results.poll()); assertThat("scheme", _scheme.get(), is("http"));
assertEquals("80",_results.poll()); assertThat("serverName", _serverName.get(), is("myhost"));
assertEquals("192.0.2.43",_results.poll()); assertThat("serverPort", _serverPort.get(), is(80));
assertEquals("0",_results.poll()); assertThat("remoteAddr", _remoteAddr.get(), is("192.0.2.43"));
assertEquals("http",_results.poll()); assertThat("remotePort", _remotePort.get(), is(0));
assertEquals("myhost",_results.poll()); assertThat("requestURL", _requestURL.get(), is("http://myhost/"));
assertEquals("80",_results.poll());
assertEquals("192.0.2.43",_results.poll()); // With spaces
assertEquals("0",_results.poll()); HttpTester.Response response2 = HttpTester.parseResponse(
assertEquals("http",_results.poll()); _connector.getResponse(
assertEquals("myhost",_results.poll()); "GET / HTTP/1.1\n" +
assertEquals("80",_results.poll()); "Host: myhost\n" +
assertEquals("192.0.2.43",_results.poll()); "Forwarded: for=192.0.2.43, for=\"[2001:db8:cafe::17]\", for=unknown\n" +
assertEquals("0",_results.poll()); "\n"));
assertThat("status", response2.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.0.2.43"));
assertThat("remotePort", _remotePort.get(), is(0));
assertThat("requestURL", _requestURL.get(), is("http://myhost/"));
// As multiple headers
HttpTester.Response response3 = HttpTester.parseResponse(
_connector.getResponse(
"GET / HTTP/1.1\n" +
"Host: myhost\n" +
"Forwarded: for=192.0.2.43\n" +
"Forwarded: for=\"[2001:db8:cafe::17]\", for=unknown\n" +
"\n"));
assertThat("status", response3.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.0.2.43"));
assertThat("remotePort", _remotePort.get(), is(0));
assertThat("requestURL", _requestURL.get(), is("http://myhost/"));
} }
/**
* <a href="https://tools.ietf.org/html/rfc7239#section-7.4">RFC 7239: Section 7.4</a>
*
* Transition
*/
@Test @Test
public void testRFC7239_Examples_7_4() throws Exception public void testRFC7239_Examples_7_4() throws Exception
{ {
_connector.getResponse( // Old syntax
"GET / HTTP/1.1\n"+ HttpTester.Response response1 = HttpTester.parseResponse(
"Host: myhost\n"+ _connector.getResponse(
"Forwarded: for=192.0.2.43, for=\"[2001:db8:cafe::17]\"\n"+ "GET / HTTP/1.1\n" +
"\n"); "Host: myhost\n" +
"X-Forwarded-For: 192.0.2.43, 2001:db8:cafe::17\n" +
"\n"));
assertEquals("http",_results.poll()); assertThat("status", response1.getStatus(), is(200));
assertEquals("myhost",_results.poll()); assertThat("scheme", _scheme.get(), is("http"));
assertEquals("80",_results.poll()); assertThat("serverName", _serverName.get(), is("myhost"));
assertEquals("192.0.2.43",_results.poll()); assertThat("serverPort", _serverPort.get(), is(80));
assertEquals("0",_results.poll()); assertThat("remoteAddr", _remoteAddr.get(), is("192.0.2.43"));
assertThat("remotePort", _remotePort.get(), is(0));
assertThat("requestURL", _requestURL.get(), is("http://myhost/"));
// New syntax
HttpTester.Response response2 = HttpTester.parseResponse(
_connector.getResponse(
"GET / HTTP/1.1\n" +
"Host: myhost\n" +
"Forwarded: for=192.0.2.43, for=\"[2001:db8:cafe::17]\"\n" +
"\n"));
assertThat("status", response2.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.0.2.43"));
assertThat("remotePort", _remotePort.get(), is(0));
assertThat("requestURL", _requestURL.get(), is("http://myhost/"));
} }
/**
* <a href="https://tools.ietf.org/html/rfc7239#section-7.5">RFC 7239: Section 7.5</a>
*
* Example Usage
*/
@Test @Test
public void testRFC7239_Examples_7_5() throws Exception public void testRFC7239_Examples_7_5() throws Exception
{ {
_connector.getResponse( HttpTester.Response response = HttpTester.parseResponse(
"GET / HTTP/1.1\n"+ _connector.getResponse(
"Host: myhost\n"+ "GET / HTTP/1.1\n" +
"Forwarded: for=192.0.2.43,for=198.51.100.17;by=203.0.113.60;proto=http;host=example.com\n"+ "Host: myhost\n" +
"\n"); "Forwarded: for=192.0.2.43,for=198.51.100.17;by=203.0.113.60;proto=http;host=example.com\n" +
"\n"));
assertEquals("http",_results.poll()); assertThat("status", response.getStatus(), is(200));
assertEquals("example.com",_results.poll()); assertThat("scheme", _scheme.get(), is("http"));
assertEquals("80",_results.poll()); assertThat("serverName", _serverName.get(), is("example.com"));
assertEquals("192.0.2.43",_results.poll()); assertThat("serverPort", _serverPort.get(), is(80));
assertEquals("0",_results.poll()); assertThat("remoteAddr", _remoteAddr.get(), is("192.0.2.43"));
assertThat("remotePort", _remotePort.get(), is(0));
assertThat("requestURL", _requestURL.get(), is("http://example.com/"));
} }
@Test @Test
@ -263,236 +316,350 @@ public class ForwardedRequestCustomizerTest
} }
@Test @Test
public void testProto() throws Exception public void testProto_OldSyntax() throws Exception
{ {
String response=_connector.getResponse( HttpTester.Response response = HttpTester.parseResponse(
"GET / HTTP/1.1\n"+ _connector.getResponse(
"Host: myhost\n"+ "GET / HTTP/1.1\n" +
"X-Forwarded-Proto: foobar\n"+ "Host: myhost\n" +
"Forwarded: proto=https\n"+ "X-Forwarded-Proto: https\n" +
"\n"); "\n"));
assertThat(response, Matchers.containsString("200 OK"));
assertEquals("https",_results.poll()); assertTrue(_wasSecure.get(), "wasSecure");
assertEquals("myhost",_results.poll()); assertThat("status", response.getStatus(), is(200));
assertEquals("443",_results.poll()); assertThat("scheme", _scheme.get(), is("https"));
assertEquals("0.0.0.0",_results.poll()); assertThat("serverName", _serverName.get(), is("myhost"));
assertEquals("0",_results.poll()); assertThat("serverPort", _serverPort.get(), is(443));
assertThat("remoteAddr", _remoteAddr.get(), is("0.0.0.0"));
assertThat("remotePort", _remotePort.get(), is(0));
assertThat("requestURL", _requestURL.get(), is("https://myhost/"));
}
@Test
public void testRFC7239_Proto() throws Exception
{
HttpTester.Response response = HttpTester.parseResponse(
_connector.getResponse(
"GET / HTTP/1.1\n" +
"Host: myhost\n" +
"Forwarded: proto=https\n" +
"\n"));
assertTrue(_wasSecure.get(), "wasSecure");
assertThat("status", response.getStatus(), is(200));
assertThat("scheme", _scheme.get(), is("https"));
assertThat("serverName", _serverName.get(), is("myhost"));
assertThat("serverPort", _serverPort.get(), is(443));
assertThat("remoteAddr", _remoteAddr.get(), is("0.0.0.0"));
assertThat("remotePort", _remotePort.get(), is(0));
assertThat("requestURL", _requestURL.get(), is("https://myhost/"));
} }
@Test @Test
public void testFor() throws Exception public void testFor() throws Exception
{ {
String response=_connector.getResponse( HttpTester.Response response = HttpTester.parseResponse(
"GET / HTTP/1.1\n"+ _connector.getResponse(
"Host: myhost\n"+ "GET / HTTP/1.1\n" +
"X-Forwarded-For: 10.9.8.7,6.5.4.3\n"+ "Host: myhost\n" +
"X-Forwarded-For: 8.9.8.7,7.5.4.3\n"+ "X-Forwarded-For: 10.9.8.7,6.5.4.3\n" +
"\n"); "X-Forwarded-For: 8.9.8.7,7.5.4.3\n" +
assertThat(response, Matchers.containsString("200 OK")); "\n"));
assertEquals("http",_results.poll());
assertEquals("myhost",_results.poll()); assertThat("status", response.getStatus(), is(200));
assertEquals("80",_results.poll()); assertThat("scheme", _scheme.get(), is("http"));
assertEquals("10.9.8.7",_results.poll()); assertThat("serverName", _serverName.get(), is("myhost"));
assertEquals("0",_results.poll()); assertThat("serverPort", _serverPort.get(), is(80));
assertThat("remoteAddr", _remoteAddr.get(), is("10.9.8.7"));
assertThat("remotePort", _remotePort.get(), is(0));
assertThat("requestURL", _requestURL.get(), is("http://myhost/"));
} }
@Test @Test
public void testForIpv4WithPort() throws Exception public void testForIpv4WithPort() throws Exception
{ {
String response=_connector.getResponse( HttpTester.Response response = HttpTester.parseResponse(
"GET / HTTP/1.1\n"+ _connector.getResponse(
"Host: myhost\n"+ "GET / HTTP/1.1\n" +
"X-Forwarded-For: 10.9.8.7:1111,6.5.4.3:2222\n"+ "Host: myhost\n" +
"\n"); "X-Forwarded-For: 10.9.8.7:1111,6.5.4.3:2222\n" +
assertThat(response, Matchers.containsString("200 OK")); "\n"));
assertEquals("http",_results.poll());
assertEquals("myhost",_results.poll()); assertThat("status", response.getStatus(), is(200));
assertEquals("80",_results.poll()); assertThat("scheme", _scheme.get(), is("http"));
assertEquals("10.9.8.7",_results.poll()); assertThat("serverName", _serverName.get(), is("myhost"));
assertEquals("1111",_results.poll()); assertThat("serverPort", _serverPort.get(), is(80));
assertThat("remoteAddr", _remoteAddr.get(), is("10.9.8.7"));
assertThat("remotePort", _remotePort.get(), is(1111));
assertThat("requestURL", _requestURL.get(), is("http://myhost/"));
} }
@Test @Test
public void testForIpv6WithPort() throws Exception public void testForIpv6WithPort() throws Exception
{ {
String response=_connector.getResponse( HttpTester.Response response = HttpTester.parseResponse(
"GET / HTTP/1.1\n"+ _connector.getResponse(
"Host: myhost\n"+ "GET / HTTP/1.1\n" +
"X-Forwarded-For: [2001:db8:cafe::17]:1111,6.5.4.3:2222\n"+ "Host: myhost\n" +
"\n"); "X-Forwarded-For: [2001:db8:cafe::17]:1111,6.5.4.3:2222\n" +
assertThat(response, Matchers.containsString("200 OK")); "\n"));
assertEquals("http",_results.poll());
assertEquals("myhost",_results.poll()); assertThat("status", response.getStatus(), is(200));
assertEquals("80",_results.poll()); assertThat("scheme", _scheme.get(), is("http"));
assertEquals("[2001:db8:cafe::17]",_results.poll()); assertThat("serverName", _serverName.get(), is("myhost"));
assertEquals("1111",_results.poll()); assertThat("serverPort", _serverPort.get(), is(80));
assertThat("remoteAddr", _remoteAddr.get(), is("[2001:db8:cafe::17]"));
assertThat("remotePort", _remotePort.get(), is(1111));
assertThat("requestURL", _requestURL.get(), is("http://myhost/"));
} }
@Test @Test
public void testForIpv6AndPort() throws Exception public void testForIpv6AndPort() throws Exception
{ {
String response=_connector.getResponse( HttpTester.Response response = HttpTester.parseResponse(
"GET / HTTP/1.1\n"+ _connector.getResponse(
"Host: myhost\n"+ "GET / HTTP/1.1\n" +
"X-Forwarded-For: 1:2:3:4:5:6:7:8\n"+ "Host: myhost\n" +
"X-Forwarded-Port: 2222\n"+ "X-Forwarded-For: 1:2:3:4:5:6:7:8\n" +
"\n"); "X-Forwarded-Port: 2222\n" +
assertThat(response, Matchers.containsString("200 OK")); "\n"));
assertEquals("http",_results.poll());
assertEquals("myhost",_results.poll());
assertEquals("80",_results.poll());
assertEquals("[1:2:3:4:5:6:7:8]",_results.poll());
assertEquals("2222",_results.poll());
response=_connector.getResponse( assertThat("status", response.getStatus(), is(200));
"GET / HTTP/1.1\n"+ assertThat("scheme", _scheme.get(), is("http"));
"Host: myhost\n"+ assertThat("serverName", _serverName.get(), is("myhost"));
"X-Forwarded-Port: 2222\n"+ assertThat("serverPort", _serverPort.get(), is(2222));
"X-Forwarded-For: 1:2:3:4:5:6:7:8\n"+ assertThat("remoteAddr", _remoteAddr.get(), is("[1:2:3:4:5:6:7:8]"));
"X-Forwarded-For: 7:7:7:7:7:7:7:7\n"+ assertThat("remotePort", _remotePort.get(), is(0));
"X-Forwarded-Port: 3333\n"+ assertThat("requestURL", _requestURL.get(), is("http://myhost:2222/"));
"\n"); }
assertThat(response, Matchers.containsString("200 OK"));
assertEquals("http",_results.poll()); @Test
assertEquals("myhost",_results.poll()); public void testForIpv6AndPort_MultiField() throws Exception
assertEquals("80",_results.poll()); {
assertEquals("[1:2:3:4:5:6:7:8]",_results.poll()); HttpTester.Response response = HttpTester.parseResponse(
assertEquals("2222",_results.poll()); _connector.getResponse(
"GET / HTTP/1.1\n" +
"Host: myhost\n" +
"X-Forwarded-Port: 2222\n" +
"X-Forwarded-For: 1:2:3:4:5:6:7:8\n" +
"X-Forwarded-For: 7:7:7:7:7:7:7:7\n" +
"X-Forwarded-Port: 3333\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(2222));
assertThat("remoteAddr", _remoteAddr.get(), is("[1:2:3:4:5:6:7:8]"));
assertThat("remotePort", _remotePort.get(), is(0));
assertThat("requestURL", _requestURL.get(), is("http://myhost:2222/"));
} }
@Test @Test
public void testLegacyProto() throws Exception public void testLegacyProto() throws Exception
{ {
String response=_connector.getResponse( HttpTester.Response response = HttpTester.parseResponse(
"GET / HTTP/1.1\n"+ _connector.getResponse(
"Host: myhost\n"+ "GET / HTTP/1.1\n" +
"X-Proxied-Https: on\n"+ "Host: myhost\n" +
"\n"); "X-Proxied-Https: on\n" +
assertThat(response, Matchers.containsString("200 OK")); "\n"));
assertEquals("https",_results.poll()); assertTrue(_wasSecure.get(), "wasSecure");
assertEquals("myhost",_results.poll()); assertThat("status", response.getStatus(), is(200));
assertEquals("443",_results.poll()); assertThat("scheme", _scheme.get(), is("https"));
assertEquals("0.0.0.0",_results.poll()); assertThat("serverName", _serverName.get(), is("myhost"));
assertEquals("0",_results.poll()); assertThat("serverPort", _serverPort.get(), is(443));
assertTrue(_wasSecure.get()); assertThat("remoteAddr", _remoteAddr.get(), is("0.0.0.0"));
assertThat("remotePort", _remotePort.get(), is(0));
assertThat("requestURL", _requestURL.get(), is("https://myhost/"));
} }
@Test @Test
public void testSslSession() throws Exception public void testSslSession() throws Exception
{ {
_customizer.setSslIsSecure(false); _customizer.setSslIsSecure(false);
String response=_connector.getResponse( HttpTester.Response response = HttpTester.parseResponse(
"GET / HTTP/1.1\n"+ _connector.getResponse(
"Host: myhost\n"+ "GET / HTTP/1.1\n" +
"Proxy-Ssl-Id: Wibble\n"+ "Host: myhost\n" +
"\n"); "Proxy-Ssl-Id: Wibble\n" +
"\n"));
assertThat(response, Matchers.containsString("200 OK")); assertFalse(_wasSecure.get(), "wasSecure");
assertEquals("http",_results.poll()); assertThat("sslSession", _sslSession.get(), is("Wibble"));
assertEquals("myhost",_results.poll()); assertThat("status", response.getStatus(), is(200));
assertEquals("80",_results.poll()); assertThat("scheme", _scheme.get(), is("http"));
assertEquals("0.0.0.0",_results.poll()); assertThat("serverName", _serverName.get(), is("myhost"));
assertEquals("0",_results.poll()); assertThat("serverPort", _serverPort.get(), is(80));
assertFalse(_wasSecure.get()); assertThat("remoteAddr", _remoteAddr.get(), is("0.0.0.0"));
assertEquals("Wibble",_sslSession.get()); assertThat("remotePort", _remotePort.get(), is(0));
assertThat("requestURL", _requestURL.get(), is("http://myhost/"));
_customizer.setSslIsSecure(true); _customizer.setSslIsSecure(true);
response=_connector.getResponse( response = HttpTester.parseResponse(
"GET / HTTP/1.1\n"+ _connector.getResponse(
"Host: myhost\n"+ "GET / HTTP/1.1\n" +
"Proxy-Ssl-Id: 0123456789abcdef\n"+ "Host: myhost\n" +
"\n"); "Proxy-Ssl-Id: 0123456789abcdef\n" +
"\n"));
assertThat(response, Matchers.containsString("200 OK")); assertTrue(_wasSecure.get(), "wasSecure");
assertEquals("https",_results.poll()); assertThat("sslSession", _sslSession.get(), is("0123456789abcdef"));
assertEquals("myhost",_results.poll()); assertThat("status", response.getStatus(), is(200));
assertEquals("443",_results.poll()); assertThat("scheme", _scheme.get(), is("https"));
assertEquals("0.0.0.0",_results.poll()); assertThat("serverName", _serverName.get(), is("myhost"));
assertEquals("0",_results.poll()); assertThat("serverPort", _serverPort.get(), is(443));
assertTrue(_wasSecure.get()); assertThat("remoteAddr", _remoteAddr.get(), is("0.0.0.0"));
assertEquals("0123456789abcdef",_sslSession.get()); assertThat("remotePort", _remotePort.get(), is(0));
assertThat("requestURL", _requestURL.get(), is("https://myhost/"));
} }
@Test @Test
public void testSslCertificate() throws Exception public void testSslCertificate() throws Exception
{ {
_customizer.setSslIsSecure(false); _customizer.setSslIsSecure(false);
String response=_connector.getResponse( HttpTester.Response response = HttpTester.parseResponse(
"GET / HTTP/1.1\n"+ _connector.getResponse(
"Host: myhost\n"+ "GET / HTTP/1.1\n" +
"Proxy-auth-cert: Wibble\n"+ "Host: myhost\n" +
"\n"); "Proxy-auth-cert: Wibble\n" +
"\n"));
assertThat(response, Matchers.containsString("200 OK"));
assertEquals("http",_results.poll());
assertEquals("myhost",_results.poll());
assertEquals("80",_results.poll());
assertEquals("0.0.0.0",_results.poll());
assertEquals("0",_results.poll());
assertFalse(_wasSecure.get());
assertEquals("Wibble",_sslCertificate.get());
assertFalse(_wasSecure.get(), "wasSecure");
assertThat("sslCertificate", _sslCertificate.get(), is("Wibble"));
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("0.0.0.0"));
assertThat("remotePort", _remotePort.get(), is(0));
assertThat("requestURL", _requestURL.get(), is("http://myhost/"));
_customizer.setSslIsSecure(true); _customizer.setSslIsSecure(true);
response=_connector.getResponse( response = HttpTester.parseResponse(
"GET / HTTP/1.1\n"+ _connector.getResponse(
"Host: myhost\n"+ "GET / HTTP/1.1\n" +
"Proxy-auth-cert: 0123456789abcdef\n"+ "Host: myhost\n" +
"\n"); "Proxy-auth-cert: 0123456789abcdef\n" +
"\n"));
assertThat(response, Matchers.containsString("200 OK")); assertTrue(_wasSecure.get(), "wasSecure");
assertEquals("https",_results.poll()); assertThat("sslCertificate", _sslCertificate.get(), is("0123456789abcdef"));
assertEquals("myhost",_results.poll()); assertThat("status", response.getStatus(), is(200));
assertEquals("443",_results.poll()); assertThat("scheme", _scheme.get(), is("https"));
assertEquals("0.0.0.0",_results.poll()); assertThat("serverName", _serverName.get(), is("myhost"));
assertEquals("0",_results.poll()); assertThat("serverPort", _serverPort.get(), is(443));
assertTrue(_wasSecure.get()); assertThat("remoteAddr", _remoteAddr.get(), is("0.0.0.0"));
assertEquals("0123456789abcdef",_sslCertificate.get()); assertThat("remotePort", _remotePort.get(), is(0));
assertThat("requestURL", _requestURL.get(), is("https://myhost/"));
}
/**
* Resetting the server port via a forwarding header
*/
@Test
public void testPort_For() throws Exception
{
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(4444));
assertThat("remoteAddr", _remoteAddr.get(), is("192.168.1.200"));
assertThat("remotePort", _remotePort.get(), is(0));
assertThat("requestURL", _requestURL.get(), is("http://myhost:4444/"));
} }
/**
* Resetting the server port via a forwarding header
*/
@Test @Test
public void testMixed() throws Exception public void testRemote_Port_For() throws Exception
{ {
String response = _connector.getResponse( _customizer.setForwardedPortAsAuthority(false);
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.
*/
@Test
public void testPort_For_LateHost() throws Exception
{
HttpTester.Response response = HttpTester.parseResponse(
_connector.getResponse(
"GET / HTTP/1.1\n" +
"X-Forwarded-Port: 4444\n" + // this order is intentional
"X-Forwarded-For: 192.168.1.200\n" +
"Host: myhost\n" + // leave this as the last header
"\n"));
assertThat("status", response.getStatus(), is(200));
assertThat("scheme", _scheme.get(), is("http"));
assertThat("serverName", _serverName.get(), is("myhost"));
assertThat("serverPort", _serverPort.get(), is(4444));
assertThat("remoteAddr", _remoteAddr.get(), is("192.168.1.200"));
assertThat("remotePort", _remotePort.get(), is(0));
assertThat("requestURL", _requestURL.get(), is("http://myhost:4444/"));
}
@Test
public void testMixed_For_Port_RFC_For() throws Exception
{
HttpTester.Response response = HttpTester.parseResponse(
_connector.getResponse(
"GET / HTTP/1.1\n" + "GET / HTTP/1.1\n" +
"Host: myhost\n" + "Host: myhost\n" +
"X-Forwarded-For: 11.9.8.7:1111,8.5.4.3:2222\n" + "X-Forwarded-For: 11.9.8.7:1111,8.5.4.3:2222\n" +
"X-Forwarded-Port: 3333\n" + "X-Forwarded-Port: 3333\n" +
"Forwarded: for=192.0.2.43,for=198.51.100.17;by=203.0.113.60;proto=http;host=example.com\n"+ "Forwarded: for=192.0.2.43,for=198.51.100.17;by=203.0.113.60;proto=http;host=example.com\n" +
"X-Forwarded-For: 11.9.8.7:1111,8.5.4.3:2222\n" + "X-Forwarded-For: 11.9.8.7:1111,8.5.4.3:2222\n" +
"\n"); "\n"));
assertEquals("http",_results.poll()); assertThat("status", response.getStatus(), is(200));
assertEquals("example.com",_results.poll()); assertThat("scheme", _scheme.get(), is("http"));
assertEquals("80",_results.poll()); assertThat("serverName", _serverName.get(), is("example.com"));
assertEquals("192.0.2.43",_results.poll()); assertThat("serverPort", _serverPort.get(), is(80));
assertEquals("0",_results.poll()); assertThat("remoteAddr", _remoteAddr.get(), is("192.0.2.43"));
assertThat("remotePort", _remotePort.get(), is(0));
assertThat("requestURL", _requestURL.get(), is("http://example.com/"));
} }
interface RequestTester interface RequestTester
{ {
boolean check(HttpServletRequest request,HttpServletResponse response) throws IOException; boolean check(HttpServletRequest request, HttpServletResponse response) throws IOException;
} }
private class RequestHandler extends AbstractHandler private class RequestHandler extends AbstractHandler
{ {
private RequestTester _checker; private RequestTester _checker;
@SuppressWarnings("unused")
private String _content;
@Override @Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{ {
((Request)request).setHandled(true); baseRequest.setHandled(true);
if (request.getContentLength()>0 if (_checker != null && _checker.check(request, response))
&& !MimeTypes.Type.FORM_ENCODED.asString().equals(request.getContentType())
&& !request.getContentType().startsWith("multipart/form-data"))
_content=IO.toString(request.getInputStream());
if (_checker!=null && _checker.check(request,response))
response.setStatus(200); response.setStatus(200);
else else
response.sendError(500); response.sendError(500);

View File

@ -1,4 +1,5 @@
org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
org.eclipse.jetty.LEVEL=WARN
#org.eclipse.jetty.LEVEL=DEBUG #org.eclipse.jetty.LEVEL=DEBUG
#org.eclipse.jetty.server.LEVEL=DEBUG #org.eclipse.jetty.server.LEVEL=DEBUG
#org.eclipse.jetty.server.ConnectionLimit.LEVEL=DEBUG #org.eclipse.jetty.server.ConnectionLimit.LEVEL=DEBUG