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&apos;s preferred
+        Locale. (markt)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Coyote">



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to