Hi Please see comments inline
On Tue, May 10, 2011 at 7:38 PM, Aki Yoshida <[email protected]> wrote: > Hi, > I noticed this behavior with CXF 2.3.4 under OSGi. I think it is > strange. But there might be some explanation or I am missing > something. > > Basically, the problem is described as follows. When I have a CXF > endpoint registered at a particular URL path, I can send a SOAP > message to this service by sending it to any URL path that starts with > this path. I stumbled on this problem when I had two paths registered > (something like /soappath and /soappath2 using two bundles, > respectively). When I stopped the second bundle and sent a message to > /soappath2, expecting to see the message being rejected, instead the > message was simply forwarded to the service under the first > destination /soappath. > > Then, I saw the following method in > org.apache.cxf.transport.http_osgi.OsgiServletController that was > responsible for this fallback logic. > > private OsgiDestination checkRestfulRequest(HttpServletRequest > request) throws IOException { > > String address = request.getPathInfo() == null ? "" : > request.getPathInfo(); > > for (String path : servlet.getTransport().getDestinationsPaths()) { > if (address.startsWith(path)) { > return servlet.getTransport().getDestinationForPath(path); > } > } > return null; > } > > Note that I am using the SOAP binding and sending SOAP messages to > these entry points. > > In 3.4.0, this OsgiServeltController class is no longer used, but when > a call enters over > org.apache.cxf.transport.servlet.ServletController's > invoke(HttpServletRequest, HttpServletResponse) method, this method > invokes an equivalent method implemented in > org.apache.cxf.transport.http.DestinationRegistryImpl > > public AbstractHTTPDestination checkRestfulRequest(String address) { > int len = -1; > AbstractHTTPDestination ret = null; > for (String path : getDestinationsPaths()) { > if (address.startsWith(path) > && path.length() > len) { > ret = getDestinationForPath(path); > len = path.length(); > } > } > if (ret != null && ret.getMessageObserver() == null) { > return null; > } > return ret; > } > > What is not clear to me is why this logic is used also for normal SOAP > calls in the OSGi setup but not in the standalone setup using > http_jetty. I'm not well aware of the how ServletController was evolving from the very start but I assume this code lives in ServletController for a default stem match to succeed, while in Jetty case it's all handled by Jetty itself, just one possible explanation. The above code is definitely needed for JAX-RS endpoints to work properly, ex, given jaxrs:server/@address = "/rest", /rest/1/2 will be matched against it. I think the above code executes in the case of SOAP requests because the initial check for available destination fails (no exact match for /soappath2) but I reckon the most effective option to block the above code from succeeding in this case is to configure a bundle specific Destination to use the strict match in checkRestfulRequest. That will definitely work, the other option is to check the Content-Type but it's not 100% guaranteed to be a SOAP endpoint that is going to handle it... Would you agree that selectively setting a strict match policy will fix the issue ? Cheers, Sergey > Could someone tell me why we have this destination finding logic here? > > I think this fallback logic should not be the default even if it is > desired in some cases. But I am interested in hearing your opinons. > > Thanks. > Regards, aki > -- Sergey Beryozkin Application Integration Division of Talend http://sberyozkin.blogspot.com
