How to suppress url encoding with spring boot - java

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
}

Related

Url encoding issue with Jersey Client

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.

Get fragment (value hash '#') from a URL in jersey #PathParameter

How can I get the fragment (value hash '#') from a URL using Jersey #PathParameter?
#Path("Step2")
public class AdResource {
#GET
#Produces(MediaType.APPLICATION_JSON)
#Path("/{password:.+}/")
public String doResc(#PathParam("password") String pwd){
System.out.println(pwd);
}
My URL is http://localhost:8080/Sample/webapi/Step2/Password#12#
but the password will be display "Password#12" only the hash(#) is missing..
Try to encode/decode the url.
for javascript:
encodeURI(uri)
then decode it in java using URLDecoder
Since you seem to have a hash in your actual value, and it's not meant to be a fragment, it needs to be encoded before sending. URL encoding is the proper way to do it (like the other answer suggests).
Note also that there are other issues sending password in the url, such as it will be stored in different access logs, it will be part of browser url history etc. Usually you should not send it that way. Prefer POST body.

Extracting ViewState when testing JSF with JMeter

I'm using JMeter to do some load tests on my JSF application and I'm having trouble passing the ViewState along the pages. The ViewState variable doesn't get extracted at all or it doesn't get passed along the pages.
I've recorded my test steps with a proxy server and this is what it looks like:
I've added the Regex extractor in the first GET request. Tested the regex and it is correct.
In every POST request I replace the hardwired View IDs with my variable.
And what I get when I send the request is the following:
The POST parameters are incorrect, as it sends the name of the variable.
POST data:
loginForm%3ArequestToken=&loginForm%3Ausername=heller&loginForm%3Apassword=%21QAYxsw2%A7EDC&loginForm%3AloginButton=Anmelden&com.sun.faces.VIEW=%24%7BjsfViewState%7D&loginForm=loginForm
Could you tell what I'm doing wrong here?
Thanks!
The ViewState parameter is an encoded value (Base64 I believe?) and may contain values that would be inappropriate if passed in a GET request through the url. URL parameters are typically encoded so that special values (Eg. space -> %20) can be represented and decoded when the request reaches the server.
The issue here is that the following request is a POST meaning that the parameters do not need to be URL encoded.
com.sun.faces.VIEW=%24%7BjsfViewState%7D&loginForm=loginForm
The above shows that JMeter or some other process is URL encoding the ViewState in the request which is incorrect. The value of the ViewState should simply be sent as is.
Found my problem: the regex was wrong, so it couldn't find anything in the response. I had to change the regex. Noticed it after adding a default value "NOT FOUND".

How do I get Rest Assured to return the text (non-encrypted or streamed) value in my REST response?

I recently moved over to Java and am attempting to write some REST tests against the netflix REST service.
I'm having an issue in that my response using rest assured either wants to send a gzip encoded response or "InputStream", neither of which provide the actual XML text in the content of the response. I discovered the "Accept-Encoding" header yet making that blank doesn't seem to be the solution. With .Net I never had to mess with this and I can't seem to find the proper means of returning a human readable response.
My code:
RestAssured.baseURI = "http://api-public.netflix.com";
RestAssured.port = 80;
Response myResponse = given().header("Accept-Encoding", "").given().auth().oauth(consumerKey, consumerSecret, accessToken, secretToken).param("term", "star wars").get("/catalog/titles/autocomplete");
My response object has a "content" value with nothing but references to buffers, wrapped streams etc. Trying to get a ToString() of the response doesn't work. None of the examples I've seen seem to work in my case.
Any suggestions on what I'm doing wrong here?
This has worked for me:
given().config(RestAssured.config().decoderConfig(DecoderConfig.decoderConfig().noContentDecoders())).get(url)
I guess in Java land everything is returned as an input stream. Using a stream reader grabbed me the data I needed.
Until its version 1.9.0, Rest-assured has been providing by default in the requests the header "Accept-Encoding:gzip,deflate" with no way of changing it.
See
https://code.google.com/p/rest-assured/issues/detail?id=154
It works for me:
String responseJson = get("/languages/").asString();

Design solution for URL encoding

I am planning a URL rewriter/encoder (maybe rewriter is a better term). The main purpose is to hide the exact URL from the client, since if he is smart enough, he can figure out how to mess up the application.
The URL encoder would be an injective function f(x) = y. The decoder would be the inverse function of f, say g such that g(y) = x. This way I can encode and decode my URLs.
A URL like:
http://www.myapp.com/servlet/myapp/template/MyScreen.vm/action/MyAction
would be encoded to something like:
http://www.myapp.com/uyatsd6787asv6dyuasgbdxuasydgb876876v
It does not matter what is in the encoded URL as far as it is not understandable.
The problem is that I do not know how to manipulate the URL that the browser displays. I am using JBoss as a servlet container and Turbine servlet as the web application framework.
I would need a module that receives the encoded URL, decodes it, passes it to Turbine, then it modifies the response's URL to show the encoded URL again.
Previous attempts to solve the problem:
I have created a servlet filter, but I can not access the URL since the filter receives a ServletRequest that is a JBoss implementation. As far as I have read it seems that a servlet filter is not a good choice for manipulating the URL.
Maybe you could do something like write a servlet that accepts the initial request, decodes the URL, and then internally forwards to your existing servlet.
For example, have a servlet that will accept:
www.myapp.com/enc/uyatsd6787asv6dyuasgbdxuasydgb876876v
This servlet could be set to handle requests that begin with /enc/ or some other marker to indicate that the URL needs to go to the decoder servlet. It would decode to the URL to:
/servlet/myapp/template/MyScreen.vm/action/MyAction
and then internally forward to this URL on your existing servlet using something like:
getServletContext().getRequestDispatcher(decoded_url).forward(req, res);

Categories