users@jax-rs-spec.java.net

[jax-rs-spec users] [jsr339-experts] Re: Re: Matching algorithm doesn't recurse back on Locators

From: Sergey Beryozkin <sberyozkin_at_talend.com>
Date: Fri, 17 May 2013 21:42:09 +0100

Hi Santiago
On 17/05/13 18:15, Santiago Pericas-Geertsen wrote:
> Bill, Sergey,
>
> I can see the issue that you're reporting. However, and I don't have a copy of the old spec handy, I believe HTTP method filtering was also done in step 3 before, so why did it work before?
>
> The general idea of the algorithm has always been to avoid backtracking; I think it would be possible to construct a more involved example in which you'd need to backtrack more than one step to match something.
>
> Could it be that your implementation always supported backtracking but the TCKs didn't test that before?
>
No, we've never supported back-tracking. And as I tried to clarify,
JAX-RS 1.1 did not even require it and CXF simply followed it to the letter.

When we have

@Path("/")
public class Resource {
     @POST
     @Path("sub")
     public void post();

     @Path("{id}")
     public Resource locator() {
     }

     @GET
     public void get();
}

and

GET /sub

returning 404 is simply not the option IMHO.

JAX-RS 1.1 adds two candidates, post() & locator() and the text clearly
makes locator() win and hence get() selected. No backtracking, simple
comparison or check: post() has a non-matching method, it is out

Likewise if we have

@Path("/")
public class Resource {
     @GET
     @Path("{id}")
     public void get();

     @Path("{id}")
     public Resource locator() {
     }

     @GET
     public void getSub();
}

we have the same 2 candidates, but get() wins because locator() loses
due to the text preferring Tmethod to Tlocator.

Whichever way you go, there's absolutely no need for the backtracking.
The only case where backtracking might be required id when two locators
have exactly the same Path, but 2.0 correctly recommends to report an
error in this case.

FYI, in 1.1, originally sublocators were winning in the latter case, and
I recall myself when the decision was made to make sure that get() in
the 2nd example wins, but the bottom line is that both get() and
locator() has always been two candidates to be selected from.

We have tests on the above and the documentation on this case.
It is backward-incompatible spec change, please check 1.1 text.

We have to keep 1.1 behavior, we can not break the existing code with 2.0

Thanks, Sergey





> -- Santiago
>
> On May 17, 2013, at 8:59 AM, Bill Burke <bburke_at_redhat.com> wrote:
>
>>
>>
>> On 5/17/2013 4:35 AM, Sergey Beryozkin wrote:
>>> Hi Bill
>>> On 17/05/13 04:41, Bill Burke wrote:
>>>> Let me give you an example:
>>>>
>>>> Given this request:
>>>>
>>>> OPTIONS /sub
>>>>
>>>> This will match:
>>>>
>>>> @Path("/")
>>>> class Resource {
>>>>
>>>> @Path("{id}")
>>>> public Locator locator() { return new Locator();}
>>>>
>>>> }
>>>>
>>>> class Locator {
>>>>
>>>> @OPTIONS
>>>> public String options() { return "OK"; }
>>>> }
>>>>
>>>> But this won't match:
>>>>
>>>> @Path("/")
>>>> class Resource {
>>>>
>>>> @GET
>>>> @Path("sub")
>>>> public String get() { return "OK"; }
>>>>
>>>> @Path("{id}")
>>>> public Locator locator() { return new Locator();}
>>>>
>>>> }
>>>>
>>> Seems to me it will too. @GET method is selected only if no @OPTIONS is
>>> available and in this case it is available.
>>>
>>
>> Check out the spec. It won't match because "sub" is matched in 2(h). 2(h) says that if there are any non-locator matches, then go to 3, then 3(a) will abort the request.
>>
>> I ran into this very problem when testing against the TCK. The TCK assumes there is no loopback to Locators and one of the tests fails. I'm able to fix this problem quite easily, but, I have some users that reported this as a "bug". They will now "regress".
>>
>>
>> --
>> Bill Burke
>> JBoss, a division of Red Hat
>> http://bill.burkecentral.com
>


-- 
Sergey Beryozkin
Talend Community Coders
http://coders.talend.com/
Blog: http://sberyozkin.blogspot.com