Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow multiple request parameters with the same key #243

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -100,21 +101,21 @@ protected void service(HttpServletRequest servletRequest, HttpServletResponse se
} catch (URISyntaxException e) {
throw new ServletException("Unexpected URI parsing error on " + queryString, e);
}
LinkedHashMap<String, String> params = new LinkedHashMap<String, String>();
LinkedHashMap<String, List<String>> params = new LinkedHashMap<>();
for (NameValuePair pair : pairs) {
params.put(pair.getName(), pair.getValue());
params.computeIfAbsent(pair.getName(), k -> new ArrayList<>()).add(pair.getValue());
}

//Now rewrite the URL
StringBuffer urlBuf = new StringBuffer();//note: StringBuilder isn't supported by Matcher
Matcher matcher = TEMPLATE_PATTERN.matcher(targetUriTemplate);
while (matcher.find()) {
String arg = matcher.group(1);
String replacement = params.remove(arg);//note we remove
List<String> replacement = params.remove(arg);//note we remove
if (replacement == null) {
throw new ServletException("Missing HTTP parameter "+arg+" to fill the template");
}
matcher.appendReplacement(urlBuf, replacement);
matcher.appendReplacement(urlBuf, replacement.get(0));
}
matcher.appendTail(urlBuf);
String newTargetUri = urlBuf.toString();
Expand All @@ -129,12 +130,14 @@ protected void service(HttpServletRequest servletRequest, HttpServletResponse se

//Determine the new query string based on removing the used names
StringBuilder newQueryBuf = new StringBuilder(queryString.length());
for (Map.Entry<String, String> nameVal : params.entrySet()) {
if (newQueryBuf.length() > 0)
newQueryBuf.append('&');
newQueryBuf.append(nameVal.getKey()).append('=');
if (nameVal.getValue() != null)
newQueryBuf.append( URLEncoder.encode(nameVal.getValue(), "UTF-8"));
for (Map.Entry<String, List<String>> nameVal : params.entrySet()) {
for (String nameValElement : nameVal.getValue()) {
if (newQueryBuf.length() > 0)
newQueryBuf.append('&');
newQueryBuf.append(nameVal.getKey()).append('=');
if (nameVal.getValue() != null)
newQueryBuf.append(URLEncoder.encode(nameValElement, "UTF-8"));
}
}
servletRequest.setAttribute(ATTR_QUERY_STRING, newQueryBuf.toString());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,8 @@ public void tearDown() throws Exception {
"/p?query=note%3ALeitbild",
"/p?id=p%20i", "/p%20i", // encoded space in param then in path
"/p?id=p+i",
"/pathwithquestionmark%3F%3F?from=1&to=10" // encoded question marks
"/pathwithquestionmark%3F%3F?from=1&to=10", // encoded question marks
"/multipleparamssamekey?duplicatedParam=value1&duplicatedParam=value&p3=v3" // multiple parameters with the same name
};
//TODO add "/p//doubleslash//f.txt" however HTTPUnit gets in the way. See issue #24

Expand Down