I've done a test with Tomcat 6.0 and it all works fine: 10-Mar-2011 18:48:08 org.apache.catalina.startup.Catalina start INFO: Server startup in 2683 ms
Encoded : 70%2F70%5C70.v1.0 Encoded : 70%2F%2F70%5C70.v1.0 This is the resource method printing the last past segment. I had to set CATALINA_OPTS though the way you explained. Do you use Tomcat 6.0 ? May be you do some additional configuration ? In my case it is just the default Tomcat instance... I'm using 2.4.0-SNAPSHOT but I don't recall changing any relevant code in ServletController recently Thanks, Sergey On Thu, Mar 10, 2011 at 6:08 PM, Sergey Beryozkin <[email protected]>wrote: > I'm going to investigate this issue further - I think we can improve > ServletController it was written a long time ago and supporting encoded URIs > was not really on the map at a time. > The other thing I'll check if it is possible to pass matrix parameters > without values, just > > ;slash > > as opposed to ;slash=y > > this has to work - just need to add a test and confirm > > Sergey > > > On Thu, Mar 10, 2011 at 5:59 PM, Keith Hawes <[email protected]> wrote: > >> I was thinking along the lines of the matrix parameter as a work around as >> well. >> >> >> On Thu, Mar 10, 2011 at 1:25 AM, Sergey Beryozkin >> <[email protected]>wrote: >> >>> Hi >>> >>> On Thu, Mar 10, 2011 at 5:32 AM, Keith Hawes <[email protected]> wrote: >>> >>>> Got the source and added breakpoints. >>>> >>>> in ServletController.invoke: >>>> String address = request.getPathInfo() == null ? "" : >>>> request.getPathInfo(); >>>> puts a decoded path info into address AND strips the repeated / >>>> >>>> I can call with "632%2F%2F04810" or "632//04810" and in both cases >>>> address is "/v1/device/632/04810" >>>> >>>> Later in ServletController.getBaseURL we have >>>> String reqPrefix = request.getRequestURL().toString(); >>>> and reqPrefix gets set to: >>>> http://localhost/myservice/v1/device/632//04810 >>>> >>>> It appears tomcat wants to strip the "extra" / on us. :( I cannot find >>>> a way to stop it for doing so. >>>> >>>> >>>> >>> Thanks for this analysis...So may be you can do some workaround ? Always >>> use a single '/' but if you need two of them then indicate it via an >>> additional matrix parameter, say >>> >>> 632/04810;optionId=1;slash=y >>> >>> which can be seen as equivalent to >>> 632//04810;optionId=1 >>> >>> Will that work for you ? >>> >>> In meantime I'll need to investigate if ServletController can be updated >>> for request.getPathInfo() call be avoided... >>> >>> thanks, Sergey >>> >>> On Wed, Mar 9, 2011 at 8:21 PM, Keith Hawes <[email protected]> wrote: >>>> >>>>> Thanks. I had not tried the @Encoded annotation, I'll give that a try >>>>> and then >>>>> >>>>> as for configuring tomcat those two parameters need to be in system >>>>> properties, I just add them to the command line with -D >>>>> like this: >>>>> >>>>> -Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true >>>>> -Dorg.apache.catalina.connector.CoyoteAdapter.ALLOW_BACKSLASH=true >>>>> >>>>> Yes I do have the matrix parameters (they are optional criteria which >>>>> narrow the results) >>>>> >>>>> On Wed, Mar 9, 2011 at 10:20 AM, Sergey Beryozkin < >>>>> [email protected]> wrote: >>>>> >>>>>> I've done a simple test (with Jetty) and it works fine. >>>>>> >>>>>> Client: >>>>>> >>>>>> @Test >>>>>> public void testBookWithComplexEncoding() throws Exception { >>>>>> BookStore store = JAXRSClientFactory.create("http://localhost:" >>>>>> + PORT, BookStore.class); >>>>>> >>>>>> String complex1 = "70%2F70%5C70.v1.0"; >>>>>> Book book = store.getBookComplexEncoded(complex1, 3L); >>>>>> assertEquals(3L, book.getId()); >>>>>> assertEquals(complex1, book.getName()); >>>>>> >>>>>> String complex2 = "70%2F%2F70%5C70.v1.0"; >>>>>> book = store.getBookComplexEncoded(complex2, 3L); >>>>>> assertEquals(3L, book.getId()); >>>>>> assertEquals(complex2, book.getName()); >>>>>> } >>>>>> >>>>>> Relevant server code: >>>>>> >>>>>> @GET >>>>>> @Path("/books/encoded/{complex}") >>>>>> public Book getBookComplexEncoded(@Encoded @PathParam("complex") >>>>>> String complex, >>>>>> @MatrixParam("optionId") Long >>>>>> id) { >>>>>> return new Book(complex, id); >>>>>> } >>>>>> >>>>>> I'm just using @Encoded to capture the exact sequence in the original >>>>>> form... >>>>>> >>>>>> Can you please explain how to configure those two properties in Tomcat >>>>>> ? >>>>>> >>>>>> org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true >>>>>> org.apache.catalina.connector.CoyoteAdapter.ALLOW_BACKSLASH=true >>>>>> >>>>>> What would really help of you could download CXF source and put a >>>>>> breakpoint in ServletController and JAXRSInInterceptor >>>>>> >>>>>> It is possible there is a flaw somewhere exposed on Tomcat only >>>>>> >>>>>> thanks, Sergey >>>>>> >>>>>> >>>>>> On Wed, Mar 9, 2011 at 10:45 AM, Sergey Beryozkin < >>>>>> [email protected]> wrote: >>>>>> >>>>>>> Hi >>>>>>> >>>>>>> Forwarding to the users list... >>>>>>> >>>>>>> I do suspect it's the ServletController's issue to do with the way >>>>>>> the handles matrix parameters >>>>>>> >>>>>>> Do you actual request URIs having matrix params like this : >>>>>>> >>>>>>> /service/v1/device/70%2F%2F70%5C70.v1.0;optionId=1 >>>>>>> >>>>>>> ? >>>>>>> >>>>>>> thanks, Sergey >>>>>>> >>>>>>> >>>>>>> On Tue, Mar 8, 2011 at 6:42 PM, kh <[email protected]> wrote: >>>>>>> >>>>>>>> I get this message when I have two encodes /s in the path %2F%2F >>>>>>>> WARNING: .No root resource matching request path >>>>>>>> /service/v1/device/70%2F%2F70%5C70.v1.0 is found. >>>>>>>> However: >>>>>>>> /service/v1/device/70%2F70%5C70.v1.0 >>>>>>>> works fine. >>>>>>>> I'm using cxf 2.2.3 >>>>>>>> >>>>>>>> I have >>>>>>>> org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true >>>>>>>> org.apache.catalina.connector.CoyoteAdapter.ALLOW_BACKSLASH=true >>>>>>>> set. >>>>>>>> >>>>>>>> My annotations are: >>>>>>>> >>>>>>>> >>>>>>>> @Path("/v1/device") >>>>>>>> public class Device extends com.netflix.customer.eds.Device { >>>>>>>> >>>>>>>> @GET >>>>>>>> @Path("/{esn}") >>>>>>>> @Consumes("application/xml") >>>>>>>> @Produces("application/xml") >>>>>>>> /* for error cases only */ >>>>>>>> @Transactional(rollbackFor = {Throwable.class}) >>>>>>>> public Response get(@Context HttpServletRequest request, >>>>>>>> @PathParam("esn") String esn, >>>>>>>> @MatrixParam("optionId") Long optionId) >>>>>>>> >>>>>>>> I gt the same response weather or not I include the matrix >>>>>>>> parameter. >>>>>>>> >>>>>>>> Am I missing something? >>>>>>>> >>>>>>>> >>>>>> >>>>> >>>> >>> >>> >>> -- >>> Sergey Beryozkin >>> >>> Application Integration Division of Talend <http://www.talend.com> >>> http://sberyozkin.blogspot.com >>> >> >> > > > -- > Sergey Beryozkin > > Application Integration Division of Talend <http://www.talend.com> > http://sberyozkin.blogspot.com > -- Sergey Beryozkin Application Integration Division of Talend <http://www.talend.com> http://sberyozkin.blogspot.com
