jsr339-experts@jax-rs-spec.java.net

[jsr339-experts] Re: [jax-rs-spec users] Re: Re: UriBuilder.segment and build with encodePathSlash

From: Bill Burke <bburke_at_redhat.com>
Date: Tue, 23 Oct 2012 13:17:14 -0400

Markus, I personally find it very weird that '/' would ever be
automatically encoded in a path template variable as it is a valid path
character as per the URI RFC. IMO, if you want special encoding rules
that are different than what is specified in the URI RFC's, then, IMO,
you should have to manually encode them, or have us provide a method
that encodes a string for you.

On 10/23/2012 12:56 PM, Markus KARG wrote:
> Sergey, in fact I do not understand why you roll up again the completed
> discussion again. What do you not understand with the user's expectation
> that values (including slashes) provided to the build() method have to be
> encoded ALWAYS as they are APPLICATION DATA (= decided by the user), while
> values provided to any other methods like path() or segment() will be
> encoded if this is needed due to the particular syntax of that URI part as
> they form URI SYNTAX (= decided by the program)? Why can you not accept that
> simple rule (maybe I miss something important)?
>
>> 1. assertEquals("a/b", uriBuilder.fromPath("").path("a/b").build());
>> 2. assertEquals("a%2Fb",
>> uriBuilder.fromPath("").path("{a}").build("a/b"));
>>
>> 3. assertEquals("a%2Fb",
>> uriBuilder.fromPath("").segment("a/b").build());
>> 4. assertEquals("a%2Fb",
>> uriBuilder.fromPath("").segment("{a}").build("a/b"));
>>
>>
>> Note 3 and 4 produce the consistent output - it is easy to see why -
>> the
>> literal value as well as the "{a}" substitution are 'segments'
>>
>> 1 and 2 produce the inconsistent results, why, because Markus thought
>> it
>> was logical to get "/" encoded by default, despite UriBuilder saying
>> loudly the encoding rules are scoped by the specific URI scheme rules.
>> This breaks 2 of CXF tests and I wonder are we breaking the
>> expectations
>> of the users migrating from 1.1 or not (the fact TCK is silent on that
>> does not count IMHO).
>>
>> Let me step back and review the actual original issue.
>> We have '?' (meaning unclear) in
>>
>> assertEquals(?, uriBuilder.fromPath("").path("{a}").build("a/b"));
>>
>> Should "/" in "a/b" be encoded or left as is, who knows ? What if we
>> have "build(readFromDB())" - where "a/b" is read from the db, etc.
>
> It MUST be encoded ALWAYS as it is provided to the BUILD() method. Fullstop.
>
>> How we solve this issue ?
>
> What issue? I do not see any issue.
>
>> We introduce 4 new methods (2 from the build and 2 from replaceTemplate
>> families) with this extra flag dedicated to dealing with "/", a single
>> symbol which happens to be important for the URI path component.
>>
>> We have 1. and 2. above producing inconsistent output where UriBuilder
>> package-level documentation conflicts with the special rules for
>> encoding "/".
>
> There is no special rule for slash. The rules of URIs are clear: APPLICATION
> DATA is to be encoded.
>
>> We have 4 extra methods which don't make sense with a dangling boolean
>> flag to be used when no template vars are found in the path component
>> as
>> opposed to the regular build functions which always make sense.
>
> The flag exists solely for backwards compatibility to the FALSE assumption
> what users expect in JAX-RS 1.1. You cannot omit it without breaking
> something.
>
>> So what could've been done instead, to address a tricky issue of
>>
>> uriBuilder.fromPath("").path("{a}").build(readFromDb()),
>> where a return value may have contain "/" which have to be encoded ?
>>
>> Well, recommend users, when they face the issue like this, to use
>>
>> uriBuilder.fromPath("").segment("{a}").build(readFromDb())
>
> The following three reasons had already been discussed and accepted by this
> EG:
>
> (1) This workaround was already discussed in the past and it did not work
> due to a bug in the RI (Jersey), which incorrectly implemented segment().
>
> (2) Also it does not work in case you do fromResource, where the parameter
> is contained in the @Path already.
>
> (3) "Segment" is not an official part of the URI specification (read it
> carefully and you will notice), so we cannot expect people to use segment()
> instead of path(), as it is counter-intuitive.
>
>> and get the implementation to remember the 'origin' of the template
>> var,
>> i.e., whether it came from path() or segment(), we would then see
>> consistently:
>>
>>
>> 1. assertEquals("a/b", uriBuilder.fromPath("").path("a/b").build());
>> 2. assertEquals("a/b",
>> uriBuilder.fromPath("").path("{a}").build("a/b"));
>>
>> 3. assertEquals("a%2Fb",
>> uriBuilder.fromPath("").segment("a/b").build());
>> 4. assertEquals("a%2Fb",
>> uriBuilder.fromPath("").segment("{a}").build("a/b"));
>>
>>
>> Well, I've updated CXF code to support the current approach at the cost
>> of getting the two failing tests 'fixed', but I felt I had to type the
>> above
>>
>>
>> Sergey
>>
>>>> Marek
>>>>
>

-- 
Bill Burke
JBoss, a division of Red Hat
http://bill.burkecentral.com