@Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (msg instanceof HttpRequest req) {
            
            List<String> lengthHeaders = req.headers().getAll(HttpHeaderNames.CONTENT_LENGTH);
            if (lengthHeaders.size() > 1) {
                ctx.writeAndFlush(new DefaultHttp2ResetFrame(Http2Error.PROTOCOL_ERROR));
                ReferenceCountUtil.safeRelease(msg);
                return;
            } else if (lengthHeaders.size() == 1) {
                expectedContentLength = Long.parseLong(lengthHeaders.get(0));
                if (expectedContentLength < 0) {
                    // TODO(carl-mastrangelo): this is not right, but meh.  Fix this to return a proper 400.
                    ctx.writeAndFlush(new DefaultHttp2ResetFrame(Http2Error.PROTOCOL_ERROR));
                    ReferenceCountUtil.safeRelease(msg);
                    return;
                }
            }
            if (hasContentLength() && HttpUtil.isTransferEncodingChunked(req)) {
                // TODO(carl-mastrangelo): this is not right, but meh.  Fix this to return a proper 400.
                ctx.writeAndFlush(new DefaultHttp2ResetFrame(Http2Error.PROTOCOL_ERROR));
                ReferenceCountUtil.safeRelease(msg);
                return;
            }
        }
        if (msg instanceof HttpContent) {
            ByteBuf content = ((HttpContent) msg).content();
            incrementSeenContent(content.readableBytes());
            if (hasContentLength() && seenContentLength > expectedContentLength) {
                // TODO(carl-mastrangelo): this is not right, but meh.  Fix this to return a proper 400.
                ctx.writeAndFlush(new DefaultHttp2ResetFrame(Http2Error.PROTOCOL_ERROR));
                ReferenceCountUtil.safeRelease(msg);
                return;
            }
        }
        if (msg instanceof LastHttpContent) {
            if (hasContentLength() && seenContentLength != expectedContentLength) {
                // TODO(carl-mastrangelo): this is not right, but meh.  Fix this to return a proper 400.
                ctx.writeAndFlush(new DefaultHttp2ResetFrame(Http2Error.PROTOCOL_ERROR));
                ReferenceCountUtil.safeRelease(msg);
                return;
            }
        }
        super.channelRead(ctx, msg);
    }
This checks that the content length does what it says, preventing a client from causing Zuul to misinterpret the
request.  Because this class is meant to work in an HTTP/2 setting, the content length and transfer encoding
checks are more semantics.  In particular, this checks:
<ul>
    <li>No duplicate Content length</li>
    <li>Content Length (if present) must always be greater than or equal to how much content has been seen</li>
    <li>Content Length (if present) must always be equal to how much content has been seen by the end</li>
    <li>Content Length cannot be present along with chunked transfer encoding.</li>
</ul>
zuul-core/src/main/java/com/netflix/zuul/netty/server/http2/Http2ContentLengthEnforcingHandler.java