Repository: quarkusio/quarkus
Issue: Wrong host forwarded after enabling  proxy address forwarding

**Describe the bug**
quarkus.http.proxy.proxy-address-forwarding=true

When an ip like 2001:db8:85a3:8d3:1319:8a2e:370:ac is used, the parsing in vertx.http  ForwardedParser breaks as it considers ac to be the port

**Expected behavior**
The obtained remote host address should be2001:db8:85a3:8d3:1319:8a2e:370:ac

**Actual behavior**
We get something like  2001:db8:85a3:8d3:1319:8a2e:370:37678


**Configuration**
```properties
# Add your application.properties here, if applicable.
quarkus.http.proxy.proxy-address-forwarding=true

```


Changed files:
extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/ForwardedParser.java
extensions/vertx-http/deployment/src/test/java/io/quarkus/vertx/http/ForwardedForHeaderTest.java

diff --git a/extensions/vertx-http/deployment/src/test/java/io/quarkus/vertx/http/ForwardedForHeaderTest.java b/extensions/vertx-http/deployment/src/test/java/io/quarkus/vertx/http/ForwardedForHeaderTest.java
index a58c803fd01..d06e24b4066 100644
--- a/extensions/vertx-http/deployment/src/test/java/io/quarkus/vertx/http/ForwardedForHeaderTest.java
+++ b/extensions/vertx-http/deployment/src/test/java/io/quarkus/vertx/http/ForwardedForHeaderTest.java
@@ -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.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"));
+    }
+
 }
diff --git a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/ForwardedParser.java b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/ForwardedParser.java
index 66441f2e08f..6866c013bc5 100644
--- a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/ForwardedParser.java
+++ b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/ForwardedParser.java
@@ -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 {