-
Enhancement
-
Resolution: Unresolved
-
P4
-
None
-
None
-
generic
-
generic
A DESCRIPTION OF THE PROBLEM :
URLEncoder.encode does the encoding for the form submitted in the URL (application/ x-www-form-urlencoded).
Therefore all spaces are encoded to a plus sign, which is fine. But we want to encode an element of the path.
https://datatracker.ietf.org/doc/html/rfc3986#appendix-A (path-rootless) defines that the plus sign is a valid char for the path. That means if we encode the path element with URLEncoder.encode, the path has a different meaning. Instead, a space must be encoded with %20.
Currently, there is no native encoding available (or I couldn't find it). Also, URI#resolve(String) requires an encoded String.
assertEquals("https://server:port/rootresource/id%20with%20space", new URI("https://server:port").resolve("rootresource").resolve("id with spaces").toString());
// often proposed, but is not RFC conform
assertEquals("https://server:port/rootresource/id+with+space", new URI("https://server:port").resolve("rootresource").resolve(URLEncoder.encode("id with spaces")).toString());
The workaround is a little ugly, but can be re-implemented in several client languages easily.
URLEncoder.encode(element.replace("+", "%2B"), StandardCharsets.UTF_8).replaceAll("\\+", "%20").replaceAll("%252B", "+");
In case there is a better solution, prefer that.
URLEncoder.encode does the encoding for the form submitted in the URL (application/ x-www-form-urlencoded).
Therefore all spaces are encoded to a plus sign, which is fine. But we want to encode an element of the path.
https://datatracker.ietf.org/doc/html/rfc3986#appendix-A (path-rootless) defines that the plus sign is a valid char for the path. That means if we encode the path element with URLEncoder.encode, the path has a different meaning. Instead, a space must be encoded with %20.
Currently, there is no native encoding available (or I couldn't find it). Also, URI#resolve(String) requires an encoded String.
assertEquals("https://server:port/rootresource/id%20with%20space", new URI("https://server:port").resolve("rootresource").resolve("id with spaces").toString());
// often proposed, but is not RFC conform
assertEquals("https://server:port/rootresource/id+with+space", new URI("https://server:port").resolve("rootresource").resolve(URLEncoder.encode("id with spaces")).toString());
The workaround is a little ugly, but can be re-implemented in several client languages easily.
URLEncoder.encode(element.replace("+", "%2B"), StandardCharsets.UTF_8).replaceAll("\\+", "%20").replaceAll("%252B", "+");
In case there is a better solution, prefer that.