Repository: tomee Updated Branches: refs/heads/release-tomee-1.7.2 0b392ec92 -> 544806da4
dont conflict with servlet cause of our jaxrs filter Project: http://git-wip-us.apache.org/repos/asf/tomee/repo Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/544806da Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/544806da Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/544806da Branch: refs/heads/release-tomee-1.7.2 Commit: 544806da419bc2f5ab8bc936a989ff99bc9d891b Parents: 0b392ec Author: Romain Manni-Bucau <rmannibu...@apache.org> Authored: Fri Jan 16 19:28:52 2015 +0100 Committer: Jonathan Gallimore <jonathan.gallim...@gmail.com> Committed: Fri Jan 16 21:39:20 2015 +0000 ---------------------------------------------------------------------- .../tomee/webservices/CXFJAXRSFilter.java | 43 ++++++++++++++++++-- .../org/apache/tomee/jaxrs/ReflectionTest.java | 31 ++++++++++++++ 2 files changed, 71 insertions(+), 3 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tomee/blob/544806da/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 61f9358..b955973 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,6 +16,8 @@ */ package org.apache.tomee.webservices; +import org.apache.catalina.servlets.DefaultServlet; +import org.apache.openejb.core.ParentClassLoaderFinder; import org.apache.openejb.server.cxf.rs.CxfRsHttpListener; import org.apache.openejb.server.httpd.ServletRequestAdapter; import org.apache.openejb.server.httpd.ServletResponseAdapter; @@ -30,8 +32,22 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.InputStream; +import java.lang.reflect.Field; public class CXFJAXRSFilter implements Filter { + private static final Field SERVLET_FIELD; + 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 + } + SERVLET_FIELD = servletFieldTmp; + } + private final CxfRsHttpListener delegate; private final String[] welcomeFiles; @@ -59,12 +75,18 @@ public class CXFJAXRSFilter implements Filter { final HttpServletRequest httpServletRequest = HttpServletRequest.class.cast(request); final HttpServletResponse httpServletResponse = HttpServletResponse.class.cast(response); - if (CxfRsHttpListener.TRY_STATIC_RESOURCES || delegate.matchPath(httpServletRequest)) { - final InputStream staticContent = delegate.findStaticContent(httpServletRequest, welcomeFiles); - if (staticContent != null) { + if (CxfRsHttpListener.TRY_STATIC_RESOURCES) { // else we just want jaxrs + if (isServlet(chain)) { chain.doFilter(request, response); return; } + if (delegate.matchPath(httpServletRequest)) { + final InputStream staticContent = delegate.findStaticContent(httpServletRequest, welcomeFiles); + if (staticContent != null) { + chain.doFilter(request, response); + return; + } + } } try { @@ -76,6 +98,21 @@ 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 respeted: + // - org.apache.catalina.core.ApplicationFilterChain name is stable (case on tomcat 8 for now) + // - ApplicationFilterChain as a field servlet with the expected servlet + try { + return SERVLET_FIELD != null + && "org.apache.catalina.core.ApplicationFilterChain".equals(chain.getClass().getName()) + && !DefaultServlet.class.isInstance(SERVLET_FIELD.get(chain)); + } catch (final IllegalAccessException e) { + return false; + } + } + @Override public void destroy() { // no-op http://git-wip-us.apache.org/repos/asf/tomee/blob/544806da/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 new file mode 100644 index 0000000..9bd5fcd --- /dev/null +++ b/tomee/tomee-jaxrs/src/test/java/org/apache/tomee/jaxrs/ReflectionTest.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.tomee.jaxrs; + +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()); + } +}