Home / Class/ Http2Decompressor Class — netty Architecture

Http2Decompressor Class — netty Architecture

Architecture documentation for the Http2Decompressor class in DelegatingDecompressorFrameListener.java from the netty codebase.

Entity Profile

Dependency Diagram

graph TD
  5daed817_25b8_7048_df6a_dfebd688213d["Http2Decompressor"]
  cdec0447_51ad_ffa5_e1e6_2257690237d4["DelegatingDecompressorFrameListener.java"]
  5daed817_25b8_7048_df6a_dfebd688213d -->|defined in| cdec0447_51ad_ffa5_e1e6_2257690237d4
  3b616ed8_35a3_6678_4e2d_df48df41f0f6["Http2Decompressor()"]
  5daed817_25b8_7048_df6a_dfebd688213d -->|method| 3b616ed8_35a3_6678_4e2d_df48df41f0f6
  dd9c50d6_64cc_0a59_6b7f_f701e1e2feae["cleanup()"]
  5daed817_25b8_7048_df6a_dfebd688213d -->|method| dd9c50d6_64cc_0a59_6b7f_f701e1e2feae
  3f8b72ec_5811_f332_169d_95c90074faa4["decompress()"]
  5daed817_25b8_7048_df6a_dfebd688213d -->|method| 3f8b72ec_5811_f332_169d_95c90074faa4
  5b535dcb_154a_329f_7d30_64ed548f02b1["incrementCompressedBytes()"]
  5daed817_25b8_7048_df6a_dfebd688213d -->|method| 5b535dcb_154a_329f_7d30_64ed548f02b1
  9ea1931e_5f39_7536_e536_f68714591f6c["incrementDecompressedBytes()"]
  5daed817_25b8_7048_df6a_dfebd688213d -->|method| 9ea1931e_5f39_7536_e536_f68714591f6c
  aa3cf3aa_c581_458c_7bfd_76d9c933e628["consumeBytes()"]
  5daed817_25b8_7048_df6a_dfebd688213d -->|method| aa3cf3aa_c581_458c_7bfd_76d9c933e628

Relationship Graph

Source Code

codec-http2/src/main/java/io/netty/handler/codec/http2/DelegatingDecompressorFrameListener.java lines 365–493

    private static final class Http2Decompressor {
        private final EmbeddedChannel decompressor;

        private int compressed;
        private int decompressed;
        private Http2Stream stream;
        private int padding;
        private boolean dataDecompressed;
        private ChannelHandlerContext targetCtx;

        Http2Decompressor(EmbeddedChannel decompressor,  Http2Connection connection, Http2FrameListener listener) {
            this.decompressor = decompressor;
            this.decompressor.pipeline().addLast(new ChannelInboundHandlerAdapter() {
                @Override
                public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
                    ByteBuf buf = (ByteBuf) msg;
                    if (!buf.isReadable()) {
                        buf.release();
                        return;
                    }
                    incrementDecompressedBytes(buf.readableBytes());
                    // Immediately return the bytes back to the flow controller. ConsumedBytesConverter will convert
                    // from the decompressed amount which the user knows about to the compressed amount which flow
                    // control knows about.
                    connection.local().flowController().consumeBytes(stream,
                            listener.onDataRead(targetCtx, stream.id(), buf, padding, false));
                    padding = 0; // Padding is only communicated once on the first iteration.
                    buf.release();

                    dataDecompressed = true;
                }

                @Override
                public void channelInactive(ChannelHandlerContext ctx) throws Exception {
                    listener.onDataRead(targetCtx, stream.id(), Unpooled.EMPTY_BUFFER, padding, true);
                }
            });
        }

        /**
         * Release remaining content from the {@link EmbeddedChannel}.
         */
        void cleanup() {
            decompressor.finishAndReleaseAll();
        }

        int decompress(ChannelHandlerContext ctx, Http2Stream stream, ByteBuf data, int padding, boolean endOfStream)
                throws Http2Exception {
            final int compressedBytes = data.readableBytes() + padding;
            incrementCompressedBytes(compressedBytes);
            try {
                this.stream = stream;
                this.padding = padding;
                this.dataDecompressed = false;
                this.targetCtx = ctx;

                // call retain here as it will call release after its written to the channel
                decompressor.writeInbound(data.retain());
                if (endOfStream) {
                    decompressor.finish();

                    if (!dataDecompressed) {
                        // No new decompressed data was extracted from the compressed data. This means the application
                        // could not be provided with data and thus could not return how many bytes were processed.
                        // We will assume there is more data coming which will complete the decompression block.
                        // To allow for more data we return all bytes to the flow control window (so the peer can
                        // send more data).
                        incrementDecompressedBytes(compressedBytes);
                        return compressedBytes;
                    }
                }
                // We consume bytes each time we call the listener to ensure if multiple frames are decompressed
                // that the bytes are accounted for immediately. Otherwise the user may see an inconsistent state of
                // flow control.
                return 0;
            } catch (Throwable t) {
                // Http2Exception might be thrown by writeInbound(...) or finish().
                if (t instanceof Http2Exception) {
                    throw (Http2Exception) t;
                }
                throw streamError(stream.id(), INTERNAL_ERROR, t,

Frequently Asked Questions

What is the Http2Decompressor class?
Http2Decompressor is a class in the netty codebase, defined in codec-http2/src/main/java/io/netty/handler/codec/http2/DelegatingDecompressorFrameListener.java.
Where is Http2Decompressor defined?
Http2Decompressor is defined in codec-http2/src/main/java/io/netty/handler/codec/http2/DelegatingDecompressorFrameListener.java at line 365.

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free