You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by rz...@apache.org on 2024/11/18 19:59:44 UTC

(tomee) 01/02: TOMEE-4424 - improved JAX-RS request routing if a welcome-file is defined

This is an automated email from the ASF dual-hosted git repository.

rzo1 pushed a commit to branch TOMEE-4424
in repository https://gitbox.apache.org/repos/asf/tomee.git

commit d19a8323007e5bba5022b9aef81f10e8167973f8
Author: Markus Jung <ju...@apache.org>
AuthorDate: Sat Nov 9 20:52:14 2024 +0100

    TOMEE-4424 - improved JAX-RS request routing if a welcome-file is defined
---
 .../servlets/welcomefile/MyFiletypeServlet.java    | 15 ++++++
 .../jaxrs/servlets/welcomefile/MyRestApi.java      | 14 ++++++
 .../servlets/welcomefile/MyRestApplication.java    |  6 +++
 .../welcomefile/ServletsWithWelcomeFileTest.java   | 56 ++++++++++++++++++++++
 .../apache/tomee/webservices/CXFJAXRSFilter.java   | 25 +++++++---
 5 files changed, 110 insertions(+), 6 deletions(-)

diff --git a/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/servlets/welcomefile/MyFiletypeServlet.java b/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/servlets/welcomefile/MyFiletypeServlet.java
new file mode 100644
index 0000000000..e717a886f3
--- /dev/null
+++ b/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/servlets/welcomefile/MyFiletypeServlet.java
@@ -0,0 +1,15 @@
+package org.apache.openejb.arquillian.tests.jaxrs.servlets.welcomefile;
+
+import jakarta.servlet.ServletException;
+import jakarta.servlet.http.HttpServlet;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+
+import java.io.IOException;
+
+public class MyFiletypeServlet extends HttpServlet {
+    @Override
+    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+        resp.getWriter().print("filetype matched");
+    }
+}
\ No newline at end of file
diff --git a/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/servlets/welcomefile/MyRestApi.java b/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/servlets/welcomefile/MyRestApi.java
new file mode 100644
index 0000000000..785ac4e133
--- /dev/null
+++ b/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/servlets/welcomefile/MyRestApi.java
@@ -0,0 +1,14 @@
+package org.apache.openejb.arquillian.tests.jaxrs.servlets.welcomefile;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.core.Response;
+
+@Path("/api")
+public class MyRestApi {
+    @GET
+    @Path("/test")
+    public Response getTest() {
+        return Response.ok("Hello world!").build();
+    }
+}
\ No newline at end of file
diff --git a/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/servlets/welcomefile/MyRestApplication.java b/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/servlets/welcomefile/MyRestApplication.java
new file mode 100644
index 0000000000..cd421c7745
--- /dev/null
+++ b/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/servlets/welcomefile/MyRestApplication.java
@@ -0,0 +1,6 @@
+package org.apache.openejb.arquillian.tests.jaxrs.servlets.welcomefile;
+
+import jakarta.ws.rs.core.Application;
+
+public class MyRestApplication extends Application {
+}
diff --git a/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/servlets/welcomefile/ServletsWithWelcomeFileTest.java b/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/servlets/welcomefile/ServletsWithWelcomeFileTest.java
new file mode 100644
index 0000000000..19126335e1
--- /dev/null
+++ b/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/servlets/welcomefile/ServletsWithWelcomeFileTest.java
@@ -0,0 +1,56 @@
+package org.apache.openejb.arquillian.tests.jaxrs.servlets.welcomefile;
+
+import org.apache.openejb.arquillian.tests.jaxrs.JaxrsTest;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.StringAsset;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.jboss.shrinkwrap.descriptor.api.Descriptors;
+import org.jboss.shrinkwrap.descriptor.api.webapp30.WebAppDescriptor;
+import org.jboss.shrinkwrap.descriptor.api.webcommon30.WebAppVersionType;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.IOException;
+
+import static org.junit.Assert.assertEquals;
+
+@RunWith(Arquillian.class)
+public class ServletsWithWelcomeFileTest extends JaxrsTest {
+    @Deployment(testable = false)
+    public static WebArchive createDeployment() {
+        WebAppDescriptor webXml = Descriptors.create(WebAppDescriptor.class)
+                .version(WebAppVersionType._3_0)
+                .createServlet()
+                    .servletName("My Filetype Servlet")
+                    .servletClass(MyFiletypeServlet.class.getName())
+                .up()
+                .createServletMapping()
+                    .servletName("My Filetype Servlet")
+                    .urlPattern("*.mine")
+                .up()
+                .createWelcomeFileList()
+                    .welcomeFile("index.mine")
+                .up();
+
+        return ShrinkWrap.create(WebArchive.class)
+                .addClasses(MyRestApi.class, MyRestApplication.class, MyFiletypeServlet.class)
+                .setWebXML(new StringAsset(webXml.exportAsString()));
+    }
+
+    @Test
+    public void welcomeFileOnRoot() throws IOException {
+        assertEquals("filetype matched", get("/"));
+    }
+
+    @Test
+    public void fileExtension() throws IOException {
+        assertEquals("filetype matched", get("/test.mine"));
+    }
+
+    @Test
+    public void jaxRsWithTrailingSlash() throws IOException {
+        assertEquals("Hello world!", get("/api/test/"));
+    }
+}
diff --git a/tomee/tomee-jaxrs/src/main/java/org/apache/tomee/webservices/CXFJAXRSFilter.java b/tomee/tomee-jaxrs/src/main/java/org/apache/tomee/webservices/CXFJAXRSFilter.java
index 2bf3297a45..0a9d3e641a 100644
--- a/tomee/tomee-jaxrs/src/main/java/org/apache/tomee/webservices/CXFJAXRSFilter.java
+++ b/tomee/tomee-jaxrs/src/main/java/org/apache/tomee/webservices/CXFJAXRSFilter.java
@@ -86,20 +86,33 @@ public class CXFJAXRSFilter implements Filter {
     }
 
     /**
-     * Checks if the request matched a defined servlet mapping matches the given request
+     * Checks if the request matched a defined servlet mapping,
+     * this also tries to detect if the servlet path has been rewritten because of a possible &lt;welcome-file&gt;
      *
      * @param request the HttpServletRequest to check
      * @return true if the servlet request is mapped to the tomcat default servlet
      */
     private boolean defaultServletMatched(final HttpServletRequest request) {
+        // First we ask nicely if the request was mapped to the default servlet
         ServletRegistration servletRegistration = request.getServletContext().getServletRegistration(
                 request.getHttpServletMapping().getServletName());
 
-        return "default".equals(servletRegistration.getName());
-    }
+        if ("default".equals(servletRegistration.getName())) {
+            return true;
+        }
 
-    @Override
-    public void destroy() {
-        // no-op
+        // See TOMEE-4424, we try to detect if tomcat rewrote this request to a welcome-file
+        // because no servlet/static resource matched the request directly
+        // otherwise requests like `GET /api/users/` are broken if a welcome-file is defined
+        boolean welcomeFileRewriteDetected = false;
+        for (final String welcomeFile : welcomeFiles) {
+            // welcomeFile was not on requestUri but is now on servlet path, so a rewrite happened
+            if (!request.getRequestURI().endsWith(welcomeFile) && request.getServletPath().endsWith(welcomeFile)) {
+                welcomeFileRewriteDetected = true;
+                break;
+            }
+        }
+
+        return welcomeFileRewriteDetected;
     }
 }