-
Notifications
You must be signed in to change notification settings - Fork 25.6k
Description
Elasticsearch version: 5.4.0
Plugins installed: N/A
JVM version (java -version): 1.8.0_121
OS version (uname -a if on a Unix-like system): Fedora 25
Description of the problem including expected versus actual behavior:
When calling any of the "performRequest" method of RestClient, the "endpoint" (= path) parameter is not url-encoded. As a result, non-ascii parameters may appear in the resulting request.
One could expect the path to be encoded, because the query parameters, passed as a map, are encoded by RestClient. I'd expect the client to either handle all of the encoding, or none of it.
Steps to reproduce:
- Call `client.performRequest("GET", "foo$bar")
- See how the produced request still includes the "$" character, instead of "%24".
Possible explanation of the issue:
The reason why path is not encoded can be found in RestClient#buildUri
// ...
URIBuilder uriBuilder = new URIBuilder(fullPath);
for (Map.Entry<String, String> param : params.entrySet()) {
uriBuilder.addParameter(param.getKey(), param.getValue());
}
return uriBuilder.build();
The path is passed to the URIBuilder constructor, but the constructor expects a valid (encoded) String representation of an URI, not a non-encoded path.
This can be confirmed by diving deeper into the implementation: URIBuilder(fullPath) first calls new URI(fullPath), which calls parse(false), which sets the path attribute. Then the constructor calls digestURI with the resulting URI, which sets encodedPath (!) to URI.getRawPath(), which simply returns the value of the path attribute that was set earlier, which is not an encoded value...
A simple solution would be to use the default constructor of URIBuilder, and just call setPath(String):
// ...
URIBuilder uriBuilder = new URIBuilder();
uriBuilder.setPath(fullPath);
for (Map.Entry<String, String> param : params.entrySet()) {
uriBuilder.addParameter(param.getKey(), param.getValue());
}
return uriBuilder.build();