From 94ab0dc4425b05e8691c0954f70c1859d0b7294c Mon Sep 17 00:00:00 2001 From: Moses Nakamura Date: Mon, 18 Dec 2017 20:41:09 -0500 Subject: [PATCH] codec-http2: Better keep track of nameLength in HpackDecoder.decode Motivation: http/2 counts header sizes somewhat inconsistently. Sometimes, headers which are substantively less than the header list size will be measured as longer than the header list size. Modifications: Keep better track of the nameLength of a given name, so that we don't accidentally end up reusing a nameLength. Result: More consistent measurement of header list size. Fixes #7511. --- .../handler/codec/http2/HpackDecoder.java | 3 +++ .../handler/codec/http2/HpackDecoderTest.java | 22 +++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/codec-http2/src/main/java/io/netty/handler/codec/http2/HpackDecoder.java b/codec-http2/src/main/java/io/netty/handler/codec/http2/HpackDecoder.java index ce81f7c498..07b1e30b53 100644 --- a/codec-http2/src/main/java/io/netty/handler/codec/http2/HpackDecoder.java +++ b/codec-http2/src/main/java/io/netty/handler/codec/http2/HpackDecoder.java @@ -162,6 +162,7 @@ final class HpackDecoder { default: // Index was stored as the prefix name = readName(index); + nameLength = name.length(); state = READ_LITERAL_HEADER_VALUE_LENGTH_PREFIX; } } else if ((b & 0x20) == 0x20) { @@ -187,6 +188,7 @@ final class HpackDecoder { default: // Index was stored as the prefix name = readName(index); + nameLength = name.length(); state = READ_LITERAL_HEADER_VALUE_LENGTH_PREFIX; } } @@ -205,6 +207,7 @@ final class HpackDecoder { case READ_INDEXED_HEADER_NAME: // Header Name matches an entry in the Header Table name = readName(decodeULE128(in, index)); + nameLength = name.length(); state = READ_LITERAL_HEADER_VALUE_LENGTH_PREFIX; break; diff --git a/codec-http2/src/test/java/io/netty/handler/codec/http2/HpackDecoderTest.java b/codec-http2/src/test/java/io/netty/handler/codec/http2/HpackDecoderTest.java index 8dd885400c..04552b9263 100644 --- a/codec-http2/src/test/java/io/netty/handler/codec/http2/HpackDecoderTest.java +++ b/codec-http2/src/test/java/io/netty/handler/codec/http2/HpackDecoderTest.java @@ -455,4 +455,26 @@ public class HpackDecoderTest { in.release(); } } + + @Test + public void testDecodeCountsNamesOnlyOnce() throws Http2Exception { + ByteBuf in = Unpooled.buffer(200); + try { + hpackDecoder.setMaxHeaderListSize(3500, 4000); + HpackEncoder hpackEncoder = new HpackEncoder(true); + + // encode headers that are slightly larger than maxHeaderListSize + // but smaller than maxHeaderListSizeGoAway + Http2Headers toEncode = new DefaultHttp2Headers(); + toEncode.add(String.format("%03000d", 0).replace('0', 'f'), "value"); + toEncode.add("accept", "value"); + hpackEncoder.encodeHeaders(1, in, toEncode, NEVER_SENSITIVE); + + Http2Headers decoded = new DefaultHttp2Headers(); + hpackDecoder.decode(1, in, decoded); + assertEquals(2, decoded.size()); + } finally { + in.release(); + } + } }