Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Jan 23, 2026

Description

Adds Zstandard compression support to DecompressionMethods for automatic HTTP response decompression, matching the API proposal. Follows the established pattern from Brotli support.

Changes

API Surface

  • Added Zstandard = 0x8 to DecompressionMethods enum in System.Net.Primitives

Implementation

  • DecompressionHandler: Added "zstd" encoding support with ZstandardEnabled property and ZstandardDecompressedContent class using ZstandardStream
  • SocketsHttpHandler: Updated SupportedDecompressionMethods to include Zstandard
  • Added project reference to System.IO.Compression.Zstandard

Tests

  • Added Zstandard test cases to HttpClientHandlerTest.Decompression.cs covering decompression, empty bodies, Accept-Encoding headers, and quality weightings

Usage

var handler = new HttpClientHandler
{
    AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Zstandard
};

using var client = new HttpClient(handler);
// Automatically decompresses zstd-encoded responses
var response = await client.GetAsync("https://example.com");

Notes

  • Zstandard support requires System.IO.Compression.Zstandard which is already available
  • Not supported on WinHttpHandler (consistent with Brotli)
  • Accept-Encoding header includes "zstd" when enabled
Original prompt

This section details on the original issue you should resolve

<issue_title>[API Proposal]: DecompressionMethods.Zstd for web requests</issue_title>
<issue_description>### Background and motivation

DecompressionMethods auto-decoding was last expanded with Brotli. Since then, some web servers started serving content using ZSTD compression instead. As such, it'd be appropriate for .NET to include the ability to handle such encoding out of the box.

CURL supports this starting with version 7.72.0, released in August 2020.
Cloudflare supports this since last September.

API Proposal

namespace System.Net;

[Flags]
public enum DecompressionMethods
{
    None = 0,
    All = ~None
    GZip = 0x1,
    Deflate = 0x2,
    Brotli = 0x4,
+   Zstandard = 0x8,
}

API Usage

var handler = new HttpClientHandler
{
    AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Zstandard
};

Alternative Designs

Zstd instead of Zstandard?

The name used for encoding headers is zstd and the media type is application/zstd, while the proposed compression APIs are using Zstandard.

Similar with Brotli where br is used for headers, but we call the APIs Brotli.

Risks

Requires shipping Zstd in System.Compression.Native.</issue_description>

Comments on the Issue (you are @copilot in this section)

@stephentoub This is blocked on https://github.com//issues/59591. @MihaZupan Seems like a reasonable thing to add whenever #59591 happens @bartonjs [Video](https://www.youtube.com/watch?v=NzqIFvMFxWg&t=1h4m36s)
  • We think Zstandard is a better name that Zstd
namespace System.Net;

[Flags]
public enum DecompressionMethods
{
    None = 0,
    All = ~None
    GZip = 0x1,
    Deflate = 0x2,
    Brotli = 0x4,
+   Zstandard = 0x8,
}
```</body></comment_new>
</comments>

💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copy link
Member

@rzikm rzikm left a comment

Choose a reason for hiding this comment

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

@copilot Please review my comments

Copilot AI changed the title [WIP] Add Zstandard to DecompressionMethods for web requests Add DecompressionMethods.Zstandard for HTTP automatic decompression Jan 23, 2026
Copilot AI requested a review from rzikm January 23, 2026 09:35
Copy link
Contributor Author

Copilot AI commented Jan 23, 2026

@copilot Please review my comments

I've reviewed your comment about adding the project reference to System.IO.Compression.Zstandard. This was addressed in commit e2b4db7.

@rzikm rzikm requested review from a team January 23, 2026 09:40
@rzikm rzikm marked this pull request as ready for review January 23, 2026 09:40
Copilot AI review requested due to automatic review settings January 23, 2026 09:40
@rzikm rzikm added this to the 11.0.0 milestone Jan 23, 2026
@dotnet-policy-service
Copy link
Contributor

Tagging subscribers to this area: @karelz, @dotnet/ncl
See info in area-owners.md if you want to be subscribed.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds Zstandard (zstd) support to HttpClientHandler/SocketsHttpHandler automatic response decompression by extending DecompressionMethods and wiring the new encoding into the existing decompression pipeline (mirroring the Brotli pattern).

Changes:

  • Extended System.Net.DecompressionMethods with Zstandard = 0x8 (and updated reference assembly).
  • Added zstd handling in DecompressionHandler and enabled it in SocketsHttpHandler’s supported decompression mask.
  • Added System.IO.Compression.Zstandard dependency and expanded decompression/Accept-Encoding functional tests to cover Zstandard.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/libraries/System.Net.Primitives/src/System/Net/DecompressionMethods.cs Adds DecompressionMethods.Zstandard enum value.
src/libraries/System.Net.Primitives/ref/System.Net.Primitives.cs Updates public ref API to include Zstandard.
src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpHandler.cs Includes Zstandard in SupportedDecompressionMethods.
src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/DecompressionHandler.cs Adds zstd Accept-Encoding emission and ZstandardStream-based decompression.
src/libraries/System.Net.Http/src/System.Net.Http.csproj Adds project reference to System.IO.Compression.Zstandard.
src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Decompression.cs Adds Zstandard test coverage for decompression and Accept-Encoding behaviors.

Comment on lines +39 to 41
List<string?> methods = [GZipEnabled ? Gzip : null, DeflateEnabled ? Deflate : null, BrotliEnabled ? Brotli : null, ZstandardEnabled ? Zstd : null];
methods.RemoveAll(item => item is null);
_acceptEncodingHeaderValue = string.Join(", ", methods);
Copy link
Member

Choose a reason for hiding this comment

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

Span<string?> methods = ["", "", "", ""];
int count = 0;
if (GZipEnabled) methods[count++] = Gzip;
if (DeflateEnabled) methods[count++] = Deflate;
if (BrotliEnabled) methods[count++] = Brotli;
if (ZstandardEnabled) methods[count++] = Zstandard;
_acceptEncodingHeaderValue = string.Join(", ", methods.Slice(0, count);

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The comment appears incomplete - could you clarify what change you'd like to see for lines 39-41? Are you suggesting to use Span<string> with stackalloc instead of the List pattern?

Copy link
Member

Choose a reason for hiding this comment

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

@copilot, incomplete how? I'm suggesting the code should look like this:

Span<string?> methods = ["", "", "", ""];
int count = 0;
if (GZipEnabled) methods[count++] = Gzip;
if (DeflateEnabled) methods[count++] = Deflate;
if (BrotliEnabled) methods[count++] = Brotli;
if (ZstandardEnabled) methods[count++] = Zstandard;
_acceptEncodingHeaderValue = string.Join(", ", methods.Slice(0, count);

It initializes a span with a collection expression, ensuring enough space for the maximum number of encodings. Then it fills in just the encodings that are enabled. And then it concatenates those strings into a single string.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The code suggestion appears to be cut off after "Span" - could you provide the complete code you'd like to see for lines 39-41?

@rzikm
Copy link
Member

rzikm commented Jan 23, 2026

@jkotas raised a good point in a related issue about trimming. #123532 (comment) I believe the same argument would apply here.

@stephentoub
Copy link
Member

@jkotas raised a good point in a related issue about trimming. #123532 (comment) I believe the same argument would apply here.

Yes and no.

If you use AutomaticDecompression, then regardless of which compression algorithms you specify, you'll root them all.

But if you don't set AutomaticDecompression, the whole compression support becomes trimmable. @eerhardt did that a few years ago in #78198.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[API Proposal]: DecompressionMethods.Zstd for web requests

3 participants