diff options
author | Elliott Hughes <enh@google.com> | 2010-02-17 15:51:36 -0800 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2010-02-17 15:51:36 -0800 |
commit | 1d1f9244611a8ba3be65795d4ea6e84bcecdb89d (patch) | |
tree | 3ec0a17e2fcc0858b3acf4da493f1b1a8553112b | |
parent | 3129a6e024c3abc19ccfe5b784cb7d7c6509d638 (diff) | |
parent | e3f55fef357e71daa6d56e838fbba31dcebe443e (diff) | |
download | libcore-1d1f9244611a8ba3be65795d4ea6e84bcecdb89d.zip libcore-1d1f9244611a8ba3be65795d4ea6e84bcecdb89d.tar.gz libcore-1d1f9244611a8ba3be65795d4ea6e84bcecdb89d.tar.bz2 |
Merge "HTTP headers should be case-insensitive but case-preserving." into dalvik-dev
-rw-r--r-- | luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/Header.java | 34 | ||||
-rw-r--r-- | luni/src/test/java/org/apache/harmony/luni/internal/net/www/protocol/http/HeaderTest.java | 41 |
2 files changed, 53 insertions, 22 deletions
diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/Header.java b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/Header.java index bdd1d0a..0f8dfa9 100644 --- a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/Header.java +++ b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/Header.java @@ -19,24 +19,23 @@ package org.apache.harmony.luni.internal.net.www.protocol.http; import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.TreeMap; /** * The general structure for request / response header. It is essentially * constructed by hashtable with key indexed in a vector for position lookup. */ public class Header implements Cloneable { - /* - * we use the non-synchronized ArrayList and HashMap instead of the - * synchronized Vector and Hashtable - */ private ArrayList<String> props; - private HashMap<String, LinkedList<String>> keyTable; + // BEGIN android-changed: header fields should be case-insensitive but case-preserving. + // http://code.google.com/p/android/issues/detail?id=6684 + private TreeMap<String, LinkedList<String>> keyTable; + // END android-changed private String statusLine; @@ -48,7 +47,7 @@ public class Header implements Cloneable { public Header() { super(); this.props = new ArrayList<String>(20); - this.keyTable = new HashMap<String, LinkedList<String>>(20); + this.keyTable = new TreeMap<String, LinkedList<String>>(String.CASE_INSENSITIVE_ORDER); // android-changed } /** @@ -79,11 +78,9 @@ public class Header implements Cloneable { try { Header clone = (Header) super.clone(); clone.props = (ArrayList<String>) props.clone(); - clone.keyTable = new HashMap<String, LinkedList<String>>(20); - for (Map.Entry<String, LinkedList<String>> next : this.keyTable - .entrySet()) { - LinkedList<String> v = (LinkedList<String>) next.getValue() - .clone(); + clone.keyTable = new TreeMap<String, LinkedList<String>>(String.CASE_INSENSITIVE_ORDER); // android-changed + for (Map.Entry<String, LinkedList<String>> next : this.keyTable.entrySet()) { + LinkedList<String> v = (LinkedList<String>) next.getValue().clone(); clone.keyTable.put(next.getKey(), v); } return clone; @@ -102,14 +99,11 @@ public class Header implements Cloneable { if (key == null) { throw new NullPointerException(); } - // BEGIN android-changed - key = key.toLowerCase(); LinkedList<String> list = keyTable.get(key); if (list == null) { list = new LinkedList<String>(); - keyTable.put(key, list); + keyTable.put(key, list); // android-changed } - // END android-changed list.add(value); props.add(key); props.add(value); @@ -126,9 +120,6 @@ public class Header implements Cloneable { if (key == null) { throw new NullPointerException(); } - // BEGIN android-added - key = key.toLowerCase(); - // END android-added LinkedList<String> list = keyTable.get(key); if (list == null) { add(key, value); @@ -154,8 +145,7 @@ public class Header implements Cloneable { * @since 1.4 */ public Map<String, List<String>> getFieldMap() { - Map<String, List<String>> result = new HashMap<String, List<String>>( - keyTable.size()); + Map<String, List<String>> result = new TreeMap<String, List<String>>(String.CASE_INSENSITIVE_ORDER); // android-changed for (Map.Entry<String, LinkedList<String>> next : keyTable.entrySet()) { List<String> v = next.getValue(); result.put(next.getKey(), Collections.unmodifiableList(v)); @@ -203,7 +193,7 @@ public class Header implements Cloneable { * such key exists. */ public String get(String key) { - LinkedList<String> result = keyTable.get(key.toLowerCase()); + LinkedList<String> result = keyTable.get(key); // android-changed if (result == null) { return null; } diff --git a/luni/src/test/java/org/apache/harmony/luni/internal/net/www/protocol/http/HeaderTest.java b/luni/src/test/java/org/apache/harmony/luni/internal/net/www/protocol/http/HeaderTest.java new file mode 100644 index 0000000..7ec5fd8 --- /dev/null +++ b/luni/src/test/java/org/apache/harmony/luni/internal/net/www/protocol/http/HeaderTest.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed 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.harmony.luni.internal.net.www.protocol.http; + +import java.util.Arrays; +import junit.framework.Test; +import junit.framework.TestSuite; + +public class HeaderTest extends junit.framework.TestCase { + // http://code.google.com/p/android/issues/detail?id=6684 + public void test_caseInsensitiveButCasePreserving() { + Header h = new Header(); + h.add("Content-Type", "text/plain"); + // Case-insensitive: + assertEquals("text/plain", h.get("Content-Type")); + assertEquals("text/plain", h.get("Content-type")); + assertEquals("text/plain", h.get("content-type")); + assertEquals("text/plain", h.get("CONTENT-TYPE")); + // ...but case-preserving: + assertEquals("Content-Type", h.getFieldMap().keySet().toArray()[0]); + + // We differ from the RI in that the Map we return is also case-insensitive. + // Our behavior seems more consistent. (And code that works on the RI will work on Android.) + assertEquals(Arrays.asList("text/plain"), h.getFieldMap().get("Content-Type")); + assertEquals(Arrays.asList("text/plain"), h.getFieldMap().get("Content-type")); // RI fails this. + } +} |