Open FrenkelS opened 11 months ago
I took a quick look at this and even if we apply the following patch to Quarkus:
diff --git a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/StaticResourcesRecorder.java b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/StaticResourcesRecorder.java
index 7738d9bfe34..df476450956 100644
--- a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/StaticResourcesRecorder.java
+++ b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/StaticResourcesRecorder.java
@@ -88,10 +88,17 @@ public void handle(RoutingContext ctx) {
handlers.add(new Handler<>() {
@Override
public void handle(RoutingContext ctx) {
- String rel = ctx.mountPoint() == null ? ctx.normalizedPath()
- : ctx.normalizedPath().substring(
- // let's be extra careful here in case Vert.x normalizes the mount points at some point
- ctx.mountPoint().endsWith("/") ? ctx.mountPoint().length() - 1 : ctx.mountPoint().length());
+ String rel;
+ if (ctx.mountPoint() == null) {
+ rel = ctx.normalizedPath();
+ } else {
+ rel = ctx.normalizedPath().substring(
+ // let's be extra careful here in case Vert.x normalizes the mount points at some point
then Vert.x's StaticResourceHandler
still does not return the file for curl localhost:8080/testing
because of how the non-root path is handled.
What I think would also be needed to fix things would be to in Vert.x Web is:
diff --git a/vertx-web/src/main/java/io/vertx/ext/web/handler/impl/StaticHandlerImpl.java b/vertx-web/src/main/java/io/vertx/ext/web/handler/impl/StaticHandlerImpl.java
--- a/vertx-web/src/main/java/io/vertx/ext/web/handler/impl/StaticHandlerImpl.java (revision 58678777c7607289a0b6b8cb87a514155017217f)
+++ b/vertx-web/src/main/java/io/vertx/ext/web/handler/impl/StaticHandlerImpl.java (revision 12fd7ed21e85bc09ff5a5dfe92f1e62fb1e9843a)
@@ -195,9 +195,21 @@
path,
// only root is known for sure to be a directory. all other directories must be
// identified as such.
- !directoryListing && "/".equals(path));
+ !directoryListing && isPathRoot(path, context));
}
}
+
+ private static boolean isPathRoot(String path, RoutingContext context) {
+ if ("/".equals(path)) {
+ return true;
+ }
+
+ String mountPoint = context.mountPoint();
+ if (mountPoint == null) {
+ return false;
+ }
+ return mountPoint.equals(path.endsWith("/") ? path : path + "/");
+ }
WDYT @cescoffier @vietj?
As a workaround I've added dependency quarkus-reactive-routes
and do the redirect myself in a @RouteFilter
:
package my.problem;
import java.net.HttpURLConnection;
import java.util.HashSet;
import java.util.Set;
import io.quarkus.vertx.web.RouteFilter;
import io.vertx.ext.web.RoutingContext;
import org.eclipse.microprofile.config.inject.ConfigProperty;
class RedirectBugFixFilter {
private final Set<String> rootPaths = new HashSet<>();
RedirectBugFixFilter(@ConfigProperty(name = "quarkus.http.root-path", defaultValue = "/") String quarkusHttpRootPath,
@ConfigProperty(name = "quarkus.resteasy.path", defaultValue = "/") String quarkusResteasyPath,
@ConfigProperty(name = "quarkus.resteasy-reactive.path", defaultValue = "/") String quarkusResteasyReactivePath) {
addRootPath(quarkusHttpRootPath);
addRootPath(quarkusResteasyPath);
addRootPath(quarkusResteasyReactivePath);
}
private void addRootPath(String rootPath) {
if (!"/".equals(rootPath)) {
rootPaths.add(rootPath.endsWith("/") ? rootPath.substring(0, rootPath.length() - 1) : rootPath);
}
}
@RouteFilter( 100 )
void redirect(RoutingContext routingContext) {
String uri = routingContext.request().uri();
if (rootPaths.contains(uri)) {
routingContext.response()
.setStatusCode(HttpURLConnection.HTTP_MOVED_PERM)
.putHeader("location", uri + '/')
.end();
} else {
routingContext.next();
}
}
}
Describe the bug
Quarkus behaves differently in development mode compared to production mode when using RESTEasy, a custom
quarkus.http.root-path
and static content.My
application.properties
containsand I have one REST service:
I also have an
index.html
insrc/main/resources/META-INF/resources
that has a link to Swagger UI. When Quarkus runs in development mode (mvn quarkus:dev
)localhost:8080/testing
redirects tolocalhost:8080/testing/
andindex.html
is shown in my browser. But when Quarkus runs in production mode (java -jar target\quarkus-app\quarkus-run.jar
),localhost:8080/testing
returns HTTP status code 404.The following urls behave the same in both modes:
localhost:8080/testing/
localhost:8080/testing/q/swagger-ui
localhost:8080/testing/q/swagger-ui/
localhost:8080/testing/hello
localhost:8080/testing/hello/
Expected behavior
In production mode,
curl localhost:8080/testing -i
should show HTTP status code 301 and a redirect to/testing/
.Actual behavior
In production mode,
curl localhost:8080/testing -i
shows HTTP status code 404.How to Reproduce?
my-redirect-problem.zip
Output of
uname -a
orver
Microsoft Windows [Version 10.0.22621.1992]
Output of
java -version
openjdk version "17" 2021-09-14 OpenJDK Runtime Environment (build 17+35-2724) OpenJDK 64-Bit Server VM (build 17+35-2724, mixed mode, sharing)
GraalVM version (if different from Java)
No response
Quarkus version or git rev
3.2.2.Final
Build tool (ie. output of
mvnw --version
orgradlew --version
)Apache Maven 3.9.3 (21122926829f1ead511c958d89bd2f672198ae9f) Maven home: C:\Progs\apache-maven-3.9.3 Java version: 17, vendor: Oracle Corporation, runtime: C:\Progs\Java\jdk-17 Default locale: nl_NL, platform encoding: Cp1252 OS name: "windows 10", version: "10.0", arch: "amd64", family: "windows"
Additional information
When
quarkus-undertow
is added as a dependency, production mode behaves the same as development mode. Butcurl localhost:8080/testing -i
shows HTTP 302 instead of 301, and the redirect is tohttp://localhost:8080/testing/
instead of/testing/
.This problem is similar to https://github.com/quarkusio/quarkus/issues/3091, https://github.com/quarkusio/quarkus/issues/6760 and https://github.com/quarkusio/quarkus/issues/19492