In brief: URIs (RFC 3986) is a mess, and back to URL.encode for the path in UrlBuilder? (with a second pass though)
http://gwt-code-reviews.appspot.com/754803/diff/21001/22002 File user/src/com/google/gwt/user/server/rpc/RemoteServiceServlet.java (right): http://gwt-code-reviews.appspot.com/754803/diff/21001/22002#newcode79 user/src/com/google/gwt/user/server/rpc/RemoteServiceServlet.java:79: String contextRelativePath = URLDecoder.decode(modulePath.substring(contextPath.length())); On 2010/09/02 10:17:07, hhchan wrote:
On 2010/09/02 09:00:57, tbroyer wrote: > Beware! URLDecoder will decode "+" into a space, whereas > it might really mean a "+". What I mean is that this is > probably a breaking change.
modulePath is only the path though, whcih doesn't include query string. Therefore, we shouldn't be seeing '+'.
Why? "+" is a valid character in path segments, and I can actually map the servlet at any path I want, including one containing a "+": <servlet-mapping> <servlet-name>foo</servlet-name> <url-pattern>/foo+bar</url-pattern> </servlet-mapping>
I hit this because in one of the tests, the module name is actually
/com.google.gwt.junit.JUnitTestWithProperties.JUnit.locale$en_US.my.property$one/com.google.gwt.junit.JUnitTestWithProperties.JUnit.locale$en_US.my.property$one.nocache.js'
which gets encoded by the UrlBuilder on the client side as:
/com.google.gwt.junit.JUnitTestWithProperties.JUnit.locale%24en_US.my.property%24one/com.google.gwt.junit.JUnitTestWithProperties.JUnit.locale%24en_US.my.property%24one.nocache.js'
if I don't decode it here, the tests never pass.
Then I'd rather fix UrlBuilder. The issue is that '$' is a reserved char in URI, which means that a plain '$' and a %-encoded one (%24) are not interchangeable (they can mean different things to the server). I faced something like this with a '+' in the path that was treated as a space by the server (that was a bit more convoluted, as I was sending a %2B but Apache mod_jk were decoding it in its request to Tomcat); I raised an issue and they invoked this obscure rule of RFC 3986: https://issues.alfresco.com/jira/browse/ALF-1857 Therefore, I think maybe UrlBuilder should rather use URL.encode(), as if the path were a full URI, but add a second pass to ensure there are no stray '#' or '?' that could be confused with a hash or query-string delimiter.
I am not sure whether module path like this will ever show up in practice, but I think decoding the path is more correct anyways.
Well, as it's passed to ServletContext#getResourceAsStream, I don't think so. The JavaDoc says (from getResource, to which getResourceAsStream redirects): "The path must begin with a "/" and is interpreted as relative to the current context root.<p>This method allows the servlet container to make a resource available to servlets from any source. Resources can be located on a local or remote file system, in a database, or in a .war file."; also note that it throws a MalformedURLException if the "pathname is not given in the correct form"; so it should be a "URL path", which to me means URL-encoded (though I might be wrong, I'm only interpreting the JavaDoc here!) http://gwt-code-reviews.appspot.com/754803/show -- http://groups.google.com/group/Google-Web-Toolkit-Contributors