users@jersey.java.net

Re: [Jersey] UriComponent.validate does not allow brackets []?

From: Martin Grotzke <martin.grotzke_at_freiheit.com>
Date: Tue, 22 Jul 2008 23:36:47 +0200

Hi Paul,

thanx for your feedback! Now I changed the URI for my test to use
URLCodec and it works :)

 "/products?q=foo&fq=price:" + new URLCodec().encode( "[10 TO 100]" );

Cheers,
Martin


On Tue, 2008-07-22 at 13:19 +0200, Paul Sandoz wrote:
> 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
> >
> >