This is an automated email from the ASF dual-hosted git repository. lukaszlenart pushed a commit to branch release/struts-6-3-x in repository https://gitbox.apache.org/repos/asf/struts.git
commit d8c69691ef1d15e76a5f4fcf33039316da2340b6 Author: Lukasz Lenart <lukaszlen...@apache.org> AuthorDate: Mon Dec 4 06:41:51 2023 +0100 Makes HttpParameters case-insensitive --- .../apache/struts2/dispatcher/HttpParameters.java | 31 ++++++++--- .../struts2/dispatcher/HttpParametersTest.java | 65 ++++++++++++++++++++++ 2 files changed, 88 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 b0ab784ab..f35d47583 100644 --- a/core/src/main/java/org/apache/struts2/dispatcher/HttpParameters.java +++ b/core/src/main/java/org/apache/struts2/dispatcher/HttpParameters.java @@ -29,7 +29,7 @@ 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> { final private Map<String, Parameter> parameters; @@ -37,6 +37,7 @@ public class HttpParameters implements Map<String, Parameter>, Cloneable { this.parameters = parameters; } + @SuppressWarnings("rawtypes") public static Builder create(Map requestParameterMap) { return new Builder(requestParameterMap); } @@ -47,7 +48,7 @@ public class HttpParameters implements Map<String, Parameter>, Cloneable { public HttpParameters remove(Set<String> paramsToRemove) { for (String paramName : paramsToRemove) { - parameters.remove(paramName); + parameters.entrySet().removeIf(p -> p.getKey().equalsIgnoreCase(paramName)); } return this; } @@ -59,12 +60,15 @@ public class HttpParameters implements Map<String, Parameter>, Cloneable { } public boolean contains(String name) { - return parameters.containsKey(name); + return parameters.keySet().stream().anyMatch(p -> p.equalsIgnoreCase(name)); } /** * Access to this method can be potentially dangerous as it allows access to raw parameter values. + * + * @deprecated since 6.4.0, it will be removed with a new major release */ + @Deprecated private Map<String, String[]> toMap() { final Map<String, String[]> result = new HashMap<>(parameters.size()); for (Map.Entry<String, Parameter> entry : parameters.entrySet()) { @@ -73,7 +77,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; } @@ -100,8 +111,11 @@ public class HttpParameters implements Map<String, Parameter>, Cloneable { @Override public Parameter get(Object key) { - if (parameters.containsKey(key)) { - return parameters.get(key); + if (key != null && contains(String.valueOf(key))) { + return parameters.entrySet().stream() + .filter(p -> p.getKey().equalsIgnoreCase(String.valueOf(key))) + .findFirst().map(Entry::getValue) + .orElse(new Parameter.Empty(String.valueOf(key))); } else { return new Parameter.Empty(String.valueOf(key)); } @@ -177,8 +191,8 @@ public class HttpParameters implements Map<String, Parameter>, Cloneable { public HttpParameters build() { Map<String, Parameter> parameters = (parent == null) - ? new HashMap<>() - : new HashMap<>(parent.parameters); + ? new HashMap<>() + : new HashMap<>(parent.parameters); for (Map.Entry<String, Object> entry : requestParameterMap.entrySet()) { String name = entry.getKey(); @@ -197,8 +211,9 @@ 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 + * @deprecated since 6.4.0, use {@link #build()} instead */ + @Deprecated public HttpParameters buildNoNestedWrapping() { Map<String, Parameter> parameters = (parent == null) ? new HashMap<>() 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