You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by rm...@apache.org on 2015/01/26 14:54:06 UTC

[1/2] tomee git commit: use wrapper to determine if we are in a jaxrs request or not

Repository: tomee
Updated Branches:
  refs/heads/tomee-1.7.x 528fa1245 -> ddb55fbcf


use wrapper to determine if we are in a jaxrs request or not


Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/be873a77
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/be873a77
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/be873a77

Branch: refs/heads/tomee-1.7.x
Commit: be873a774d3d8998e3bf40ee0b0afb91abb61fc9
Parents: 528fa12
Author: Romain Manni-Bucau <rm...@apache.org>
Authored: Mon Jan 26 14:25:48 2015 +0100
Committer: Romain Manni-Bucau <rm...@apache.org>
Committed: Mon Jan 26 14:25:48 2015 +0100

----------------------------------------------------------------------
 .../tomee/webservices/CXFJAXRSFilter.java       | 88 +++++++++++++++-----
 .../tomee/webservices/TomcatRsRegistry.java     | 19 +++--
 .../org/apache/tomee/jaxrs/ReflectionTest.java  |  7 +-
 3 files changed, 80 insertions(+), 34 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tomee/blob/be873a77/tomee/tomee-jaxrs/src/main/java/org/apache/tomee/webservices/CXFJAXRSFilter.java
----------------------------------------------------------------------
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 13bbcde..39907ca 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
@@ -16,8 +16,9 @@
  */
 package org.apache.tomee.webservices;
 
-import org.apache.catalina.servlets.DefaultServlet;
-import org.apache.openejb.core.ParentClassLoaderFinder;
+import org.apache.catalina.Wrapper;
+import org.apache.catalina.connector.Request;
+import org.apache.catalina.connector.RequestFacade;
 import org.apache.openejb.server.cxf.rs.CxfRsHttpListener;
 import org.apache.openejb.server.httpd.ServletRequestAdapter;
 import org.apache.openejb.server.httpd.ServletResponseAdapter;
@@ -29,27 +30,29 @@ import javax.servlet.ServletException;
 import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
 import java.io.InputStream;
 import java.lang.reflect.Field;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
 
 public class CXFJAXRSFilter implements Filter {
-    private static final Field SERVLET_FIELD;
+    private static final Field REQUEST;
     static {
-        Field servletFieldTmp = null;
         try {
-            final Class<?> clazz = ParentClassLoaderFinder.Helper.get().loadClass("org.apache.catalina.core.ApplicationFilterChain");
-            servletFieldTmp = clazz.getDeclaredField("servlet");
-            servletFieldTmp.setAccessible(true);
-        } catch (final Exception e) {
-            // no-op
+            REQUEST = RequestFacade.class.getDeclaredField("request");
+        } catch (final NoSuchFieldException e) {
+            throw new IllegalStateException(e);
         }
-        SERVLET_FIELD = servletFieldTmp;
+        REQUEST.setAccessible(true);
     }
 
     private final CxfRsHttpListener delegate;
     private final String[] welcomeFiles;
+    private final ConcurrentMap<Wrapper, Boolean> mappingByServlet = new ConcurrentHashMap<Wrapper, Boolean>();
+    private String mapping;
 
     public CXFJAXRSFilter(final CxfRsHttpListener delegate, final String[] welcomeFiles) {
         this.delegate = delegate;
@@ -62,7 +65,7 @@ public class CXFJAXRSFilter implements Filter {
 
     @Override
     public void init(final FilterConfig filterConfig) throws ServletException {
-        // no-op
+        mapping = filterConfig.getInitParameter("mapping");
     }
 
     @Override
@@ -76,7 +79,7 @@ public class CXFJAXRSFilter implements Filter {
         final HttpServletResponse httpServletResponse = HttpServletResponse.class.cast(response);
 
         if (CxfRsHttpListener.TRY_STATIC_RESOURCES) { // else we just want jaxrs
-            if (isServlet(chain)) {
+            if (servletMappingIsUnderRestPath(httpServletRequest)) {
                 chain.doFilter(request, response);
                 return;
             }
@@ -96,19 +99,62 @@ public class CXFJAXRSFilter implements Filter {
         }
     }
 
-    // see org.apache.tomcat.util.http.mapper.Mapper.internalMapWrapper
-    private boolean isServlet(final FilterChain chain) {
-        // will not work if we are not the first filter - which is likely the case the keep security etc -
-        // and the chain is wrapped which is more unlikely so this should work as long as these untyped constraints are respected:
-        // - org.apache.catalina.core.ApplicationFilterChain name is stable (case on tomcat 8 for now)
-        // - ApplicationFilterChain as a field servlet with the expected servlet
+    private boolean servletMappingIsUnderRestPath(final HttpServletRequest request) {
+        final HttpServletRequest unwrapped = unwrap(request);
+        if (!RequestFacade.class.isInstance(unwrapped)) {
+            return false;
+        }
+
+        final Request tr;
         try {
-            return SERVLET_FIELD != null
-                    && "org.apache.catalina.core.ApplicationFilterChain".equals(chain.getClass().getName())
-                    && !DefaultServlet.class.isInstance(SERVLET_FIELD.get(chain));
+            tr = Request.class.cast(REQUEST.get(unwrapped));
         } catch (final IllegalAccessException e) {
             return false;
         }
+        final Wrapper wrapper = tr.getWrapper();
+        if (wrapper == null || mapping == null) {
+            return false;
+        }
+
+        Boolean accept = mappingByServlet.get(wrapper);
+        if (accept == null) {
+            accept = false;
+            if (!"org.apache.catalina.servlets.DefaultServlet".equals(wrapper.getServletClass())) {
+                for (final String mapping : wrapper.findMappings()) {
+                    if (!mapping.isEmpty() && !"/*".equals(mapping) && !"/".equals(mapping) && mapping.startsWith(this.mapping)) {
+                        accept = true;
+                        break;
+                    }
+                }
+            }
+            mappingByServlet.putIfAbsent(wrapper, accept);
+            return accept;
+        }
+
+        return false;
+    }
+
+    private HttpServletRequest unwrap(final HttpServletRequest request) {
+        HttpServletRequest unwrapped = request;
+        boolean changed;
+        do {
+            changed = false;
+            while (HttpServletRequestWrapper.class.isInstance(unwrapped)) {
+                final HttpServletRequest tmp = HttpServletRequest.class.cast(HttpServletRequestWrapper.class.cast(unwrapped).getRequest());
+                if (tmp != unwrapped) {
+                    unwrapped = tmp;
+                } else {
+                    changed = false; // quit
+                    break;
+                }
+                changed = true;
+            }
+            while (ServletRequestAdapter.class.isInstance(unwrapped)) {
+                unwrapped = ServletRequestAdapter.class.cast(unwrapped).getRequest();
+                changed = true;
+            }
+        } while (changed);
+        return unwrapped;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/tomee/blob/be873a77/tomee/tomee-jaxrs/src/main/java/org/apache/tomee/webservices/TomcatRsRegistry.java
----------------------------------------------------------------------
diff --git a/tomee/tomee-jaxrs/src/main/java/org/apache/tomee/webservices/TomcatRsRegistry.java b/tomee/tomee-jaxrs/src/main/java/org/apache/tomee/webservices/TomcatRsRegistry.java
index 8f185cb..d460d14 100644
--- a/tomee/tomee-jaxrs/src/main/java/org/apache/tomee/webservices/TomcatRsRegistry.java
+++ b/tomee/tomee-jaxrs/src/main/java/org/apache/tomee/webservices/TomcatRsRegistry.java
@@ -106,15 +106,6 @@ public class TomcatRsRegistry implements RsRegistry {
         final CxfRsHttpListener cxfRsHttpListener = findCxfRsHttpListener(listener);
         final String description = "tomee-jaxrs-" + listener;
 
-        final FilterDef filterDef = new FilterDef();
-        filterDef.setAsyncSupported("true");
-        filterDef.setDescription(description);
-        filterDef.setFilterName(description);
-        filterDef.setDisplayName(description);
-        filterDef.setFilter(new CXFJAXRSFilter(cxfRsHttpListener, context.findWelcomeFiles()));
-        filterDef.setFilterClass(CXFJAXRSFilter.class.getName());
-        context.addFilterDef(filterDef);
-
         String mapping = completePath;
         if (!completePath.endsWith("/*")) { // respect servlet spec (!= from our embedded listeners)
             if (completePath.endsWith("*")) {
@@ -126,6 +117,16 @@ public class TomcatRsRegistry implements RsRegistry {
         final String urlPattern = removeWebContext(webContext, mapping);
         cxfRsHttpListener.setUrlPattern(urlPattern.substring(0, urlPattern.length() - 1));
 
+        final FilterDef filterDef = new FilterDef();
+        filterDef.setAsyncSupported("true");
+        filterDef.setDescription(description);
+        filterDef.setFilterName(description);
+        filterDef.setDisplayName(description);
+        filterDef.setFilter(new CXFJAXRSFilter(cxfRsHttpListener, context.findWelcomeFiles()));
+        filterDef.setFilterClass(CXFJAXRSFilter.class.getName());
+        filterDef.addInitParameter("mapping", urlPattern.substring(0, urlPattern.length() - "/*".length())); // just keep base path
+        context.addFilterDef(filterDef);
+
         final FilterMap filterMap = new FilterMap();
         filterMap.addURLPattern(urlPattern);
         filterMap.setFilterName(filterDef.getFilterName());

http://git-wip-us.apache.org/repos/asf/tomee/blob/be873a77/tomee/tomee-jaxrs/src/test/java/org/apache/tomee/jaxrs/ReflectionTest.java
----------------------------------------------------------------------
diff --git a/tomee/tomee-jaxrs/src/test/java/org/apache/tomee/jaxrs/ReflectionTest.java b/tomee/tomee-jaxrs/src/test/java/org/apache/tomee/jaxrs/ReflectionTest.java
index 9bd5fcd..98ebf07 100644
--- a/tomee/tomee-jaxrs/src/test/java/org/apache/tomee/jaxrs/ReflectionTest.java
+++ b/tomee/tomee-jaxrs/src/test/java/org/apache/tomee/jaxrs/ReflectionTest.java
@@ -16,16 +16,15 @@
  */
 package org.apache.tomee.jaxrs;
 
+import org.apache.catalina.connector.Request;
 import org.junit.Test;
 
-import javax.servlet.Servlet;
-
 import static org.junit.Assert.assertEquals;
 
 public class ReflectionTest {
     @Test // a quick test to break the build if upgrading tomcat our reflection will silently be broken
     public void breakTheBuildIfWhatWeUseChanged() throws ClassNotFoundException, NoSuchFieldException {
-        final Class<?> clazz = Thread.currentThread().getContextClassLoader().loadClass("org.apache.catalina.core.ApplicationFilterChain");
-        assertEquals(Servlet.class, clazz.getDeclaredField("servlet").getType());
+        final Class<?> clazz = Thread.currentThread().getContextClassLoader().loadClass("org.apache.catalina.connector.RequestFacade");
+        assertEquals(Request.class, clazz.getDeclaredField("request").getType());
     }
 }


[2/2] tomee git commit: don't override jaxrs by *.xxx mappings

Posted by rm...@apache.org.
don't override jaxrs by *.xxx mappings


Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/ddb55fbc
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/ddb55fbc
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/ddb55fbc

Branch: refs/heads/tomee-1.7.x
Commit: ddb55fbcf95fca3d8651d0a6c5b32e45072387fa
Parents: be873a7
Author: Romain Manni-Bucau <rm...@apache.org>
Authored: Mon Jan 26 14:47:10 2015 +0100
Committer: Romain Manni-Bucau <rm...@apache.org>
Committed: Mon Jan 26 14:47:10 2015 +0100

----------------------------------------------------------------------
 .../main/java/org/apache/tomee/webservices/CXFJAXRSFilter.java    | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tomee/blob/ddb55fbc/tomee/tomee-jaxrs/src/main/java/org/apache/tomee/webservices/CXFJAXRSFilter.java
----------------------------------------------------------------------
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 39907ca..5dd4ac9 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
@@ -121,7 +121,8 @@ public class CXFJAXRSFilter implements Filter {
             accept = false;
             if (!"org.apache.catalina.servlets.DefaultServlet".equals(wrapper.getServletClass())) {
                 for (final String mapping : wrapper.findMappings()) {
-                    if (!mapping.isEmpty() && !"/*".equals(mapping) && !"/".equals(mapping) && mapping.startsWith(this.mapping)) {
+                    if (!mapping.isEmpty() && !"/*".equals(mapping) && !"/".equals(mapping) && !mapping.startsWith("*")
+                            && mapping.startsWith(this.mapping)) {
                         accept = true;
                         break;
                     }