diff --git a/codec-http2/src/main/java/io/netty/handler/codec/http2/HttpConversionUtil.java b/codec-http2/src/main/java/io/netty/handler/codec/http2/HttpConversionUtil.java index 650ce38aaf3e..6841265d88b6 100644 --- a/codec-http2/src/main/java/io/netty/handler/codec/http2/HttpConversionUtil.java +++ b/codec-http2/src/main/java/io/netty/handler/codec/http2/HttpConversionUtil.java @@ -38,7 +38,6 @@ import java.net.URI; import java.util.Iterator; -import java.util.List; import java.util.Map.Entry; import static io.netty.handler.codec.http.HttpScheme.HTTP; @@ -413,14 +412,13 @@ public static Http2Headers toHttp2Headers(HttpHeaders inHeaders, boolean validat return out; } - private static CharSequenceMap toLowercaseMap(List values) { + private static CharSequenceMap toLowercaseMap(Iterator valuesIter, + int arraySizeHint) { UnsupportedValueConverter valueConverter = UnsupportedValueConverter.instance(); - CharSequenceMap result = - new CharSequenceMap(true, valueConverter, values.size()); + CharSequenceMap result = new CharSequenceMap(true, valueConverter, arraySizeHint); - // we iterate because the underlying list is probably a linked list - for (CharSequence value : values) { - AsciiString lowerCased = AsciiString.of(value).toLowerCase(); + while (valuesIter.hasNext()) { + AsciiString lowerCased = AsciiString.of(valuesIter.next()).toLowerCase(); try { int index = lowerCased.forEachByte(FIND_COMMA); if (index != -1) { @@ -429,7 +427,7 @@ private static CharSequenceMap toLowercaseMap(List values) result.add(lowerCased.subSequence(start, index, false).trim(), EMPTY_STRING); start = index + 1; } while (start < lowerCased.length() && - (index = lowerCased.forEachByte(start, value.length() - start, FIND_COMMA)) != -1); + (index = lowerCased.forEachByte(start, lowerCased.length() - start, FIND_COMMA)) != -1); result.add(lowerCased.subSequence(start, lowerCased.length(), false).trim(), EMPTY_STRING); } else { result.add(lowerCased.trim(), EMPTY_STRING); @@ -445,8 +443,10 @@ private static CharSequenceMap toLowercaseMap(List values) public static void toHttp2Headers(HttpHeaders inHeaders, Http2Headers out) { Iterator> iter = inHeaders.iteratorCharSequence(); + // Choose 8 as a default size because it is unlikely we will see more than 4 Connection headers values, but + // still allowing for "enough" space in the map to reduce the chance of hash code collision. CharSequenceMap connectionBlacklist = - toLowercaseMap(inHeaders.getAll(HttpHeaderNames.CONNECTION)); + toLowercaseMap(inHeaders.valueCharSequenceIterator(HttpHeaderNames.CONNECTION), 8); while (iter.hasNext()) { Entry entry = iter.next(); final AsciiString aName = AsciiString.of(entry.getKey()).toLowerCase();