This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch 7.0.x in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/7.0.x by this push: new 03454db Ensure values are not duplicated when manipulating the vary header 03454db is described below commit 03454dba0567c02e585ad1e745c840925dc650ce Author: Mark Thomas <ma...@apache.org> AuthorDate: Wed Dec 2 18:51:26 2020 +0000 Ensure values are not duplicated when manipulating the vary header --- java/org/apache/tomcat/util/http/ResponseUtil.java | 14 +++--- .../apache/tomcat/util/http/TestResponseUtil.java | 50 +++++++++++----------- webapps/docs/changelog.xml | 4 ++ 3 files changed, 37 insertions(+), 31 deletions(-) diff --git a/java/org/apache/tomcat/util/http/ResponseUtil.java b/java/org/apache/tomcat/util/http/ResponseUtil.java index 1c40d3b..4f5cfbd 100644 --- a/java/org/apache/tomcat/util/http/ResponseUtil.java +++ b/java/org/apache/tomcat/util/http/ResponseUtil.java @@ -21,9 +21,9 @@ import java.io.StringReader; import java.util.ArrayList; import java.util.Collection; import java.util.Enumeration; -import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashSet; import java.util.List; -import java.util.Set; import javax.servlet.http.HttpServletResponse; @@ -76,7 +76,7 @@ public class ResponseUtil { // the existing values, check if the new value is already present and // then add it if not. The good news is field names are tokens which // makes parsing simpler. - Set<String> fieldNames = new HashSet<String>(); + LinkedHashSet<String> fieldNames = new LinkedHashSet<String>(); for (String varyHeader : varyHeaders) { StringReader input = new StringReader(varyHeader); @@ -97,10 +97,12 @@ public class ResponseUtil { // Replace existing header(s) to ensure any invalid values are removed fieldNames.add(name); StringBuilder varyHeader = new StringBuilder(); - varyHeader.append(name); - for (String fieldName : fieldNames) { + Iterator<String> iter = fieldNames.iterator(); + // There must be at least one value as one is added just above + varyHeader.append(iter.next()); + while (iter.hasNext()) { varyHeader.append(','); - varyHeader.append(fieldName); + varyHeader.append(iter.next()); } adapter.setHeader(VARY_HEADER, varyHeader.toString()); } diff --git a/test/org/apache/tomcat/util/http/TestResponseUtil.java b/test/org/apache/tomcat/util/http/TestResponseUtil.java index 68b296d..2597ff4 100644 --- a/test/org/apache/tomcat/util/http/TestResponseUtil.java +++ b/test/org/apache/tomcat/util/http/TestResponseUtil.java @@ -16,8 +16,8 @@ */ package org.apache.tomcat.util.http; -import java.util.HashSet; -import java.util.Set; +import java.util.ArrayList; +import java.util.List; import org.junit.Assert; import org.junit.Test; @@ -31,7 +31,7 @@ public class TestResponseUtil { TesterResponse response = new TesterResponse(); response.getCoyoteResponse(); response.addHeader("vary", "host"); - Set<String> expected = new HashSet<String>(); + List<String> expected = new ArrayList<String>(); expected.add("*"); doTestAddVaryFieldName(response, "*", expected); } @@ -42,7 +42,7 @@ public class TestResponseUtil { TesterResponse response = new TesterResponse(); response.getCoyoteResponse(); response.addHeader("vary", "*"); - Set<String> expected = new HashSet<String>(); + List<String> expected = new ArrayList<String>(); expected.add("*"); doTestAddVaryFieldName(response, "*", expected); } @@ -52,7 +52,7 @@ public class TestResponseUtil { public void testAddAllWithNone() { TesterResponse response = new TesterResponse(); response.getCoyoteResponse(); - Set<String> expected = new HashSet<String>(); + List<String> expected = new ArrayList<String>(); expected.add("*"); doTestAddVaryFieldName(response, "*", expected); } @@ -63,9 +63,9 @@ public class TestResponseUtil { TesterResponse response = new TesterResponse(); response.getCoyoteResponse(); response.addHeader("vary", "foo, bar"); - Set<String> expected = new HashSet<String>(); - expected.add("bar"); + List<String> expected = new ArrayList<String>(); expected.add("foo"); + expected.add("bar"); expected.add("too"); doTestAddVaryFieldName(response, "too", expected); } @@ -76,7 +76,7 @@ public class TestResponseUtil { TesterResponse response = new TesterResponse(); response.getCoyoteResponse(); response.addHeader("vary", "foo, *"); - Set<String> expected = new HashSet<String>(); + List<String> expected = new ArrayList<String>(); expected.add("*"); doTestAddVaryFieldName(response, "too", expected); } @@ -87,9 +87,9 @@ public class TestResponseUtil { TesterResponse response = new TesterResponse(); response.getCoyoteResponse(); response.addHeader("vary", "foo, bar"); - Set<String> expected = new HashSet<String>(); - expected.add("bar"); + List<String> expected = new ArrayList<String>(); expected.add("foo"); + expected.add("bar"); doTestAddVaryFieldName(response, "foo", expected); } @@ -100,9 +100,9 @@ public class TestResponseUtil { response.getCoyoteResponse(); response.addHeader("vary", "foo"); response.addHeader("vary", "bar"); - Set<String> expected = new HashSet<String>(); - expected.add("bar"); + List<String> expected = new ArrayList<String>(); expected.add("foo"); + expected.add("bar"); expected.add("too"); doTestAddVaryFieldName(response, "too", expected); } @@ -114,7 +114,7 @@ public class TestResponseUtil { response.getCoyoteResponse(); response.addHeader("vary", "foo"); response.addHeader("vary", "*"); - Set<String> expected = new HashSet<String>(); + List<String> expected = new ArrayList<String>(); expected.add("*"); doTestAddVaryFieldName(response, "too", expected); } @@ -126,9 +126,9 @@ public class TestResponseUtil { response.getCoyoteResponse(); response.addHeader("vary", "foo"); response.addHeader("vary", "bar"); - Set<String> expected = new HashSet<String>(); - expected.add("bar"); + List<String> expected = new ArrayList<String>(); expected.add("foo"); + expected.add("bar"); doTestAddVaryFieldName(response, "foo", expected); } @@ -138,7 +138,7 @@ public class TestResponseUtil { TesterResponse response = new TesterResponse(); response.getCoyoteResponse(); response.addHeader("vary", "{{{, bar"); - Set<String> expected = new HashSet<String>(); + List<String> expected = new ArrayList<String>(); expected.add("bar"); expected.add("too"); doTestAddVaryFieldName(response, "too", expected); @@ -150,7 +150,7 @@ public class TestResponseUtil { TesterResponse response = new TesterResponse(); response.getCoyoteResponse(); response.addHeader("vary", "{{{, *"); - Set<String> expected = new HashSet<String>(); + List<String> expected = new ArrayList<String>(); expected.add("*"); doTestAddVaryFieldName(response, "too", expected); } @@ -161,18 +161,18 @@ public class TestResponseUtil { TesterResponse response = new TesterResponse(); response.getCoyoteResponse(); response.addHeader("vary", "{{{, bar"); - Set<String> expected = new HashSet<String>(); + List<String> expected = new ArrayList<String>(); expected.add("bar"); doTestAddVaryFieldName(response, "bar", expected); } private void doTestAddVaryFieldName(TesterResponse response, String fieldName, - Set<String> expected) { + List<String> expected) { ResponseUtil.addVaryFieldName(response, fieldName); // There will now only be one Vary header String resultHeader = response.getHeader("vary"); - Set<String> result = new HashSet<String>(); + List<String> result = new ArrayList<String>(); // Deliberately do not use Vary.parseVary as it will skip invalid values. for (String value : resultHeader.split(",")) { result.add(value.trim()); @@ -184,7 +184,7 @@ public class TestResponseUtil { @Test public void testMimeHeadersAddAllWithNone() { MimeHeaders mh = new MimeHeaders(); - Set<String> expected = new HashSet<String>(); + List<String> expected = new ArrayList<String>(); expected.add("*"); doTestAddVaryFieldName(mh, "*", expected); } @@ -195,19 +195,19 @@ public class TestResponseUtil { MimeHeaders mh = new MimeHeaders(); mh.addValue("vary").setString("foo"); mh.addValue("vary").setString("bar"); - Set<String> expected = new HashSet<String>(); - expected.add("bar"); + List<String> expected = new ArrayList<String>(); expected.add("foo"); + expected.add("bar"); expected.add("too"); doTestAddVaryFieldName(mh, "too", expected); } private void doTestAddVaryFieldName(MimeHeaders mh, String fieldName, - Set<String> expected) { + List<String> expected) { ResponseUtil.addVaryFieldName(mh, fieldName); // There will now only be one Vary header String resultHeader = mh.getHeader("vary"); - Set<String> result = new HashSet<String>(); + List<String> result = new ArrayList<String>(); // Deliberately do not use Vary.parseVary as it will skip invalid values. for (String value : resultHeader.split(",")) { result.add(value.trim()); diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index 18b6eff..688875e 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -127,6 +127,10 @@ the return value of <code>ServletRequest.getRemoteAddr()</code> rather than always returning a value for the proxy. (markt) </fix> + <fix> + Ensure that values are not duplicated when manipulating the vary header. + Based on a pull request by Fredrik Fall. (markt) + </fix> </changelog> </subsection> <subsection name="WebSocket"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org