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

Reply via email to