Martin Grotzke wrote:
> Hi,
>
> we have a resource method that accepts some query parameter named fq
> (filter query). The fq param accepts ranges for e.g. a price filter, so
> that the value for the fq param might be "price:[160%20TO%20200]".
>
According to the URI ABNF:
sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
/ "*" / "+" / "," / ";" / "="
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
query = *( pchar / "/" / "?" )
'[' and ']' characters are not valid characters of a URI query component.
> When a client performs a request with such a param value, the
> UriComponent.validate says that this is not valid:
>
> [ERROR] 17 Jul 2008 15:50:45,166 btpool0-1 com.sun.jersey.spi.spring.container.servlet.SpringServlet.service:
> Caught exception.
>
> java.lang.IllegalArgumentException: The string 'q=foo&fq=price:[160%20TO%20200]' for the URI component QUERY contains an invalid character, '[', at index 15
> at com.sun.jersey.api.uri.UriComponent.validate(UriComponent.java:95)
> at com.sun.jersey.impl.uri.UriBuilderImpl.encode(UriBuilderImpl.java:353)
> at com.sun.jersey.impl.uri.UriBuilderImpl.replaceQueryParams(UriBuilderImpl.java:286)
> at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:273)
>
> I think this should be valid, even UriComponent.decode handles this
> correctly.
>
The JavaDoc states:
/**
* Decodes characters of a string that are percent-encoded octets using
* UTF-8 decoding (if needed).
* <p>
* It is assumed that the string is valid according to an (unspecified)
URI
* component type. If a sequence of contiguous percent-encoded octets is
* not a valid UTF-8 character then the octets are replaced with '\uFFFD'.
* <p>
* If the URI component is of type HOST then any "%" found between "[]" is
* left alone. It is an IPv6 literal with a scope_id.
* <p>
* @param s the string to be decoded.
* @param t the URI component type, may be null.
* @return the decoded string.
* @throws IllegalArgumentException if a malformed percent-encoded octet is
* detected
*/
Paul.
> One possible patch I can think of is in
> UriComponent.creatingEncodingTables:
>
> Index: src/api/com/sun/jersey/api/uri/UriComponent.java
> ===================================================================
> --- src/api/com/sun/jersey/api/uri/UriComponent.java (revision 1166)
> +++ src/api/com/sun/jersey/api/uri/UriComponent.java (working copy)
> @@ -243,6 +243,8 @@
> tables[Type.PATH.ordinal()] = creatingEncodingTable(l);
>
> l.add("?");
> + l.add("[");
> + l.add("]");
>
> tables[Type.QUERY.ordinal()] = creatingEncodingTable(l);
> tables[Type.FRAGMENT.ordinal()] = tables[Type.QUERY.ordinal()];
>
> This test goes through then:
>
> Index: test/com/sun/jersey/impl/UriComponentValidateTest.java
> ===================================================================
> --- test/com/sun/jersey/impl/UriComponentValidateTest.java (revision 1166)
> +++ test/com/sun/jersey/impl/UriComponentValidateTest.java (working copy)
> @@ -54,4 +54,8 @@
> assertEquals(true, UriComponent.valid("/x20y", UriComponent.Type.PATH));
> assertEquals(true, UriComponent.valid("/x%20y", UriComponent.Type.PATH));
> }
> +
> + public void testQuery() {
> + assertEquals(true, UriComponent.valid("fq=price:[1%20TO%20100]", UriComponent.Type.QUERY));
> + }
> }
>
> Please notice that I took this diff in a branch, so line numbers might
> be wrong.
>
> Any thoughts on this?
>
> Thanx && cheers,
> Martin
>
>
--
| ? + ? = To question
----------------\
Paul Sandoz
x38109
+33-4-76188109