Author: markt
Date: Fri Aug 15 07:34:43 2014
New Revision: 1618112
URL: http://svn.apache.org/r1618112
Log:
Need to put all locales in order before adding them to the locales collection -
not just those from the first header.
Modified:
tomcat/trunk/java/org/apache/catalina/connector/Request.java
tomcat/trunk/test/org/apache/catalina/connector/TestRequest.java
tomcat/trunk/test/org/apache/catalina/connector/TesterRequest.java
tomcat/trunk/webapps/docs/changelog.xml
Modified: tomcat/trunk/java/org/apache/catalina/connector/Request.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/Request.java?rev=1618112&r1=1618111&r2=1618112&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/connector/Request.java (original)
+++ tomcat/trunk/java/org/apache/catalina/connector/Request.java Fri Aug 15
07:34:43 2014
@@ -3086,26 +3086,33 @@ public class Request
localesParsed = true;
+ // Store the accumulated languages that have been requested in
+ // a local collection, sorted by the quality value (so we can
+ // add Locales in descending order). The values will be ArrayLists
+ // containing the corresponding Locales to be added
+ TreeMap<Double, ArrayList<Locale>> locales = new TreeMap<>();
+
Enumeration<String> values = getHeaders("accept-language");
while (values.hasMoreElements()) {
String value = values.nextElement();
- parseLocalesHeader(value);
+ parseLocalesHeader(value, locales);
}
+ // Process the quality values in highest->lowest order (due to
+ // negating the Double value when creating the key)
+ for (ArrayList<Locale> list : locales.values()) {
+ for (Locale locale : list) {
+ addLocale(locale);
+ }
+ }
}
/**
* Parse accept-language header value.
*/
- protected void parseLocalesHeader(String value) {
-
- // Store the accumulated languages that have been requested in
- // a local collection, sorted by the quality value (so we can
- // add Locales in descending order). The values will be ArrayLists
- // containing the corresponding Locales to be added
- TreeMap<Double, ArrayList<Locale>> locales = new TreeMap<>();
+ protected void parseLocalesHeader(String value, TreeMap<Double,
ArrayList<Locale>> locales) {
// Preprocess the value to remove all whitespace
int white = value.indexOf(' ');
@@ -3200,17 +3207,7 @@ public class Request
locales.put(key, values);
}
values.add(locale);
-
- }
-
- // Process the quality values in highest->lowest order (due to
- // negating the Double value when creating the key)
- for (ArrayList<Locale> list : locales.values()) {
- for (Locale locale : list) {
- addLocale(locale);
- }
}
-
}
Modified: tomcat/trunk/test/org/apache/catalina/connector/TestRequest.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/catalina/connector/TestRequest.java?rev=1618112&r1=1618111&r2=1618112&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/catalina/connector/TestRequest.java (original)
+++ tomcat/trunk/test/org/apache/catalina/connector/TestRequest.java Fri Aug 15
07:34:43 2014
@@ -27,6 +27,7 @@ import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
+import java.util.Locale;
import java.util.TreeMap;
import javax.servlet.ServletException;
@@ -39,8 +40,8 @@ import static org.junit.Assert.assertNot
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import org.junit.Assert;
import org.junit.Test;
-
import org.apache.catalina.Context;
import org.apache.catalina.authenticator.BasicAuthenticator;
import org.apache.catalina.filters.FailedRequestFilter;
@@ -795,4 +796,35 @@ public class TestRequest extends TomcatB
resp.getWriter().print(req.getContextPath());
}
}
+
+ @Test
+ public void getLocaleMultipleHeaders01() throws Exception {
+ TesterRequest req = new TesterRequest();
+
+ req.addHeader("accept-language", "en;q=0.5");
+ req.addHeader("accept-language", "en-gb");
+
+ Locale actual = req.getLocale();
+ Locale expected = Locale.forLanguageTag("en-gb");
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ /*
+ * Reverse header order of getLocaleMultipleHeaders01() and make sure the
+ * result is the same.
+ */
+ @Test
+ public void getLocaleMultipleHeaders02() throws Exception {
+ TesterRequest req = new TesterRequest();
+
+ req.addHeader("accept-language", "en-gb");
+ req.addHeader("accept-language", "en;q=0.5");
+
+ Locale actual = req.getLocale();
+ Locale expected = Locale.forLanguageTag("en-gb");
+
+ Assert.assertEquals(expected, actual);
+ }
+
}
Modified: tomcat/trunk/test/org/apache/catalina/connector/TesterRequest.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/catalina/connector/TesterRequest.java?rev=1618112&r1=1618111&r2=1618112&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/catalina/connector/TesterRequest.java
(original)
+++ tomcat/trunk/test/org/apache/catalina/connector/TesterRequest.java Fri Aug
15 07:34:43 2014
@@ -16,6 +16,13 @@
*/
package org.apache.catalina.connector;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
public class TesterRequest extends Request {
@Override
public String getScheme() {
@@ -45,4 +52,31 @@ public class TesterRequest extends Reque
public String getMethod() {
return method;
}
+
+ private final Map<String,List<String>> headers = new HashMap<>();
+ protected void addHeader(String name, String value) {
+ List<String> values = headers.get(name);
+ if (values == null) {
+ values = new ArrayList<>();
+ headers.put(name, values);
+ }
+ values.add(value);
+ }
+ @Override
+ public String getHeader(String name) {
+ List<String> values = headers.get(name);
+ if (values == null || values.size() == 0) {
+ return null;
+ }
+ return values.get(0);
+ }
+ @Override
+ public Enumeration<String> getHeaders(String name) {
+ return Collections.enumeration(headers.get(name));
+ }
+
+ @Override
+ public Enumeration<String> getHeaderNames() {
+ return Collections.enumeration(headers.keySet());
+ }
}
Modified: tomcat/trunk/webapps/docs/changelog.xml
URL:
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1618112&r1=1618111&r2=1618112&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/trunk/webapps/docs/changelog.xml Fri Aug 15 07:34:43 2014
@@ -136,6 +136,11 @@
<bug>56840</bug>: Avoid NPE when the rewrite valve is mapped to
a context. (remm)
</fix>
+ <fix>
+ Correctly handle multiple <code>accept-language</code> headers rather
+ than just using the first header to determine the user's preferred
+ Locale. (markt)
+ </fix>
</changelog>
</subsection>
<subsection name="Coyote">
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]