Skip to content

UriTemplate unconditionally percent-encodes literal part #24094

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
bodewig opened this issue Nov 27, 2019 · 3 comments
Closed

UriTemplate unconditionally percent-encodes literal part #24094

bodewig opened this issue Nov 27, 2019 · 3 comments
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) status: declined A suggestion or change that we don't feel we should currently apply

Comments

@bodewig
Copy link

bodewig commented Nov 27, 2019

Affects: 5.2.1 and earlier

When using UriTemplate with a properly percent-encoded literal part, the percent sign gets encoded a second time. For example

new UriTemplate("https://example.org/foo%20and%20bar/{baz}").expand("xyzzy")

yields https://example.org/foo%2520and%2520bar/xyzzy rather than the expected https://example.org/foo%20and%20bar/xyzzy.

UriTemplate's constructor uses UriComponentsBuilder.build() without any arguments. One option could be to provide a second constructor with a boolean encoded argument mirroring the one-arg version of UriComponentsBuilder.build(). If this sounds like a useful addition I can create a small PR.

@rstoyanchev
Copy link
Contributor

rstoyanchev commented Nov 28, 2019

UriTemplate is a thin wrapper around UriComponentsBuilder that exists for historic reasons, so why not bypass it altogether? That said your requirement can't be expressed with boolean flag because then "{" and "}" are invalid characters and UriComponents will flag them.

UriBuilderFactory provides another thin layer over UriComponentsBuilder with multiple options for encoding. It could be used like this for this use case:

DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory();
factory.setEncodingMode(EncodingMode.VALUES_ONLY);

URI url = factory.uriString("https://example.org/foo%20and%20bar/{baz}").build("xyzzy");

Also see the reference on URI Links.

@rstoyanchev rstoyanchev added status: waiting-for-feedback We need additional information before we can continue status: declined A suggestion or change that we don't feel we should currently apply and removed status: waiting-for-feedback We need additional information before we can continue status: waiting-for-triage An issue we've not yet triaged or decided on labels Nov 28, 2019
@rstoyanchev
Copy link
Contributor

Closing but feel free to comment.

rstoyanchev added a commit that referenced this issue Nov 28, 2019
Also update Javadoc of UriTemplate to point to UriComponentsBuilder and
UriBuilderFactory as more flexible options.

See gh-24094
@bodewig
Copy link
Author

bodewig commented Nov 28, 2019

Many thanks @rstoyanchev I agree this is the better approach.

Actually I've been using UriTemplate transitively via Spring HATEOAS - and @odrotbohm has already taken your advice and fixed things over there. I really appreciate both of you taking time for this.

@sbrannen sbrannen added the in: web Issues in web modules (web, webmvc, webflux, websocket) label Nov 29, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) status: declined A suggestion or change that we don't feel we should currently apply
Projects
None yet
Development

No branches or pull requests

4 participants