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

[jsr339-experts] Re: UriBuilder, forward slashes, path and segments

From: Markus KARG <markus_at_headcrashing.eu>
Date: Sun, 3 Jun 2012 10:21:50 +0200

*sigh*

I do not see what is so hard for everybody to understand with this simple
thing?

As a slash is part of the URI syntax, one has to understand that when it is
part of the data, it obviously has to be encoded EVER as %2F. There is
nothing that is up the user's choice. If one needs to effectively gets a
forward slash, the reason for that simply is that it is NOT part of the
data, but part of the syntax. So it is wrong to use the forward slash in
build() but instead the slash has to be used in path().

See, the API clearly separates building the resulting String in two parts:
Building a syntax template (where a slash must stay a slash) and filling in
user data (where a slash must never stay a slash but always be %2F). Everey
other use of the API is simply wrong.

There is nothing bad with that. We simple force authors of wrong use to
correct their use and fix their apps. If this breaks apps for a while, it
does so by intention, as it forces fixes. This is not an API change. It is a
clarification in how to separate syntax templates from user data.

See, in JDBC you can also directly put quotes (= escape characters) in user
data, what effectively EVER will result in encoded quotes and never result
in quotes being part of the effective SQL command. If you want quotes to be
quotes, you have to use a different command (createStatement) so the driver
knows to keep them. It's the same here. path() says the driver "this is part
of the syntax", build() says the driver "this is part of the data".

And NO, IT IS NOT ACCEPTABLE for anybody that a slash has to be encoded
manually. MANUAL ENCODING IS A 100% NO-GO FOR THIS SPEC, at least for me.
That means, as you noticed certainly, I abstain from lots of dicussion, but
in this one you will notice that I will persistent. Which means: If there is
no solution making encoding of slash in build() the default, this will have
consequences in my end vote of the complete spec. Clear separation of
template building and data provision is one of my key drivers for being in
this EG and I will not accept anything but slash is encoded by default when
used in build().

The confusion comes from the fact that this is not explicitly told and
possibly was not intended by the authors of the JAX-RS spec. But it is what
non-experts understand it when used to other templating APIs.

Regards
Markus

> -----Original Message-----
> From: Bill Burke [mailto:bburke_at_redhat.com]
> Sent: Freitag, 1. Juni 2012 18:59
> To: jsr339-experts_at_jax-rs-spec.java.net
> Subject: [jsr339-experts] Re: UriBuilder, forward slashes, path and
> segments
>
> Well, if you automatically encode '/' in a build(), then what if the
> user does *not* want the '/' encoded? There is no workaround and they
> can't use UriBuilder. Very Bad.
>
> On the other hand, if you do *not* encode '/' in a build(), the work
> around is for the developer to manually encode it. Acceptable.
>
> IMO, there are a lot more use cases that would not want to encode '/'.
> UriBuilder is going to be used a lot to extract link hrefs.
>
> On 6/1/12 9:36 AM, Markus KARG wrote:
> > Gentlemen,
> >
> > please keep things simple.
> >
> > Strings provided by .path() are template placeholders, while Strings
> > provided by .build() are variables content (to be filled into the
> > template placeholders).
> >
> > So if anybody does NOT expect that .path("{a}").build("a/b")
> > effectively produces "a%2FB" in the end has simply done a programming
> fault.
> >
> > Certainly you can punish everybody else by providing another
> > parameter, but in fact, omitting the parameter SHOULD break any
> > existing code that expects
> > .build("a/b") is NOT providing "a%2FB" as this assumption was simply
> a
> > wrong understanding of the sense of template placeholders and
> variables content.
> >
> > Regards
> > Markus
> >
> >> -----Original Message-----
> >> From: Sergey Beryozkin [mailto:sberyozkin_at_talend.com]
> >> Sent: Freitag, 1. Juni 2012 12:43
> >> To: jsr339-experts_at_jax-rs-spec.java.net
> >> Subject: [jsr339-experts] Re: UriBuilder, forward slashes, path and
> >> segments
> >>
> >> On 01/06/12 11:26, Sergey Beryozkin wrote:
> >>> Hi
> >>>
> >>> I remember the lively thread we had awhile back about encoding "/"
> >>> passed to UriBuilder path and segment methods as if it was
> yesterday
> >>> when we talked about it :-), but I have to admit I've no idea what
> >> the
> >>> actual conclusion to it was, sorry :-)
> >>>
> >>> I've just had a related query on the users list and I'm coming to
> >>> the conclusion that the encoding of "/" should be different
> >>> depending on when it is passed to UriBuilder, in case of path()
> methods:
> >>>
> >>> 1. UriBuilder.fromPath("").path("a/b").build()
> >>> should produce "a/b" - as per the JavaDocs of path(...)
> >>>
> >>> 2. UriBuilder.fromPath("").path("{a}").build("a/b")
> >>> should produce "a%2Fb"
> >>>
> >>> The reason I think the 2nd variant should produce "a%2Fb" is
> because
> >>> producing "a/b" will be inconsistent with the fact the the matching
> >>> algorithm will not actually match "a/b" when we have @Path("{a}")
> >>> and I think it should kind of work both ways.
> >>>
> >>> I'm not sure all will agree as one can imagine it can break some
> >>> existing code, but please imagine JAX-RS 2.0 Client code doing 1.
> >>> above and working against the endpoint with @Path("{a}") and then
> >> repeating 2.
> >>> and failing against the same endpoint
> >>>
> >> Actually. In both cases, as it currently stands, we will get "a/b"
> >> and that will fail to match against @Path("{a}") but I think that
> the
> >> user expectation in the 2nd case will likely be for it not to fail.
> >>
> >> Marek, I recall you suggested to add an optional flag to build(), to
> >> influence whether the "/" should be encoded or not in cases like
> >>
> >> UriBuilder.fromPath("").path("{a}").build("a/b");
> >>
> >> example
> >>
> >> UriBuilder.fromPath("").path("{a}").build(true, "a/b");
> >>
> >> produces ("a%2Fb") ?
> >>
> >> thanks, Sergey
> >>
> >>> For segments, the forward slash has to be encoded all the time:
> >>>
> >>> 1. UriBuilder.fromPath("").segment("a/b").build()
> >>> should produce "a%2Fb" - as per the JavaDocs of segment(...)
> >>>
> >>> 2. UriBuilder.fromPath("").segment("{a}").build("a/b")
> >>> should produce "a%2Fb"
> >>>
> >>> I do not see any ambiguity here
> >>>
> >
>
> --
> Bill Burke
> JBoss, a division of Red Hat
> http://bill.burkecentral.com