This is an automated email from the ASF dual-hosted git repository. lukaszlenart pushed a commit to branch release/struts-2-5-x in repository https://gitbox.apache.org/repos/asf/struts.git
commit 162e29fee9136f4bfd9b2376da2cbf590f9ea163 Author: Lukasz Lenart <lukaszlen...@apache.org> AuthorDate: Mon Dec 4 06:45:16 2023 +0100 Makes HttpParameters case-insensitive --- .../apache/struts2/dispatcher/HttpParameters.java | 47 +++++++++++++--- .../struts2/dispatcher/HttpParametersTest.java | 65 ++++++++++++++++++++++ 2 files changed, 104 insertions(+), 8 deletions(-) diff --git a/core/src/main/java/org/apache/struts2/dispatcher/HttpParameters.java b/core/src/main/java/org/apache/struts2/dispatcher/HttpParameters.java index d96614205..68d7e14db 100644 --- a/core/src/main/java/org/apache/struts2/dispatcher/HttpParameters.java +++ b/core/src/main/java/org/apache/struts2/dispatcher/HttpParameters.java @@ -25,13 +25,14 @@ import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; @SuppressWarnings("unchecked") -public class HttpParameters implements Map<String, Parameter>, Cloneable { +public class HttpParameters implements Map<String, Parameter> { private Map<String, Parameter> parameters; @@ -39,6 +40,7 @@ public class HttpParameters implements Map<String, Parameter>, Cloneable { this.parameters = parameters; } + @SuppressWarnings("rawtypes") public static Builder create(Map requestParameterMap) { return new Builder(requestParameterMap); } @@ -49,7 +51,15 @@ public class HttpParameters implements Map<String, Parameter>, Cloneable { public HttpParameters remove(Set<String> paramsToRemove) { for (String paramName : paramsToRemove) { - parameters.remove(paramName); + String paramNameLowerCase = paramName.toLowerCase(); + Iterator<Entry<String, Parameter>> iterator = parameters.entrySet().iterator(); + + while (iterator.hasNext()) { + Map.Entry<String, Parameter> entry = iterator.next(); + if (entry.getKey().equalsIgnoreCase(paramNameLowerCase)) { + iterator.remove(); + } + } } return this; } @@ -61,7 +71,17 @@ public class HttpParameters implements Map<String, Parameter>, Cloneable { } public boolean contains(String name) { - return parameters.containsKey(name); + boolean found = false; + String nameLowerCase = name.toLowerCase(); + + for (String key : parameters.keySet()) { + if (key.equalsIgnoreCase(nameLowerCase)) { + found = true; + break; + } + } + + return found; } /** @@ -78,7 +98,14 @@ public class HttpParameters implements Map<String, Parameter>, Cloneable { return result; } + /** + * Appends all the parameters by overriding any existing params in a case-insensitive manner + * + * @param newParams A new params to append + * @return a current instance of {@link HttpParameters} + */ public HttpParameters appendAll(Map<String, Parameter> newParams) { + remove(newParams.keySet()); parameters.putAll(newParams); return this; } @@ -109,11 +136,15 @@ public class HttpParameters implements Map<String, Parameter>, Cloneable { @Override public Parameter get(Object key) { - if (parameters.containsKey(key)) { - return parameters.get(key); - } else { - return new Parameter.Empty(String.valueOf(key)); + if (key != null && contains(String.valueOf(key))) { + String keyString = String.valueOf(key).toLowerCase(); + for (Map.Entry<String, Parameter> entry : parameters.entrySet()) { + if (entry.getKey() != null && entry.getKey().equalsIgnoreCase(keyString)) { + return entry.getValue(); + } + } } + return new Parameter.Empty(String.valueOf(key)); } @Override @@ -206,7 +237,7 @@ public class HttpParameters implements Map<String, Parameter>, Cloneable { * Alternate Builder method which avoids wrapping any parameters that are already * a {@link Parameter} element within another {@link Parameter} wrapper. * - * @return + * @return */ public HttpParameters buildNoNestedWrapping() { Map<String, Parameter> parameters = (parent == null) diff --git a/core/src/test/java/org/apache/struts2/dispatcher/HttpParametersTest.java b/core/src/test/java/org/apache/struts2/dispatcher/HttpParametersTest.java new file mode 100644 index 000000000..7c2efbc12 --- /dev/null +++ b/core/src/test/java/org/apache/struts2/dispatcher/HttpParametersTest.java @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.struts2.dispatcher; + +import org.junit.Test; + +import java.util.HashMap; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class HttpParametersTest { + + @Test + public void shouldGetBeCaseInsensitive() { + // given + HttpParameters params = HttpParameters.create(new HashMap<String, Object>() {{ + put("param1", "value1"); + }}).build(); + + // then + assertEquals("value1", params.get("Param1").getValue()); + assertEquals("value1", params.get("paraM1").getValue()); + assertEquals("value1", params.get("pAraM1").getValue()); + } + + @Test + public void shouldAppendSameParamsIgnoringCase() { + // given + HttpParameters params = HttpParameters.create(new HashMap<String, Object>() {{ + put("param1", "value1"); + }}).build(); + + // when + assertEquals("value1", params.get("param1").getValue()); + + params = params.appendAll(HttpParameters.create(new HashMap<String, String>() {{ + put("Param1", "Value1"); + }}).build()); + + // then + assertTrue(params.contains("param1")); + assertTrue(params.contains("Param1")); + + assertEquals("Value1", params.get("param1").getValue()); + assertEquals("Value1", params.get("Param1").getValue()); + } + +} \ No newline at end of file