Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

URI getRawQuery vs getQuery

Tags:

java

uri

I think that using getQuery loses information, is dangerous and that instead only getRawQuery should be used, and that any query parameter values that are known to be encoded should be manually decoded (once the raw query is split on the & characters) with URLDecoder.

Case in point: Assume you have the URL www.example.com with two query parameters:

  • a parameter url with value =www.otherexample.com?b=2&c=3
  • a nondescript parameter d with value 4.

The parameter url should be url-encoded, so the URI that your application sees is:

www.example.com?url=www%2Eotherexample%2Ecom%3Fb%3D2%26c%3D3&d=4

Now, if you obtain the query part with getQuery, you get the following:

url=www.otherexample.com?b=2&c=3&d=4

Notice that you've already lost information as you can't say whether d is a query parameter of the www.example.com or of www.otherexample.com.

If instead you obtain the query part with getRawQuery, you get the following:

url=www%2Eotherexample%2Ecom%3Fb%3D2%26c%3D3&d=4

This time, no information is lost and all's well. You can parse the query part and URL-decode the value of the url parameter if you like.

Am I missing anything ?

like image 775
Marcus Junius Brutus Avatar asked Feb 13 '18 22:02

Marcus Junius Brutus


People also ask

What is java URI?

What is URI? URI stands for Uniform Resource Identifier. A Uniform Resource Identifier is a sequence of characters used for identification of a particular resource. It enables for the interaction of the representation of the resource over the network using specific protocols.

What does URI resolve do?

resolve. Resolves the given URI against this URI. If the given URI is already absolute, or if this URI is opaque, then the given URI is returned.

How do you get a query in Java?

URL getQuery() method in Java with Examples The getQuery() function is a part of URL class. The function getQuery() returns the Query of a specified URL. Return Type: The function returns String Type Query of a specified URL.

How do you make a URI?

create. Creates a URI by parsing the given string. This convenience factory method works as if by invoking the URI(String) constructor; any URISyntaxException thrown by the constructor is caught and wrapped in a new IllegalArgumentException object, which is then thrown.


1 Answers

You're correct. URI.getQuery() is broken and you shouldn't use it.

Strange thing is I can't find any confirmation of this apart from your post, which made me think maybe URI.getQuery could be useful for something. But after some testing of my own I'm pretty sure it just shouldn't be used unless your application's query string doesn't follow the convention of separating arguments with ampersand.

EDIT 11/11/2019

As pointed out in a comment below, while you can use URI.getRawQuery() to work around the broken URI.getQuery() method, you can't just use the raw query as the query argument to the multi-argument URI constructor, as that constructor is also broken.

You can't use the multi-argument URI constructor if any of the query string arguments contain an ampersand. You could argue this is a bug, but the documentation of the expected behaviour contradicts itself so it's not clear which behaviour is correct. The javadoc of the multi-argument constructor says "Any character that is not a legal URI character is quoted". This implies that an escaped octet should NOT be quoted because the main class documentation includes it as a legal character ("The set of all legal URI characters consists of the unreserved, reserved, escaped, and other characters"). But further down, it documents the observed behaviour that the percent character ('%') is always quoted by the multi-argument constructors, which one assumes is without regard for whether it's part of an escaped octet.

Regardless of whether there is ever any acknowledgement that the documentation is contradictory, or what the correct behaviour should be, it is almost certain the current behaviour will never be altered. The only work-around is not to use the multi-argument constructors if you need the URI to end up containing the quoted ampersand octet "%26". Use the single-argument constructor instead, after doing your own encoding and quoting of special characters.

like image 192
Martin Avatar answered Nov 10 '22 06:11

Martin