Url encoding issue with Jersey Client - java

I need to make a service call such as this:
http://myservice.com/path?var1=value1&var2=value2
The issue I have is value1 and value2 ends up getting encoded, and this makes the service call fail. For example, value1 is something like "a=b&b=c;2&&="... it contains special characters, basically.
I am guessing that this is an issue for the service to fix - to properly handle decoding encoded characters, which I do not think it is currently doing.
Here is a sample of how I am making these requests:
WebTarget target = client.target("http://test.com")
.path("path1")
.queryParam("var1", var1);
Builder builder = target.request();
...
What's puzzling to me is that if I make the same request just using Chrome, everything works. So that makes me to believe that I should have some way with the Jersey API of "disabling" the encoding.

Only way I have found so far to use "raw" Url is to use URI.
So call like this
URI uri = URI.create("http://localhost/~Common~0#/edit?vadf&&sfs&&fdsfd=fs&fsd");
WebTarget target = client.target(uri);
You get request url
1 > GET http://localhost/~Common~0#/edit?vadf&&sfs&&fdsfd=fs&fsd
Everything else I tried resulted in encoding special characters.

Related

fix for spot bug - HRS_REQUEST_PARAMETER_TO_HTTP_HEADER

I am executing below code inside servlet and getting this spot bugs - HRS_REQUEST_PARAMETER_TO_HTTP_HEADER
Bug: HTTP parameter directly written to HTTP header output in SSOIdpLogoutRedirect.doPost(HttpServletRequest, HttpServletResponse)
String relayState = request.getParameter("RELAY_STATE");
if(relayState != null)
{
response.sendRedirect(relayState);
}
To fix this bugs i added below code.
relayState = URLEncoder.encode(relayState,StandardCharsets.UTF_8);
But URL does not redirect in correct way as i can see the relaystate url has been changed after encoding
original relaystate = https://sad.ezhdj.net/system/web/apps/dfgh/
and after encoded it is
relaystate =https%3A%2F%2Fsad.ezdev.net%2Fsystem%2Fweb%2Fapps%2Fdfgh%2F`
you should use HttpServletResponse.encodeRedirectURL() to encode redirect urls:
String encodeRedirectURL(String url)
Encodes the specified URL for use in the sendRedirect method or, if
encoding is not needed, returns the URL unchanged. The implementation
of this method includes the logic to determine whether the session ID
needs to be encoded in the URL.
...
All URLs sent to the HttpServletResponse.sendRedirect method should be
run through this method...
this should work:
response.sendRedirect(response.encodeRedirectURL(relayState));
since your url doesn't actually need encoding, output from encodeRedirectURL() will be:
https://sad.ezhdj.net/system/web/apps/dfgh/
and the redirect will work just fine.
edit:
apparently proposed solution still triggers HRS_REQUEST_PARAMETER_TO_HTTP_HEADER spotbug error.
after doing little more research I found out that the error is meant to prevent HTTP response splitting vulnerability (i.e. when unwanted \r\n are written in the header section of http response).
we should then better sanitize relayState against this type of vulnerability.
a simple relayState.replace("\r\n", "") is enough to make the error go away:
response.sendRedirect(response.encodeRedirectURL(relayState.replace("\r\n", "")));

How to suppress url encoding with spring boot

I have created a GET/POST API using Spring boot which has a http url parameter say refid. Now this parameter is already encoded before invoking GET/POST request
e.g. http://localhost:8080/users/TESTFNkJXiQAH%2FJBKxigBx
But, when I deploy this through Spring Boot, the encoded refid is encoded again and the refid changes. i.e. it becomes:
http://localhost:8080/users/TESTFNkJXiQAH%252FJBKxigBx
I want to suppress this 2nd encoding by Spring boot. Can anyone advise here?
Don't know if you are still having this problem or you found out why it's happening, but because I was trying to explain to someone the phenomenon, I looked if there is already a good explanation. But since you also ask and I didn't find any, here is my answer.
So you encode your refid
TESTFNkJXiQAH%2FJBKxigBx
before you send it through the url, which then you give into a browser. Now this is only the encoded refid. When you call it through a URL directly you have to encode it again, according to the HTML URL encoding standards. That’s why the double escape. Also read this. E.g. so if your refid looks like this
test%123
and you encode it you turn it into
test%25123
now if you also want to pass it through a url on the browser you'd have to encode it again.
test%2525123
But if a service A is using this service and service A encodes this refid properly then you wont have this problem. It's happening only because you are trying to call this api endpoint through the browser.
Of course I take for granted that you are doing this:
String decoded = URLDecoder.decode(refid, "UTF-8");
in your controller
Pass the decoded URL in first place instead of doing inconvenient things to stop double encoding.
You get already decoded field in rest controller.
Example if you pass www.xyz.com?name=nilesh%20salpe
you will get value of param name as "nilesh salpe" and not "nilesh%20salpe"
This is a basic example of URLDecoder:
#RequestMapping(value = "/users/{refId}", method = GET)
public void yourMethod(#PathVariable("refId") String refId) {
// This is what you get in Spring Boot
String encoded = refId; //"TESTFNkJXiQAH%252FJBKxigBx"
String decoded = URLDecoder.decode(encoded, "UTF-8");
System.out.println(decoded);
// Result TESTFNkJXiQAH%2FJBKxigBx
}

Sending simple as URL parameter HttpClient GET request

I am developing an Android application in which I am trying to send a simple array as a URL parameter, but it is not working properly. I am using a HTTP client and GET method. I have tried this in the following way:
StringBuilder sb = new StringBuilder();
sb.append(URLEncoder.encode(e.getKey(), "UTF-8")).append('=').append(URLEncoder.encode(e.getValue()+"", "UTF-8"));
where e.getValue() is ArrayList<Integers>
My URL params are appended %5B28%5D when I am sending [28]. If I don't use URL encoder then it goes as [28] But I want to use URL encoder. Am I doing anything wrong?
Your code is fine. this is how URL encoding works.
Seems like there issue in server at the time of decoding.
Debug the server for any possible issue with decoding.
also refer this answer for a better way of sending an array in get request.

Uri not Absolute exception getting while calling Restful Webservice

The below code snippet is using to call my web service using restful API.
ClientConfig config = new DefaultClientConfig();
Client client = Client.create(config);
String uri= "https://127.0.0.1:8443/cas-server-webapp-3.5.0/login";
WebResource resource = client.resource(URLEncoder.encode(uri));
MultivaluedMap<String, String> queryParams = new MultivaluedMapImpl();
queryParams.add("username", "suresh");
queryParams.add("password", "suresh");
resource.queryParams(queryParams);
ClientResponse response = resource.type(
"application/x-www-form-urlencoded").get(ClientResponse.class);
String en = response.getEntity(String.class);
System.out.println(en);
And getting this exception while running the above code
com.sun.jersey.api.client.ClientHandlerException: java.lang.IllegalArgumentException: URI is not absolute
at com.sun.jersey.client.urlconnection.URLConnectionClientHandler.handle(URLConnectionClientHandler.java:151)
at com.sun.jersey.api.client.Client.handle(Client.java:648)
at com.sun.jersey.api.client.WebResource.handle(WebResource.java:680)
I googled many articles and did'nt get where i am doing wrong .
Side note :cas-server-webapp-3.5.0 war deployed on my machine in Apache tomacat7
An absolute URI specifies a scheme; a URI that is not absolute is said to be relative.
http://docs.oracle.com/javase/8/docs/api/java/net/URI.html
So, perhaps your URLEncoder isn't working as you're expecting (the https bit)?
URLEncoder.encode(uri)
For others who landed in this error and it's not 100% related to the OP question, please check that you are passing the value and it is not null in case of spring-boot: #Value annotation.
The problem is likely that you are calling URLEncoder.encode() on something that already is a URI.
Maybe the problem only in your IDE encoding settings. Try to set UTF-8 everywhere:
In an API Key Authorization Scenario...
You may be performing the 2nd REST call after getting an AUTH_TOKEN and ENDPOINT_URL from the first REST call.
Check your concatenation of "<ENDPOINT_URL> + <API_METHOD_URI>", you may be sending only the API_METHOD_URI.
This happened to me using the Streamsets integration platform trying to connect to Oracle's Responsys API.
For me, I was getting this error, when configuation in yaml files, which composed my URL was changed. oops,

Server returned HTTP response code: 400

I am reading data from a webservice. The issue if I put the link on the browser it works fine. When I run like this give me error. I am suspecting is it due to the way how I send my parameters. My paramater list has this dID=1,5,7,11,14,18,26&FromDate=18 Sep 2012 00:00 am&ToDate=18 Sep 2012 10:00 am. Do I need to do some encoding here?
URL xmlURLDM = new URL(urlDM);
InputStream xml2 = xmlURLDM.openStream();
I get this error
java.io.IOException: Server returned HTTP response code: 400 for URL:
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1612)
at java.net.URL.openStream(URL.java:1035)
at xmlreader.main(xmlreader.java:172)
You do need encoding, most likley it is the spaces in your URL that is causing the trouble.
Use Javas built in url-encoding. eg:
String encoded = URLEncoder.encode(myUrl, "UTF-8");
...
call web service with encoded as URL
There can be other reasons for the status code being 400, but this encoding issue is probably your first stumbling block.
The Documentation of URL says,
The URL class does not itself encode or decode any URL components
according to the escaping mechanism defined in RFC2396. It is the
responsibility of the caller to encode any fields, which need to be
escaped prior to calling URL, and also to decode any escaped fields,
that are returned from URL. Furthermore, because URL has no knowledge
of URL escaping, it does not recognise equivalence between the encoded
or decoded form of the same URL.
So please use URLEncoder.encode() before you invoke URL()

Categories