Repository: quarkusio/quarkus
Issue: CORS Rejected Error on same-origin requests when CORS is enabled

### Describe the bug

Since Quarkus 2.14.2, requests return status `403` if CORS is enabled and the origin is not in the list of allowed CORS origins, even if the request is not cross-origin at all.

### Expected behavior

CORS Settings should have no impact on same-origin requests.

### Actual behavior

Enabling CORS seems to prevent all requests with an `Origin`-header that isn't explicitly whitelisted, even same-origin requests. `GET`-Requests may still work as browsers don't add the `Origin`-Header to same-origin `GET`-requests.

### How to Reproduce?

Reproducer: [cors.zip](https://github.com/quarkusio/quarkus/files/10106358/cors.zip)

See the test or just start the project and try to use the Dev UI - anything that isn't a plain GET request like the attempts to establish websockets for test and logstream will fail.



### Output of `uname -a` or `ver`

_No response_

### Output of `java -version`

_No response_

### GraalVM version (if different from Java)

_No response_

### Quarkus version or git rev

2.14.2.Final

### Build tool (ie. output of `mvnw --version` or `gradlew --version`)

_No response_

### Additional information

_No response_

Changed files:
extensions/vertx-http/deployment/src/test/java/io/quarkus/vertx/http/cors/CORSHandlerTestWildcardOriginCase.java
extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/cors/CORSFilter.java

diff --git a/extensions/vertx-http/deployment/src/test/java/io/quarkus/vertx/http/cors/CORSHandlerTestWildcardOriginCase.java b/extensions/vertx-http/deployment/src/test/java/io/quarkus/vertx/http/cors/CORSHandlerTestWildcardOriginCase.java
index bea0ee15783..c1852e10dd8 100644
--- a/extensions/vertx-http/deployment/src/test/java/io/quarkus/vertx/http/cors/CORSHandlerTestWildcardOriginCase.java
+++ b/extensions/vertx-http/deployment/src/test/java/io/quarkus/vertx/http/cors/CORSHandlerTestWildcardOriginCase.java
@@ -49,6 +49,60 @@ void corsNotMatchingOrigin() {
                 .header("Access-Control-Allow-Credentials", "false");
     }
 
+    @Test
+    void corsSameOriginRequest() {
+        String origin = "http://localhost:8081";
+        given().header("Origin", origin)
+                .get("/test").then()
+                .statusCode(200)
+                .header("Access-Control-Allow-Origin", origin);
+    }
+
+    @Test
+    void corsInvalidSameOriginRequest1() {
+        String origin = "http";
+        given().header("Origin", origin)
+                .get("/test").then()
+                .statusCode(403)
+                .header("Access-Control-Allow-Origin", nullValue());
+    }
+
+    @Test
+    void corsInvalidSameOriginRequest2() {
+        String origin = "http://local";
+        given().header("Origin", origin)
+                .get("/test").then()
+                .statusCode(403)
+                .header("Access-Control-Allow-Origin", nullValue());
+    }
+
+    @Test
+    void corsInvalidSameOriginRequest3() {
+        String origin = "http://localhost";
+        given().header("Origin", origin)
+                .get("/test").then()
+                .statusCode(403)
+                .header("Access-Control-Allow-Origin", nullValue());
+    }
+
+    @Test
+    void corsInvalidSameOriginRequest4() {
+        String origin = "http://localhost:9999";
+        given().header("Origin", origin)
+                .get("/test").then()
+                .statusCode(403)
+                .header("Access-Control-Allow-Origin", nullValue());
+    }
+
+    @Test
+    void corsInvalidSameOriginRequest5() {
+        String origin = "https://localhost:8483";
+        given().header("Origin", origin)
+                .get("/test").then()
+                .statusCode(403)
+                .header("Access-Control-Allow-Origin", nullValue());
+    }
+
     @Test
     @DisplayName("Returns false 'Access-Control-Allow-Credentials' header on matching origin '*'")
     void corsMatchingOriginWithWildcard() {
diff --git a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/cors/CORSFilter.java b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/cors/CORSFilter.java
index 4a7fee1a14e..d9cba6755d0 100644
--- a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/cors/CORSFilter.java
+++ b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/cors/CORSFilter.java
@@ -1,5 +1,6 @@
 package io.quarkus.vertx.http.runtime.cors;
 
+import java.net.URI;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -176,7 +177,7 @@ public void handle(RoutingContext event) {
             }
 
             boolean allowsOrigin = isConfiguredWithWildcard(corsConfig.origins) || corsConfig.origins.get().contains(origin)
-                    || isOriginAllowedByRegex(allowedOriginsRegex, origin);
+                    || isOriginAllowedByRegex(allowedOriginsRegex, origin) || isSameOrigin(request, origin);
 
             if (allowsOrigin) {
                 response.headers().set(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, origin);
@@ -210,4 +211,18 @@ public void handle(RoutingContext event) {
             }
         }
     }
+
+    private static boolean isSameOrigin(HttpServerRequest request, String origin) {
+        String absUriString = request.absoluteURI();
+        if (absUriString.startsWith(origin)) {
+            // Make sure that Origin URI contains scheme, host, and port.
+            // If no port is set in Origin URI then the request URI must not have it set either
+            URI baseUri = URI.create(absUriString.substring(0, origin.length()));
+            if (baseUri.getScheme() != null && baseUri.getHost() != null
+                    && (baseUri.getPort() > 0 || URI.create(absUriString).getPort() == -1)) {
+                return true;
+            }
+        }
+        return false;
+    }
 }