Url Routing with Encoding in Java Web API - java

I'm new to java and I'm trying to write a utility api to encrypt/decrypt a string. I have my controller and request mapping working, and I have the encrypt/decrypt methods working.
The problem I'm running into is decrypting a string that contains a forward slash ('/'). If I leave it unencoded in the url (such as http://localhost:8080/api/package/util/decrypt/oJfTtchpM9WC/4Oqpu7FZQ==) then url routing breaks (which is obvious why).
If I url encode it (such as http://localhost:8080/api/package/util/decrypt/oJfTtchpM9WC%2F4Oqpu7FZQ==) then the value in the path variable is empty.
Also note that http://localhost:8080/api/package/util/decrypt/oJfTtchpM9WC (no slash) works fine.
It seems whenever I put in a '%' into the path variable, I just get a blank page in response. Doesn't hit the method. Doesn't throw an exception (that I can find - again, I'm learning the environment still)
I've simplified my decrypt method to only output the path variable denoted as data
#RequestMapping(value = "/util/decrypt/{data}", method = RequestMethod.GET)
#ResponseBody
public String decrypt(HttpServletResponse httpResponse,
#PathVariable String data) throws Exception
{
return data;
// return URLDecoder.decode(data, "UTF-8");
}
Can anyone explain to me what is happening and how I can get this working?
Many thanks!!

I updated my encrypt method to use the function encodeBase64URLSafeString (vs just encodeBase64String) and also changed it to pass the data as a standard request param (ie ?data=string). This removed the problem.
Encodes binary data using a URL-safe variation of the base64 algorithm
but does not chunk the output. The url-safe variation emits - and _
instead of + and / characters. Note: no padding is added.

Related

How can I prevent the automatic decoding of RequestParam Strings in a Spring controller

I have an HTTP GET request controller endpoint where I take in a fileName as a query param and pass that on to another service. For this request the param the filename could include any sort of special characters and I would like to keep these values encoded when passing them on. 2 Characters that have been causing issues are spaces (%20) and +(%2B).
How can I keep these characters encoded in the request params.
So far I have tried using the #RequestParam annotation as well as retrieving the params via HttpServletRequest.getParameterValues(String) but both return the decoded values as spaces.
Any help is appreciated thanks!
Yes, these are automatically decoded by the servlet API. You should be able to re-encode them -
encodedValue = URLEncoder.encode(value, StandardCharsets.UTF_8);
I found out that I could get the actual value passed in by using the HttpServletRequest.getQueryString() method. Parsing this query string I was able to get the un-decoded version of the fileName being passed in. I hope this helps someone in the future.

How do I parse an HttpExchange request after an ending slash?

I have a request as follows:
localhost:8000/location/:01
My code takes as input an HttpContext request.
func(HttpExchange r) {
String area_path = r.getRequestURI(); // Equals string "/location/"
}
How do I parse an HttpExchange correctly so I can pull out the "01" from this path and store it as a variable?
That (localhost:8000/location/:01) is not a valid URL or URI
A plain colon character is not legal in the path of a URL or URI. If you want to put a colon in the path, it must be percent-encoded. Furthermore, if this was a URL, it would start with a protocol; e.g. http:.
Now ... it is unclear what the HTTP stack you are using will do with a syntactically incorrect URL / URI, but it could simply be ignoring the colon and the characters after it.
Your code looks a bit odd too. You have tagged the question as [java]. But the code looks like JavaScript rather than Java; i.e. func is a Javascript keyword. But it also looks like you are using the (deprecated) com.sun.net.httpserver.HttpExchange Java class. I don't know what to make of that ...
My advice:
Don't use a colon character in the URL path.
If you must do it, then percent-encode the colon it.
If you cannot encode it properly, then you may need to find and use a different framework for your HTTP request handling. One that will accept and handle a malformed URL / URI in the way that you want. (Good luck finding one!)
Unfortunately, the details in your question are too sketchy to give more detailed advice.

Missing entire string in query parameter when given special character - Java Spring Boot

I'm currently writing a Java Spring Boot application with a REST API server. I'm cutting out a lot of non-relevant code here, but one of my POST routes looks like this:
#RequestMapping(value = "/post-request", method = RequestMethod.POST)
public String postRequest(
#RequestParam(name = REQUEST_STRING) String requestString,
){ logger.info(requestString)}
This approach works great for most strings, but I'm getting a really weird error when including special characters in the request parameter. For example, if I send the application with a request containing
This (&) is an ampersand
within Postman, the application will log
This (
and cut out everything else after the special character. I'm fairly certain that this has to do with the way that special characters are encoded within REST API's, especially when it comes to request parameters, but what am I doing wrong here? Is there a way for me to get the full string using Java Spring Boot, or am I restricted from doing this?
RequestParam are diffrentiated with "&" so if you pass "&" directly in string anything after & will be treated as another RequestParam
eg:
http://testdata.com?username=test&password=hello&123&type=user
Here password will be passed as hello and 123 will be treated as anotehr RequestParam
To overcome this you need to do encoding for "&" as "%26"
http://testdata.com?username=test&password=hello%26123&type=user

java servlet: request parameter contains plus

The request parameter is like decrypt?param=5FHjiSJ6NOTmi7/+2tnnkQ==.
In the servlet, when I try to print the parameter by String param = request.getParameter("param"); I get 5FHjiSJ6NOTmi7/ 2tnnkQ==. It turns the character + into a space. How can I keep the orginal paramter or how can I properly handle the character +.
Besides, what else characters should I handle?
You have two choices
URL encode the parameter
If you have control over the generation of the URL you should choose this. If not...
Manually retrieve the parameter
If you can't change how the URL is generated (above) then you can manually retrieve the raw URL. Certain methods decode parameters for you. getParameter is one of them. On the other hand, getQueryString does not decode the String. If you have only a few parameters it shouldn't be difficult to parse the value yourself.
request.getQueryString();
//?param=5FHjiSJ6NOTmi7/+2tnnkQ==
If you want to use the '+' character in a URL you need to encode it when it is generated. For '+' the correct encoding is %2b
Use URLEncoder,URLDecoder's static methods for encoding and decoding URLs.
For example : -
Encode the URL param using
URLEncoder.encode(url,"UTF-8")
Back in the server side , decode this parameter using
URLDecoder.decode(url,"UTF-8")
decode method returns a String type of the decoded URL.
Allthough the question is some years old, I'd like to write down how I fixed the problem in my case: the download link to a file is created in a GWT page where
com.google.gwt.http.client.URL.encode(finalurl)
is used to encode the URL.
The problem was that the "+" sign a customer of us had in the filename wasn't encoded/escaped. So I had to remove the URL.encode(finalurl) and encode each parameter in the url with
URL.encodePathSegment(fileName)
I know my question is bound to GWT but it seems, URLEncoder.encode(string, encoding) should be applied to the parameter only aswell.

Encode URL query parameters

How can I encode URL query parameter values? I need to replace spaces with %20, accents, non-ASCII characters etc.
I tried to use URLEncoder but it also encodes / character and if I give a string encoded with URLEncoder to the URL constructor I get a MalformedURLException (no protocol).
URLEncoder has a very misleading name. It is according to the Javadocs used encode form parameters using MIME type application/x-www-form-urlencoded.
With this said it can be used to encode e.g., query parameters. For instance if a parameter looks like &/?# its encoded equivalent can be used as:
String url = "http://host.com/?key=" + URLEncoder.encode("&/?#");
Unless you have those special needs the URL javadocs suggests using new URI(..).toURL which performs URI encoding according to RFC2396.
The recommended way to manage the encoding and decoding of URLs is to use URI
The following sample
new URI("http", "host.com", "/path/", "key=| ?/#ä", "fragment").toURL();
produces the result http://host.com/path/?key=%7C%20?/%23ä#fragment. Note how characters such as ?&/ are not encoded.
For further information, see the posts HTTP URL Address Encoding in Java or how to encode URL to avoid special characters in java.
EDIT
Since your input is a string URL, using one of the parameterized constructor of URI will not help you. Neither can you use new URI(strUrl) directly since it doesn't quote URL parameters.
So at this stage we must use a trick to get what you want:
public URL parseUrl(String s) throws Exception {
URL u = new URL(s);
return new URI(
u.getProtocol(),
u.getAuthority(),
u.getPath(),
u.getQuery(),
u.getRef()).
toURL();
}
Before you can use this routine you have to sanitize your string to ensure it represents an absolute URL. I see two approaches to this:
Guessing. Prepend http:// to the string unless it's already present.
Construct the URI from a context using new URL(URL context, String spec)
So what you're saying is that you want to encode part of your URL but not the whole thing. Sounds to me like you'll have to break it up into parts, pass the ones that you want encoded through the encoder, and re-assemble it to get your whole URL.

Categories