Velocity Tools
  1. Velocity Tools
  2. VELTOOLS-138

StrutsLinkTool breaks paths containing a query string

    Details

    • Type: Bug Bug
    • Status: Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: 2.0
    • Fix Version/s: 2.0.x
    • Component/s: GenericTools
    • Labels:

      Description

      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.

        Activity

        Gabriel Lavoie created issue -
        Gabriel Lavoie made changes -
        Field Original Value New Value
        Labels patch
        Gabriel Lavoie made changes -
        Gabriel Lavoie made changes -
        Description 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
        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.

          People

          • Assignee:
            Unassigned
            Reporter:
            Gabriel Lavoie
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:

              Development