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 db8a9ad64e0..5c38e601d52 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 @@ -19,25 +19,20 @@ package org.eclipse.jetty.server; import java.io.IOException; -import java.util.ArrayDeque; -import java.util.Deque; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; - import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; 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.util.IO; -import org.hamcrest.Matchers; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; 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.assertTrue; @@ -46,11 +41,15 @@ public class ForwardedRequestCustomizerTest private Server _server; private LocalConnector _connector; private RequestHandler _handler; - final Deque _results = new ArrayDeque<>(); final AtomicBoolean _wasSecure = new AtomicBoolean(false); final AtomicReference _sslSession = new AtomicReference<>(); final AtomicReference _sslCertificate = new AtomicReference<>(); - + final AtomicReference _scheme = new AtomicReference<>(); + final AtomicReference _serverName = new AtomicReference<>(); + final AtomicReference _serverPort = new AtomicReference<>(); + final AtomicReference _remoteAddr = new AtomicReference<>(); + final AtomicReference _remotePort = new AtomicReference<>(); + ForwardedRequestCustomizer _customizer; @BeforeEach @@ -62,29 +61,25 @@ public class ForwardedRequestCustomizerTest http.getHttpConfiguration().setRequestHeaderSize(512); http.getHttpConfiguration().setResponseHeaderSize(512); http.getHttpConfiguration().setOutputBufferSize(2048); - http.getHttpConfiguration().addCustomizer(_customizer=new ForwardedRequestCustomizer()); - _connector = new LocalConnector(_server,http); + http.getHttpConfiguration().addCustomizer(_customizer = new ForwardedRequestCustomizer()); + _connector = new LocalConnector(_server, http); _server.addConnector(_connector); _handler = new RequestHandler(); _server.setHandler(_handler); - _handler._checker = new RequestTester() + _handler._checker = (request, response) -> { - @Override - public boolean check(HttpServletRequest request,HttpServletResponse response) - { - _wasSecure.set(request.isSecure()); - _sslSession.set(String.valueOf(request.getAttribute("javax.servlet.request.ssl_session_id"))); - _sslCertificate.set(String.valueOf(request.getAttribute("javax.servlet.request.cipher_suite"))); - _results.add(request.getScheme()); - _results.add(request.getServerName()); - _results.add(Integer.toString(request.getServerPort())); - _results.add(request.getRemoteAddr()); - _results.add(Integer.toString(request.getRemotePort())); - return true; - } + _wasSecure.set(request.isSecure()); + _sslSession.set(String.valueOf(request.getAttribute("javax.servlet.request.ssl_session_id"))); + _sslCertificate.set(String.valueOf(request.getAttribute("javax.servlet.request.cipher_suite"))); + _scheme.set(request.getScheme()); + _serverName.set(request.getServerName()); + _serverPort.set(request.getServerPort()); + _remoteAddr.set(request.getRemoteAddr()); + _remotePort.set(request.getRemotePort()); + return true; }; - + _server.start(); } @@ -92,391 +87,468 @@ public class ForwardedRequestCustomizerTest public void destroy() throws Exception { _server.stop(); - _server.join(); } @Test public void testHostIpv4() throws Exception { - String response=_connector.getResponse( - "GET / HTTP/1.1\n"+ - "Host: 1.2.3.4:2222\n"+ - "\n"); - assertThat(response, Matchers.containsString("200 OK")); - assertEquals("http",_results.poll()); - assertEquals("1.2.3.4",_results.poll()); - assertEquals("2222",_results.poll()); - assertEquals("0.0.0.0",_results.poll()); - assertEquals("0",_results.poll()); + HttpTester.Response response = HttpTester.parseResponse( + _connector.getResponse( + "GET / HTTP/1.1\n" + + "Host: 1.2.3.4:2222\n" + + "\n")); + assertThat("status", response.getStatus(), is(200)); + assertThat("scheme", _scheme.get(), is("http")); + assertThat("serverName", _serverName.get(), is("1.2.3.4")); + assertThat("serverPort", _serverPort.get(), is(2222)); } @Test public void testHostIpv6() throws Exception { - String response=_connector.getResponse( - "GET / HTTP/1.1\n"+ - "Host: [::1]:2222\n"+ - "\n"); - assertThat(response, Matchers.containsString("200 OK")); - assertEquals("http",_results.poll()); - assertEquals("[::1]",_results.poll()); - assertEquals("2222",_results.poll()); - assertEquals("0.0.0.0",_results.poll()); - assertEquals("0",_results.poll()); + HttpTester.Response response = HttpTester.parseResponse( + _connector.getResponse( + "GET / HTTP/1.1\n" + + "Host: [::1]:2222\n" + + "\n")); + assertThat("status", response.getStatus(), is(200)); + assertThat("scheme", _scheme.get(), is("http")); + assertThat("serverName", _serverName.get(), is("[::1]")); + assertThat("serverPort", _serverPort.get(), is(2222)); } - - @Test public void testURIIpv4() throws Exception { - String response=_connector.getResponse( - "GET http://1.2.3.4:2222/ HTTP/1.1\n"+ - "Host: wrong\n"+ - "\n"); - assertThat(response, Matchers.containsString("200 OK")); - assertEquals("http",_results.poll()); - assertEquals("1.2.3.4",_results.poll()); - assertEquals("2222",_results.poll()); - assertEquals("0.0.0.0",_results.poll()); - assertEquals("0",_results.poll()); + HttpTester.Response response = HttpTester.parseResponse( + _connector.getResponse( + "GET http://1.2.3.4:2222/ HTTP/1.1\n" + + "Host: wrong\n" + + "\n")); + assertThat("status", response.getStatus(), is(200)); + assertThat("scheme", _scheme.get(), is("http")); + assertThat("serverName", _serverName.get(), is("1.2.3.4")); + assertThat("serverPort", _serverPort.get(), is(2222)); } @Test public void testURIIpv6() throws Exception { - String response=_connector.getResponse( - "GET http://[::1]:2222/ HTTP/1.1\n"+ - "Host: wrong\n"+ - "\n"); - assertThat(response, Matchers.containsString("200 OK")); - assertEquals("http",_results.poll()); - assertEquals("[::1]",_results.poll()); - assertEquals("2222",_results.poll()); - assertEquals("0.0.0.0",_results.poll()); - assertEquals("0",_results.poll()); + HttpTester.Response response = HttpTester.parseResponse( + _connector.getResponse( + "GET http://[::1]:2222/ HTTP/1.1\n" + + "Host: wrong\n" + + "\n")); + assertThat("status", response.getStatus(), is(200)); + assertThat("scheme", _scheme.get(), is("http")); + assertThat("serverName", _serverName.get(), is("[::1]")); + assertThat("serverPort", _serverPort.get(), is(2222)); } - + /** + * RFC 7239: Section 4 + * + * Examples of syntax. + */ @Test public void testRFC7239_Examples_4() throws Exception { - String response=_connector.getResponse( - "GET / HTTP/1.1\n"+ - "Host: myhost\n"+ - "Forwarded: for=\"_gazonk\"\n"+ - "Forwarded: For=\"[2001:db8:cafe::17]:4711\"\n"+ - "Forwarded: for=192.0.2.60;proto=http;by=203.0.113.43\n"+ - "Forwarded: for=192.0.2.43, for=198.51.100.17\n"+ - "\n"); - assertThat(response, Matchers.containsString("200 OK")); - assertEquals("http",_results.poll()); - assertEquals("myhost",_results.poll()); - assertEquals("80",_results.poll()); - assertEquals("[2001:db8:cafe::17]",_results.poll()); - assertEquals("4711",_results.poll()); + HttpTester.Response response = HttpTester.parseResponse( + _connector.getResponse( + "GET / HTTP/1.1\n" + + "Host: myhost\n" + + "Forwarded: for=\"_gazonk\"\n" + + "Forwarded: For=\"[2001:db8:cafe::17]:4711\"\n" + + "Forwarded: for=192.0.2.60;proto=http;by=203.0.113.43\n" + + "Forwarded: for=192.0.2.43, for=198.51.100.17\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("[2001:db8:cafe::17]")); + assertThat("remotePort", _remotePort.get(), is(4711)); } - + + /** + * RFC 7239: Section 7.1 + * + * Examples of syntax with regards to HTTP header fields + */ @Test public void testRFC7239_Examples_7_1() throws Exception { - _connector.getResponse( - "GET / HTTP/1.1\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, 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"); + // Without spaces + HttpTester.Response response1 = HttpTester.parseResponse( + _connector.getResponse( + "GET / HTTP/1.1\n" + + "Host: myhost\n" + + "Forwarded: for=192.0.2.43,for=\"[2001:db8:cafe::17]\",for=unknown\n" + + "\n")); - assertEquals("http",_results.poll()); - assertEquals("myhost",_results.poll()); - assertEquals("80",_results.poll()); - assertEquals("192.0.2.43",_results.poll()); - assertEquals("0",_results.poll()); - assertEquals("http",_results.poll()); - assertEquals("myhost",_results.poll()); - assertEquals("80",_results.poll()); - assertEquals("192.0.2.43",_results.poll()); - assertEquals("0",_results.poll()); - assertEquals("http",_results.poll()); - assertEquals("myhost",_results.poll()); - assertEquals("80",_results.poll()); - assertEquals("192.0.2.43",_results.poll()); - assertEquals("0",_results.poll()); + assertThat("status", response1.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)); + + // With spaces + 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]\", for=unknown\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)); + + // 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)); } + /** + * RFC 7239: Section 7.4 + * + * Transition + */ @Test public void testRFC7239_Examples_7_4() throws Exception { - _connector.getResponse( - "GET / HTTP/1.1\n"+ - "Host: myhost\n"+ - "Forwarded: for=192.0.2.43, for=\"[2001:db8:cafe::17]\"\n"+ - "\n"); + // Old syntax + HttpTester.Response response1 = HttpTester.parseResponse( + _connector.getResponse( + "GET / HTTP/1.1\n" + + "Host: myhost\n" + + "X-Forwarded-For: 192.0.2.43, 2001:db8:cafe::17\n" + + "\n")); - assertEquals("http",_results.poll()); - assertEquals("myhost",_results.poll()); - assertEquals("80",_results.poll()); - assertEquals("192.0.2.43",_results.poll()); - assertEquals("0",_results.poll()); + assertThat("status", response1.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)); + + // 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)); } + /** + * RFC 7239: Section 7.5 + * + * Example Usage + */ @Test public void testRFC7239_Examples_7_5() throws Exception { - _connector.getResponse( - "GET / HTTP/1.1\n"+ - "Host: myhost\n"+ - "Forwarded: for=192.0.2.43,for=198.51.100.17;by=203.0.113.60;proto=http;host=example.com\n"+ - "\n"); + HttpTester.Response response = HttpTester.parseResponse( + _connector.getResponse( + "GET / HTTP/1.1\n" + + "Host: myhost\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()); - assertEquals("example.com",_results.poll()); - assertEquals("80",_results.poll()); - assertEquals("192.0.2.43",_results.poll()); - assertEquals("0",_results.poll()); + assertThat("status", response.getStatus(), is(200)); + assertThat("scheme", _scheme.get(), is("http")); + assertThat("serverName", _serverName.get(), is("example.com")); + assertThat("serverPort", _serverPort.get(), is(80)); + assertThat("remoteAddr", _remoteAddr.get(), is("192.0.2.43")); + assertThat("remotePort", _remotePort.get(), is(0)); } @Test - public void testProto() throws Exception + public void testProto_OldSyntax() throws Exception { - String response=_connector.getResponse( - "GET / HTTP/1.1\n"+ - "Host: myhost\n"+ - "X-Forwarded-Proto: foobar\n"+ - "Forwarded: proto=https\n"+ - "\n"); - assertThat(response, Matchers.containsString("200 OK")); - assertEquals("https",_results.poll()); - assertEquals("myhost",_results.poll()); - assertEquals("443",_results.poll()); - assertEquals("0.0.0.0",_results.poll()); - assertEquals("0",_results.poll()); + HttpTester.Response response = HttpTester.parseResponse( + _connector.getResponse( + "GET / HTTP/1.1\n" + + "Host: myhost\n" + + "X-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)); + } + + @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)); } @Test public void testFor() throws Exception { - String response=_connector.getResponse( - "GET / HTTP/1.1\n"+ - "Host: myhost\n"+ - "X-Forwarded-For: 10.9.8.7,6.5.4.3\n"+ - "X-Forwarded-For: 8.9.8.7,7.5.4.3\n"+ - "\n"); - assertThat(response, Matchers.containsString("200 OK")); - assertEquals("http",_results.poll()); - assertEquals("myhost",_results.poll()); - assertEquals("80",_results.poll()); - assertEquals("10.9.8.7",_results.poll()); - assertEquals("0",_results.poll()); + HttpTester.Response response = HttpTester.parseResponse( + _connector.getResponse( + "GET / HTTP/1.1\n" + + "Host: myhost\n" + + "X-Forwarded-For: 10.9.8.7,6.5.4.3\n" + + "X-Forwarded-For: 8.9.8.7,7.5.4.3\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("10.9.8.7")); + assertThat("remotePort", _remotePort.get(), is(0)); } @Test public void testForIpv4WithPort() throws Exception { - String response=_connector.getResponse( - "GET / HTTP/1.1\n"+ - "Host: myhost\n"+ - "X-Forwarded-For: 10.9.8.7:1111,6.5.4.3:2222\n"+ - "\n"); - assertThat(response, Matchers.containsString("200 OK")); - assertEquals("http",_results.poll()); - assertEquals("myhost",_results.poll()); - assertEquals("80",_results.poll()); - assertEquals("10.9.8.7",_results.poll()); - assertEquals("1111",_results.poll()); + HttpTester.Response response = HttpTester.parseResponse( + _connector.getResponse( + "GET / HTTP/1.1\n" + + "Host: myhost\n" + + "X-Forwarded-For: 10.9.8.7:1111,6.5.4.3:2222\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("10.9.8.7")); + assertThat("remotePort", _remotePort.get(), is(1111)); } @Test public void testForIpv6WithPort() throws Exception { - String response=_connector.getResponse( - "GET / HTTP/1.1\n"+ - "Host: myhost\n"+ - "X-Forwarded-For: [2001:db8:cafe::17]:1111,6.5.4.3:2222\n"+ - "\n"); - assertThat(response, Matchers.containsString("200 OK")); - assertEquals("http",_results.poll()); - assertEquals("myhost",_results.poll()); - assertEquals("80",_results.poll()); - assertEquals("[2001:db8:cafe::17]",_results.poll()); - assertEquals("1111",_results.poll()); + HttpTester.Response response = HttpTester.parseResponse( + _connector.getResponse( + "GET / HTTP/1.1\n" + + "Host: myhost\n" + + "X-Forwarded-For: [2001:db8:cafe::17]:1111,6.5.4.3:2222\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("[2001:db8:cafe::17]")); + assertThat("remotePort", _remotePort.get(), is(1111)); } @Test public void testForIpv6AndPort() throws Exception { - String response=_connector.getResponse( - "GET / HTTP/1.1\n"+ - "Host: myhost\n"+ - "X-Forwarded-For: 1:2:3:4:5:6:7:8\n"+ - "X-Forwarded-Port: 2222\n"+ - "\n"); - assertThat(response, Matchers.containsString("200 OK")); - 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()); + HttpTester.Response response = HttpTester.parseResponse( + _connector.getResponse( + "GET / HTTP/1.1\n" + + "Host: myhost\n" + + "X-Forwarded-For: 1:2:3:4:5:6:7:8\n" + + "X-Forwarded-Port: 2222\n" + + "\n")); - response=_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(response, Matchers.containsString("200 OK")); - 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()); + 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("[1:2:3:4:5:6:7:8]")); + assertThat("remotePort", _remotePort.get(), is(2222)); + } + + @Test + public void testForIpv6AndPort_MultiField() throws Exception + { + HttpTester.Response response = HttpTester.parseResponse( + _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(80)); + assertThat("remoteAddr", _remoteAddr.get(), is("[1:2:3:4:5:6:7:8]")); + assertThat("remotePort", _remotePort.get(), is(2222)); } @Test public void testLegacyProto() throws Exception { - String response=_connector.getResponse( - "GET / HTTP/1.1\n"+ - "Host: myhost\n"+ - "X-Proxied-Https: on\n"+ - "\n"); - assertThat(response, Matchers.containsString("200 OK")); - assertEquals("https",_results.poll()); - assertEquals("myhost",_results.poll()); - assertEquals("443",_results.poll()); - assertEquals("0.0.0.0",_results.poll()); - assertEquals("0",_results.poll()); - assertTrue(_wasSecure.get()); + HttpTester.Response response = HttpTester.parseResponse( + _connector.getResponse( + "GET / HTTP/1.1\n" + + "Host: myhost\n" + + "X-Proxied-Https: on\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)); } @Test public void testSslSession() throws Exception { _customizer.setSslIsSecure(false); - String response=_connector.getResponse( - "GET / HTTP/1.1\n"+ - "Host: myhost\n"+ - "Proxy-Ssl-Id: 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",_sslSession.get()); - - _customizer.setSslIsSecure(true); - response=_connector.getResponse( - "GET / HTTP/1.1\n"+ - "Host: myhost\n"+ - "Proxy-Ssl-Id: 0123456789abcdef\n"+ - "\n"); - - assertThat(response, Matchers.containsString("200 OK")); - assertEquals("https",_results.poll()); - assertEquals("myhost",_results.poll()); - assertEquals("443",_results.poll()); - assertEquals("0.0.0.0",_results.poll()); - assertEquals("0",_results.poll()); - assertTrue(_wasSecure.get()); - assertEquals("0123456789abcdef",_sslSession.get()); + HttpTester.Response response = HttpTester.parseResponse( + _connector.getResponse( + "GET / HTTP/1.1\n" + + "Host: myhost\n" + + "Proxy-Ssl-Id: Wibble\n" + + "\n")); + + assertFalse(_wasSecure.get(), "wasSecure"); + assertThat("sslSession", _sslSession.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)); + + _customizer.setSslIsSecure(true); + response = HttpTester.parseResponse( + _connector.getResponse( + "GET / HTTP/1.1\n" + + "Host: myhost\n" + + "Proxy-Ssl-Id: 0123456789abcdef\n" + + "\n")); + + assertTrue(_wasSecure.get(), "wasSecure"); + assertThat("sslSession", _sslSession.get(), is("0123456789abcdef")); + 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)); } - + @Test public void testSslCertificate() throws Exception { _customizer.setSslIsSecure(false); - String response=_connector.getResponse( - "GET / HTTP/1.1\n"+ - "Host: myhost\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()); - - - _customizer.setSslIsSecure(true); - response=_connector.getResponse( - "GET / HTTP/1.1\n"+ - "Host: myhost\n"+ - "Proxy-auth-cert: 0123456789abcdef\n"+ - "\n"); - - assertThat(response, Matchers.containsString("200 OK")); - assertEquals("https",_results.poll()); - assertEquals("myhost",_results.poll()); - assertEquals("443",_results.poll()); - assertEquals("0.0.0.0",_results.poll()); - assertEquals("0",_results.poll()); - assertTrue(_wasSecure.get()); - assertEquals("0123456789abcdef",_sslCertificate.get()); + HttpTester.Response response = HttpTester.parseResponse( + _connector.getResponse( + "GET / HTTP/1.1\n" + + "Host: myhost\n" + + "Proxy-auth-cert: Wibble\n" + + "\n")); + + 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)); + + _customizer.setSslIsSecure(true); + response = HttpTester.parseResponse( + _connector.getResponse( + "GET / HTTP/1.1\n" + + "Host: myhost\n" + + "Proxy-auth-cert: 0123456789abcdef\n" + + "\n")); + + assertTrue(_wasSecure.get(), "wasSecure"); + assertThat("sslCertificate", _sslCertificate.get(), is("0123456789abcdef")); + 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)); } - @Test - public void testMixed() throws Exception + public void testMixed_For_Port_RFC_For() throws Exception { - String response = _connector.getResponse( + HttpTester.Response response = HttpTester.parseResponse( + _connector.getResponse( "GET / HTTP/1.1\n" + "Host: myhost\n" + "X-Forwarded-For: 11.9.8.7:1111,8.5.4.3:2222\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" + - "\n"); + "\n")); - assertEquals("http",_results.poll()); - assertEquals("example.com",_results.poll()); - assertEquals("80",_results.poll()); - assertEquals("192.0.2.43",_results.poll()); - assertEquals("0",_results.poll()); + assertThat("status", response.getStatus(), is(200)); + assertThat("scheme", _scheme.get(), is("http")); + assertThat("serverName", _serverName.get(), is("example.com")); + assertThat("serverPort", _serverPort.get(), is(80)); + assertThat("remoteAddr", _remoteAddr.get(), is("192.0.2.43")); + assertThat("remotePort", _remotePort.get(), is(0)); } - - + interface RequestTester { - boolean check(HttpServletRequest request,HttpServletResponse response) throws IOException; + boolean check(HttpServletRequest request, HttpServletResponse response) throws IOException; } private class RequestHandler extends AbstractHandler { private RequestTester _checker; - @SuppressWarnings("unused") - private String _content; @Override 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 - && !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)) + if (_checker != null && _checker.check(request, response)) response.setStatus(200); else response.sendError(500);