users@jersey.java.net

Re: [Jersey] Trailing slash redirect

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Thu, 11 Feb 2010 18:52:43 +0100

Hi Chris,

Two things to help throw more light on this issue:

1) Set tracing to true:

https://jersey.dev.java.net/nonav/apidocs/latest/jersey/com/sun/jersey/api/core/ResourceConfig.html
#FEATURE_TRACE

2) Set request and response logging on:

https://jersey.dev.java.net/nonav/apidocs/latest/jersey/com/sun/jersey/api/container/filter/LoggingFilter.html

Feel free to send the output privately if public disclosure is an
issue. And, if i still cannot work out what is wrong from the logging
output then a reproducible test case will be most appreciated so i can
better work out what is going wrong.


On Feb 11, 2010, at 6:44 PM, Chris Carrier wrote:

> My Jersey dependencies are:
>
> <!--Jersey-->
> <dependency>
> <groupId>com.sun.jersey</groupId>
> <artifactId>jersey-bundle</artifactId>
> <version>1.1.5</version>
> </dependency>
> <dependency>
> <groupId>com.sun.jersey.contribs</groupId>
> <artifactId>jersey-spring</artifactId>
> <version>1.1.5</version>
> </dependency>
>
> I'm using the bundle dependency because of issues I ran into with the
> META-INF/services directory clashing across dependencies (I could also
> fix this with the Maven shade plugin i think).

Correct, and make sure you use the ServicesResourceTransformer to
merge META-INF service files.

Paul.

> When I remove the star
> I am left with a class level Path that looks like:
>
> @Path("/some/path/{version}/json/")
>
> And my GET like:
>
> @GET
> @Path("/{id}/")
>
> But my tests then fail. And if i try without trailing slash redirect
> with a path like:
>
> @GET
> @Path("/{id}")
>
> They also fail. The only way I can get GETs without trailing slashes
> to work is with the path i mentioned before:
>
> @GET
> @Path("/{id}/*")
>
> And trailing slash redirect turned on.
>
> Chris
>
> On Thu, Feb 11, 2010 at 9:31 AM, Paul Sandoz <Paul.Sandoz_at_sun.com>
> wrote:
>>
>> On Feb 11, 2010, at 6:06 PM, Chris Carrier wrote:
>>
>>> I seemed to have found a solution by messing with my Path. If I
>>> annotate my GETs with a Path like:
>>>
>>> @Path("/{key}/*")
>>>
>>> Where before i just had:
>>>
>>> @Path("/{key}")
>>>
>>
>> Not sure what is going on here as the '*' character should be
>> considered a
>> literal character that is part of the path and should not have the
>> same
>> syntax as that defined for regular expressions. Although that could
>> be a bug
>> in the template to regex convertor...
>>
>> It would help if i knew what version of Jersey you are using.
>>
>> In any case the @Path("/{key}/") should work as documented when
>> FEATURE_REDIRECT is declared:
>>
>> https://jersey.dev.java.net/nonav/apidocs/latest/jersey/com/sun/jersey/api/core/ResourceConfig.html
>> #FEATURE_REDIRECT
>>
>> And if that value is false and you have @Path("/{key}") then it
>> should match
>> with or without a '/' present at the end of the request URL path.
>>
>>
>>> It works. I'm not sure why i need the star at the end but that
>>> seems
>>> to fix it. Is that expected behavior?
>>
>> No.
>>
>>
>>
>>> As for the POST issue it must
>>> be my client. I'm using Wiztools (Rest Client) from google
>>> tools. It
>>> must auto redirect even on POSTs.
>>>
>>
>> OK.
>>
>>
>>> It would be ideal if I didn't have this 'magic" path pattern but as
>>> long as it works I don't have too much to complain about. If you
>>> still want to see a project that shows this behavior I could pretty
>>> easily strip down our code to a simple endpoint and test and send it
>>> over.
>>>
>>
>> If it is something that does not take a lot of time for you to do
>> then it
>> would be most helpful as there might be a bug or two lurking here.
>>
>> Paul.
>>
>>
>>> Chris
>>>
>>> On Thu, Feb 11, 2010 at 12:48 AM, Paul Sandoz
>>> <Paul.Sandoz_at_sun.com> wrote:
>>>>
>>>> Hi Chris,
>>>>
>>>> What version of Jersey are you using?
>>>>
>>>> The latest version of Jersey will work with or without a trailing
>>>> '/' but
>>>> by
>>>> default no redirection will be performed. And you can enabled
>>>> redirection
>>>> as
>>>> you have done with the FEATURE_REDIRECT property.
>>>>
>>>> I think there may be something wrong with your configuration. It
>>>> is hard
>>>> to
>>>> tell with Jetty, Spring and Jersey in the mix what exactly is going
>>>> wrong.
>>>> Plus i do not know what client you are using.
>>>>
>>>> Note that redirection on temporary redirect responses are only
>>>> meant to
>>>> happen for GET and HEAD, not POST:
>>>>
>>>> http://greenbytes.de/tech/webdav/rfc2616.html#status.307
>>>>
>>>> If the 307 status code is received in response to a request
>>>> other than
>>>> GET
>>>> or HEAD, the user agent MUST NOT
>>>> automatically redirect the request unless it can be confirmed by
>>>> the
>>>> user,
>>>> since this might change the conditions
>>>> under which the request was issued.
>>>>
>>>> Would it be possible to send me (privately if public disclosure
>>>> is an
>>>> issue)
>>>> a maven-based project that reproduces the issue?
>>>>
>>>> Paul.
>>>>
>>>> On Feb 10, 2010, at 8:55 PM, Chris Carrier wrote:
>>>>
>>>>> Hi folks,
>>>>>
>>>>> I've seen this topic mentioned in the archive but I am having
>>>>> trouble
>>>>> getting it to work. It's a pretty annoying problem. I just
>>>>> want all
>>>>> my calls to work whether they have a trailing slash or not. In
>>>>> this
>>>>> project we're using embedded Jetty that is being programatically
>>>>> configured. So in that code I added:
>>>>>
>>>>> Servlet servlet = new SpringServlet();
>>>>> ServletHolder holder = new ServletHolder(servlet);
>>>>>
>>>>> Map initParams = new HashMap();
>>>>> initParams.put(ResourceConfig.FEATURE_REDIRECT, "true");
>>>>> holder.setInitParameters(initParams);
>>>>>
>>>>> But this seems to cause pretty unpredictable behavior. For
>>>>> instance
>>>>> after I added that I tried making a POST to my endpoint which
>>>>> has a
>>>>> method annotated as @POST but I get a 400 response. And the weird
>>>>> thing is the debug log shows:
>>>>>
>>>>> 2010-02-10 11:40:03,382 DEBUG
>>>>> org.springframework.web.context.request.RequestContextListener:69
>>>>> Bound
>>>>> request context to thread: POST /some/path HTTP/1.1
>>>>> ...
>>>>>
>>>>> 2010-02-10 11:40:03,383 DEBUG
>>>>> org.springframework.web.context.request.RequestContextListener:89
>>>>> Cleared
>>>>> thread-bound request context: POST /some/path HTTP/1.1
>>>>> ...
>>>>>
>>>>> 2010-02-10 11:40:03,384 DEBUG
>>>>> org.springframework.web.context.request.RequestContextListener:69
>>>>> Bound
>>>>> request context to thread: GET /some/path/ HTTP/1.1
>>>>> ...
>>>>>
>>>>> 2010-02-10 11:40:03,385 DEBUG
>>>>> org.springframework.web.context.request.RequestContextListener:89
>>>>> Cleared
>>>>> thread-bound request context: GET /some/path/ HTTP/1.1
>>>>> ...
>>>>>
>>>>> There isn't a GET call being made. It's like the POST is getting
>>>>> turned into a GET for some reason. This doesn't happen when i
>>>>> don't
>>>>> have the redirect on. Does the trailing slash thing only apply to
>>>>> GETs? If that's the case shouldn't it just ignore my POST? If
>>>>> i have
>>>>> a trailing slash in the original call it works fine.
>>>>>
>>>>> Aside from that the redirect doesn't even work for my GETs.
>>>>> When i
>>>>> try a GET without a trailing slash I get:
>>>>>
>>>>> 2010-02-10 11:47:15,344 DEBUG
>>>>> org.springframework.web.context.request.RequestContextListener:69
>>>>> Bound
>>>>> request context to thread: GET /some/path/c4e713e HTTP/1.1
>>>>>
>>>>> 2010-02-10 11:47:15,346 DEBUG
>>>>> org.springframework.web.context.request.RequestContextListener:89
>>>>> Cleared
>>>>> thread-bound request context: GET /some/path/c4e713e HTTP/1.1
>>>>>
>>>>> 2010-02-10 11:47:15,359 DEBUG
>>>>> org.springframework.web.context.request.RequestContextListener:69
>>>>> Bound
>>>>> request context to thread: GET /some/path/c4e713e/ HTTP/1.1
>>>>>
>>>>> 2010-02-10 11:47:15,440 DEBUG
>>>>> org.springframework.web.context.request.RequestContextListener:89
>>>>> Cleared
>>>>> thread-bound request context: GET /some/path/c4e713e/ HTTP/1.1
>>>>>
>>>>> Which looks like it's redirecting properly but then it returns a
>>>>> 404.
>>>>> In this case it doesn't matter whether i have a trailing slash
>>>>> on the
>>>>> original call or not it always returns a 404. Even though I
>>>>> have a
>>>>> GET annotated class and I've tried various combinations for the
>>>>> path:
>>>>>
>>>>> @GET
>>>>> @Path("/{id}/")
>>>>>
>>>>> @GET
>>>>> @Path("/{id}")
>>>>>
>>>>> Is there something I'm missing here? For my main Path i've tried:
>>>>>
>>>>> @Path("/some/path/")
>>>>> @Path("/some/path")
>>>>> @Path("/some/path*")
>>>>>
>>>>> And probably some others.
>>>>>
>>>>> Any ideas?
>>>>>
>>>>> Thanks!
>>>>> Chris
>>>>>
>>>>> ---------------------------------------------------------------------
>>>>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>>>>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>>>>
>>>>
>>>>
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>>>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>>>
>>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>