Skip to content

Commit

Permalink
Improved the parsing of the host and port in vertx
Browse files Browse the repository at this point in the history
bobbyphilip authored and gsmet committed Oct 27, 2020
1 parent b874fc2 commit 0494ca9
Showing 2 changed files with 110 additions and 28 deletions.
Original file line number Diff line number Diff line change
@@ -16,23 +16,93 @@ public class ForwardedForHeaderTest {

@RegisterExtension
static final QuarkusUnitTest config = new QuarkusUnitTest()
.setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class)
.addClasses(ForwardedHandlerInitializer.class)
.addAsResource(new StringAsset("quarkus.http.proxy-address-forwarding=true\n" +
"quarkus.http.proxy.enable-forwarded-host=true\n"),
"application.properties"));
.setArchiveProducer(
() -> ShrinkWrap.create(JavaArchive.class).addClasses(ForwardedHandlerInitializer.class)
.addAsResource(
new StringAsset("quarkus.http.proxy.proxy-address-forwarding=true\n"
+ "quarkus.http.proxy.enable-forwarded-host=true\n"),
"application.properties"));

@Test
public void test() {
assertThat(RestAssured.get("/forward").asString()).startsWith("http|");

RestAssured.given()
.header("X-Forwarded-Proto", "https")
.header("X-Forwarded-For", "backend:4444")
.header("X-Forwarded-Host", "somehost")
.get("/forward")
.then()
RestAssured.given().header("X-Forwarded-Proto", "https").header("X-Forwarded-For", "backend:4444")
.header("X-Forwarded-Host", "somehost").get("/forward").then()
.body(Matchers.equalTo("https|somehost|backend:4444"));
}

@Test
public void testIPV4WithPort() {
assertThat(RestAssured.get("/forward").asString()).startsWith("http|");

RestAssured.given().header("X-Forwarded-Proto", "https").header("X-Forwarded-For", "192.168.42.123:4444")
.header("X-Forwarded-Host", "somehost").get("/forward").then()
.body(Matchers.equalTo("https|somehost|192.168.42.123:4444"));
}

@Test
public void testIPV4NoPort() {
assertThat(RestAssured.get("/forward").asString()).startsWith("http|");

RestAssured.given().header("X-Forwarded-Proto", "https").header("X-Forwarded-For", "192.168.42.123")
.header("X-Forwarded-Host", "somehost").get("/forward").then()
.body(Matchers.containsString("192.168.42.123"));
}

@Test
public void testIPV6() {
assertThat(RestAssured.get("/forward").asString()).startsWith("http|");

RestAssured.given().header("X-Forwarded-Proto", "https")
.header("X-Forwarded-For", "2001:db8:85a3:8d3:1319:8a2e:370:12").header("X-Forwarded-Host", "somehost")
.get("/forward").then().body(Matchers.containsString("2001:db8:85a3:8d3:1319:8a2e:370:12"));
}

@Test
public void testIPV6HexEnding() {
assertThat(RestAssured.get("/forward").asString()).startsWith("http|");

RestAssured.given().header("X-Forwarded-Proto", "https")
.header("X-Forwarded-For", "2001:db8:85a3:8d3:1319:8a2e:370:ac").header("X-Forwarded-Host", "somehost")
.get("/forward").then().body(Matchers.containsString("2001:db8:85a3:8d3:1319:8a2e:370:ac"));
}

@Test
public void testIPV6Compressed() {
assertThat(RestAssured.get("/forward").asString()).startsWith("http|");

RestAssured.given().header("X-Forwarded-Proto", "https").header("X-Forwarded-For", "2001:db8:85a3::12")
.header("X-Forwarded-Host", "somehost").get("/forward").then()
.body(Matchers.containsString("2001:db8:85a3::12"));
}

@Test
public void testIPV6AnotherCompressed() {
assertThat(RestAssured.get("/forward").asString()).startsWith("http|");

RestAssured.given().header("X-Forwarded-Proto", "https").header("X-Forwarded-For", "2001:db8:85a3::")
.header("X-Forwarded-Host", "somehost").get("/forward").then()
.body(Matchers.containsString("2001:db8:85a3::"));
}

@Test
public void testIPV6WithPort() {
assertThat(RestAssured.get("/forward").asString()).startsWith("http|");

RestAssured.given().header("X-Forwarded-Proto", "https")
.header("X-Forwarded-For", "[2001:db8:85a3:8d3:1319:8a2e:370:ac]:101")
.header("X-Forwarded-Host", "somehost").get("/forward").then()
.body(Matchers.containsString("[2001:db8:85a3:8d3:1319:8a2e:370:ac]:101"));
}

@Test
public void testIPV6CompressedWithPort() {
assertThat(RestAssured.get("/forward").asString()).startsWith("http|");

RestAssured.given().header("X-Forwarded-Proto", "https").header("X-Forwarded-For", "[2001:db8:85a3:8d3::]:101")
.header("X-Forwarded-Host", "somehost").get("/forward").then()
.body(Matchers.containsString("[2001:db8:85a3:8d3::]:101"));
}

}
Original file line number Diff line number Diff line change
@@ -178,29 +178,41 @@ private void calculate() {
}

private void setHostAndPort(String hostToParse, int defaultPort) {
int portSeparatorIdx = hostToParse.lastIndexOf(':');
if (portSeparatorIdx > hostToParse.lastIndexOf(']')) {
host = hostToParse.substring(0, portSeparatorIdx);
delegate.headers().set(HttpHeaders.HOST, host);
port = parsePort(hostToParse.substring(portSeparatorIdx + 1), defaultPort);
} else {
host = hostToParse;
port = -1;
}
String[] hostAndPort = parseHostAndPort(hostToParse);
host = hostAndPort[0];
delegate.headers().set(HttpHeaders.HOST, host);
port = parsePort(hostAndPort[1], defaultPort);
}

private SocketAddress parseFor(String forToParse, int defaultPort) {
String host = forToParse;
int port = defaultPort;
int portSeparatorIdx = forToParse.lastIndexOf(':');
if (portSeparatorIdx > forToParse.lastIndexOf(']')) {
host = forToParse.substring(0, portSeparatorIdx);
port = parsePort(forToParse.substring(portSeparatorIdx + 1), defaultPort);
}

String[] hostAndPort = parseHostAndPort(forToParse);
String host = hostAndPort[0];
int port = parsePort(hostAndPort[1], defaultPort);
return new SocketAddressImpl(port, host);
}

/**
* Returns a String[] of 2 elements, with the first being the host and the second the port
*/
private String[] parseHostAndPort(String hostToParse) {
String[] hostAndPort = { hostToParse, "" };
int portSeparatorIdx = hostToParse.lastIndexOf(':');
int squareBracketIdx = hostToParse.lastIndexOf(']');
if ((squareBracketIdx > -1 && portSeparatorIdx > squareBracketIdx)) {
// ipv6 with port
hostAndPort[0] = hostToParse.substring(0, portSeparatorIdx);
hostAndPort[1] = hostToParse.substring(portSeparatorIdx + 1);
} else {
long numberOfColons = hostToParse.chars().filter(ch -> ch == ':').count();
if (numberOfColons == 1 && !hostToParse.endsWith(":")) {
// ipv4 with port
hostAndPort[0] = hostToParse.substring(0, portSeparatorIdx);
hostAndPort[1] = hostToParse.substring(portSeparatorIdx + 1);
}
}
return hostAndPort;
}

private int parsePort(String portToParse, int defaultPort) {
if (portToParse != null && portToParse.length() > 0) {
try {

0 comments on commit 0494ca9

Please sign in to comment.