Skip to content

Add dictionary support to Zstd and Brotli compressor input streams - #821

Open
arturobernalg wants to merge 1 commit into
apache:masterfrom
arturobernalg:compression-dictionaries
Open

arturobernalg wants to merge 1 commit into
apache:masterfrom
arturobernalg:compression-dictionaries

Conversation

@arturobernalg

@arturobernalg arturobernalg commented Oct 7, 2026 •

Copy link
Copy Markdown
Member

Add ZstdCompressorInputStream.Builder.setDict(byte[]) and BrotliCompressorInputStream.Builder.setDict(byte[]) to decompress input compressed with a dictionary, for example Compression Dictionary Transport (RFC 9842) payloads.

Motivation: Compression Dictionary Transport (RFC 9842) support in Apache HttpClient, see apache/httpcomponents-client#881

Thanks for your contribution to Apache Commons! Your help is appreciated!

Before you push a pull request, review this list:

  • [X ] Read the contribution guidelines for this project.
  • [X ] Read the ASF Generative Tooling Guidance if you use Artificial Intelligence (AI).
  • [X ] I used AI to create any part of, or all of, this pull request. Which AI tool was used to create this pull request, and to what extent did it contribute?
  • [X ] Run a successful build using the default Maven goal with mvn; that's mvn on the command line by itself.
  • [ X] Write unit tests that match behavioral changes, where the tests fail if the changes to the runtime are not applied. This may not always be possible, but it is a best practice.
  • [X ] Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
  • [X ] Each commit in the pull request should have a meaningful subject line and body. Note that a maintainer may squash commits during the merge process.

Add ZstdCompressorInputStream.Builder.setDict(byte[]) and
BrotliCompressorInputStream.Builder.setDict(byte[]) to decompress input
compressed with a dictionary, for example Compression Dictionary
Transport (RFC 9842) payloads.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

The Zstandard path-based builder leaks its internally opened input stream because close propagation is disabled.

Review effort: Balanced
Findings: 1 Medium severity

Open (1)
What changed in this PR

Adds dictionary-based decompression support to Brotli and Zstandard input streams.

Changes:

  • Adds builders with setDict(byte[]).
  • Adds dictionary decompression and missing-dictionary tests.
  • Adds fixtures, release notes, and binary resource handling.
File Description
.gitattributes Marks dictionary fixtures as binary.
src/​changes/​changes.xml Documents both new APIs.
BrotliCompressorInputStream.java Adds dictionary-aware builder.
ZstdCompressorInputStream.java Adds dictionary-aware builder.
BrotliCompressorInputStreamTest.java Tests Brotli dictionary decoding.
ZstdCompressorInputStreamTest.java Tests Zstandard dictionary decoding.
brotli.dictionary.dict Provides the test dictionary.
brotli.dictionary.uncompressed Provides expected decompressed data.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@SuppressWarnings("resource") // Caller closes
private ZstdCompressorInputStream(final Builder builder) throws IOException {
this.decIS = new ZstdInputStream(
countingStream = BoundedInputStream.builder().setInputStream(builder.getInputStream()).setPropagateClose(false).get());
@garydgregory

Copy link
Copy Markdown
Member

@arturobernalg
Thank you for the PR. Please review Copilot's comment.

@garydgregory garydgregory left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added 2 questions about the byte array setters.

* @return {@code this} instance.
*/
public Builder setDict(final byte[] dict) {
this.dict = dict;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the builder track a defensive copy?

* @see <a href="https://facebook.github.io/zstd/zstd_manual.html#Chapter14">Zstd manual Chapter14</a>
*/
public Builder setDict(final byte[] dict) {
this.dict = dict;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the builder track a defensive copy?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants