StrutsLinkTool breaks paths containing a query string
-----------------------------------------------------
Key: VELTOOLS-138
URL: https://issues.apache.org/jira/browse/VELTOOLS-138
Project: Velocity Tools
Issue Type: Bug
Components: GenericTools
Affects Versions: 2.0
Reporter: Gabriel Lavoie
Fix For: 2.0.x
When using StrutsLinkTool with a Struts global-forward containing a query
string in its path, the question mark separating the path from the query string
gets encoded into %3F and the generated link is broken. I traced problem down
to the "public LinkTool absolute(Object obj)" method from the "LinkTool" class
that doesn't manage well "non-absolute" links (not starting with the "http"
prefix). Those links are managed as if they were only a path and the query
string isn't extracted. The Java URI class is able to manage such link to
extract correctly the information.
Here's a patch that solves the problem (including a unit test that will fail if
LinkTool.java isn't patched):
--- src/main/java/org/apache/velocity/tools/generic/LinkTool.java Wed Mar
16 13:35:18 2011
+++ src/main/java/org/apache/velocity/tools/generic/LinkTool.java Wed Mar
16 13:42:28 2011
@@ -1349,40 +1349,44 @@
else
{
pth = String.valueOf(obj);
+
+ // looks absolute already
+ URI uri = toURI(pth);
+ if (uri == null)
+ {
+ return null;
+ }
+
if (pth.startsWith(DEFAULT_SCHEME))
{
- // looks absolute already
- URI uri = toURI(pth);
- if (uri == null)
- {
- return null;
- }
copy.setScheme(uri.getScheme());
copy.setUserInfo(uri.getUserInfo());
copy.setHost(uri.getHost());
copy.setPort(uri.getPort());
- // handle path, query and fragment with care
- pth = uri.getPath();
- if (pth.equals("/") || pth.length() == 0)
- {
- pth = null;
- }
- copy.setPath(pth);
- if (uri.getQuery() != null)
- {
- copy.setQuery(uri.getQuery());
- }
- if (uri.getFragment() != null)
- {
- copy.setFragment(uri.getFragment());
- }
- return copy;
}
- else if (!pth.startsWith("/"))
+
+ // handle path, query and fragment with care
+ pth = uri.getPath();
+
+ if (pth.equals("/") || pth.length() == 0)
+ {
+ pth = null;
+ }
+
+ if (pth != null && !pth.startsWith("/"))
{
// paths that don't start with '/'
// are considered relative to the current directory
pth = combinePath(getDirectory(), pth);
+ }
+
+ if (uri.getQuery() != null)
+ {
+ copy.setQuery(uri.getQuery());
+ }
+ if (uri.getFragment() != null)
+ {
+ copy.setFragment(uri.getFragment());
}
}
copy.setPath(pth);
--- src/test/java/org/apache/velocity/tools/generic/LinkToolTests.java Wed Mar
16 13:35:42 2011
+++ src/test/java/org/apache/velocity/tools/generic/LinkToolTests.java Wed Mar
16 13:43:35 2011
@@ -463,6 +463,16 @@
assertEquals("http://apache.org/test/bar.vm", result.toString());
result = result.absolute("/woogie.vm");
assertEquals("http://apache.org/woogie.vm", result.toString());
+
+ result = link.absolute("http://apache.org/a/path?param1=value1");
+ assertEquals("apache.org", result.getHost());
+ assertEquals("value1", result.getParams().get("param1"));
+ assertEquals("/a/path", result.getPath());
+
+ result = link.absolute("/a/path?param1=value1");
+ assertNull(result.getHost());
+ assertEquals("value1", result.getParams().get("param1"));
+ assertEquals("/a/path", result.getPath());
}
public @Test void methodGetBaseRef() throws Exception
--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]