Author: cbrisson Date: Tue Oct 10 15:31:40 2017 New Revision: 1811713 URL: http://svn.apache.org/viewvc?rev=1811713&view=rev Log: [tools] ImportTool: query string parameters of local url inclusion should overwrite original request ones ()
Modified: velocity/tools/trunk/src/changes/changes.xml velocity/tools/trunk/velocity-tools-view/src/main/java/org/apache/velocity/tools/view/ViewImportSupport.java velocity/tools/trunk/velocity-tools-view/src/test/java/org/apache/velocity/tools/test/blackbox/RequestAdaptor.java Modified: velocity/tools/trunk/src/changes/changes.xml URL: http://svn.apache.org/viewvc/velocity/tools/trunk/src/changes/changes.xml?rev=1811713&r1=1811712&r2=1811713&view=diff ============================================================================== --- velocity/tools/trunk/src/changes/changes.xml (original) +++ velocity/tools/trunk/src/changes/changes.xml Tue Oct 10 15:31:40 2017 @@ -24,13 +24,16 @@ <title>Changelog</title> </properties> <body> - <release version="3.0-SNAPSHOT" date="In Subversion"> + <action type="fix" dev="cbrisson"> + Removed deprecated components velocity-tools-uberjar and velocity-tools-assembly + </action> <action type="add" dev="cbrisson"> ImportTool reenginering: <ul> <li>the ImportSupport utility class has been splitted between o.a.v.generic.ImportSupport and o.a.v.view.ViewImportSupport</li> <li>the ImportTool now has a generic version (for remote URLs import) and a view version (for local URLs import) which cannot use remote URLs in safe mode</li> + <li>the local URLs import respects the 3.1 servlets specification: query parameters of the included URL do overwrite original ones</li> </ul> </action> <action type="add" dev="cbrisson"> Modified: velocity/tools/trunk/velocity-tools-view/src/main/java/org/apache/velocity/tools/view/ViewImportSupport.java URL: http://svn.apache.org/viewvc/velocity/tools/trunk/velocity-tools-view/src/main/java/org/apache/velocity/tools/view/ViewImportSupport.java?rev=1811713&r1=1811712&r2=1811713&view=diff ============================================================================== --- velocity/tools/trunk/velocity-tools-view/src/main/java/org/apache/velocity/tools/view/ViewImportSupport.java (original) +++ velocity/tools/trunk/velocity-tools-view/src/main/java/org/apache/velocity/tools/view/ViewImportSupport.java Tue Oct 10 15:31:40 2017 @@ -29,7 +29,11 @@ import java.io.StringWriter; import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.net.URL; +import java.net.URLEncoder; import java.util.Locale; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; import javax.servlet.RequestDispatcher; import javax.servlet.ServletContext; import javax.servlet.ServletException; @@ -38,6 +42,7 @@ import javax.servlet.http.HttpServletReq import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponseWrapper; +import org.apache.velocity.tools.Toolbox; import org.apache.velocity.tools.generic.ImportSupport; import org.apache.velocity.tools.generic.ValueParser; import org.slf4j.Logger; @@ -183,6 +188,14 @@ public class ViewImportSupport extends I // strip the session id from the url url = stripSession(url); + // According to the 3.1 Servlet API specification, the query string parameters of the URL to include + // take *precedence* over the original query string parameters. It means that: + // - we must merge both query strings + // - we must set aside the cached request toolbox during the include + url = mergeQueryStrings(url); + Object parentToolbox = request.getAttribute(Toolbox.KEY); + request.removeAttribute(Toolbox.KEY); + // from this context, get a dispatcher RequestDispatcher rd = application.getRequestDispatcher(url); if (rd == null) @@ -207,6 +220,10 @@ public class ViewImportSupport extends I throw new IOException("Problem importing the local URL \"" + url + "\": " + se.getMessage(), se); } + finally + { + request.setAttribute(Toolbox.KEY, parentToolbox); + } /* let RuntimeExceptions go through */ // disallow inappropriate response codes per JSTL spec @@ -491,6 +508,57 @@ public class ViewImportSupport extends I } //********************************************************************* + // Merge query strings + + /** + * Merge original parameters into the query string + * + * @param url the url to include + * @return the merged url + */ + protected String mergeQueryStrings(String url) + { + Map<String, String[]> originalParameters = request.getParameterMap(); + if (originalParameters.size() > 0) + { + StringBuilder builder = new StringBuilder(url); + Set<String> newParameterNames = new HashSet<String>(); + int qm = url.indexOf('?'); + if (qm != -1) + { + + String[] newParameters = url.substring(qm + 1).split("&"); + for (String newParam : newParameters) + { + int eq = newParam.indexOf('='); + if (eq != -1) + { + newParam = newParam.substring(eq); + } + newParameterNames.add(newParam); + } + } + char separator = ( qm == -1 ? '?' : '&' ); + for (Map.Entry<String, String[]> entry : originalParameters.entrySet()) + { + String key = entry.getKey(); + if (!newParameterNames.contains(key)) + { + key = URLEncoder.encode(key); + for (String value : entry.getValue()) + { + builder.append(separator); + separator = '&'; + builder.append(key).append('=').append(URLEncoder.encode(value)); + } + } + } + url = builder.toString(); + } + return url; + } + + //********************************************************************* // Fetch local resource @Override Modified: velocity/tools/trunk/velocity-tools-view/src/test/java/org/apache/velocity/tools/test/blackbox/RequestAdaptor.java URL: http://svn.apache.org/viewvc/velocity/tools/trunk/velocity-tools-view/src/test/java/org/apache/velocity/tools/test/blackbox/RequestAdaptor.java?rev=1811713&r1=1811712&r2=1811713&view=diff ============================================================================== --- velocity/tools/trunk/velocity-tools-view/src/test/java/org/apache/velocity/tools/test/blackbox/RequestAdaptor.java (original) +++ velocity/tools/trunk/velocity-tools-view/src/test/java/org/apache/velocity/tools/test/blackbox/RequestAdaptor.java Tue Oct 10 15:31:40 2017 @@ -158,6 +158,18 @@ public class RequestAdaptor implements I { return new IteratorEnumeration(_params.keySet().iterator()); } + else if("getAttribute".equals(methodName)) + { + return null; + } + else if("setAttribute".equals(methodName)) + { + return null; + } + else if("removeAttribute".equals(methodName)) + { + return null; + } else if("getSession".equals(methodName)) { return null;