< Summary

Information
Class: System.Net.Http.ZstandardCompressedContent
Assembly: System.Net.Http
File(s): D:\runner\runtime\src\libraries\System.Net.Http\src\System\Net\Http\ZstandardCompressedContent.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 45
Coverable lines: 45
Total lines: 121
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 6
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.cctor()100%110%
.ctor(...)0%220%
.ctor(...)100%110%
SerializeToStream(...)100%110%
SerializeToStreamAsync(...)100%110%
SerializeToStreamAsync(...)100%110%
TryComputeLength(...)100%110%
Dispose(...)0%220%
CreateCompressionStream(...)0%220%

File(s)

D:\runner\runtime\src\libraries\System.Net.Http\src\System\Net\Http\ZstandardCompressedContent.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using System.IO;
 5using System.IO.Compression;
 6using System.Runtime.Versioning;
 7using System.Threading;
 8using System.Threading.Tasks;
 9
 10namespace System.Net.Http
 11{
 12    /// <summary>
 13    /// Provides HTTP content that compresses the inner content using the Zstandard content coding.
 14    /// </summary>
 15    [UnsupportedOSPlatform("browser")]
 16    public sealed class ZstandardCompressedContent : HttpContent
 17    {
 18        private const string Encoding = "zstd";
 19
 20        // RFC 9659 requires zstd decoders for the "zstd" content coding to support a window size of at
 21        // least 8 MB (2^23) and recommends that encoders not produce frames requiring a larger window.
 22        // Some compression levels (notably CompressionLevel.SmallestSize) would otherwise select a larger
 23        // window, producing payloads that a conformant server would reject. See RFC 9659, Section 3.
 24        private const int RfcMaxWindowLog2 = 23;
 025        private static readonly ZstandardCompressionOptions s_smallestSizeRfcOptions = new ZstandardCompressionOptions
 026        {
 027            Quality = ZstandardCompressionOptions.MaxQuality,
 028            WindowLog2 = RfcMaxWindowLog2
 029        };
 30
 31        private readonly HttpContent _content;
 32        private readonly ZstandardCompressionOptions? _compressionOptions;
 33        private readonly CompressionLevel _compressionLevel;
 34
 35        /// <summary>
 36        /// Initializes a new instance of the <see cref="ZstandardCompressedContent"/> class that compresses the
 37        /// provided content using the Zstandard content coding at the specified compression level.
 38        /// </summary>
 39        /// <param name="content">The HTTP content to compress.</param>
 40        /// <param name="compressionLevel">One of the enumeration values that indicates whether to emphasize speed or co
 41        /// <remarks>
 42        /// RFC 9659 requires that the "zstd" content coding be decodable with a window size of 8 MB (2^23) and
 43        /// recommends that encoders not produce frames requiring a larger window. When setting <paramref name="compress
 44        /// to <see cref="CompressionLevel.SmallestSize"/>, this class applies RFC-compliant options to limit the window
 45        /// so that the produced content is accepted by servers that enforce this limit.
 46        /// </remarks>
 047        public ZstandardCompressedContent(HttpContent content, CompressionLevel compressionLevel = CompressionLevel.Opti
 048        {
 049            ArgumentNullException.ThrowIfNull(content);
 050            CompressedContentCore.ValidateCompressionLevel(compressionLevel, nameof(compressionLevel));
 51
 052            if (compressionLevel == CompressionLevel.SmallestSize)
 053            {
 54                // use RFC-compliant options for SmallestSize to avoid producing frames that a conformant server would r
 055                _compressionOptions = s_smallestSizeRfcOptions;
 056            }
 57            else
 058            {
 059                _compressionLevel = compressionLevel;
 060            }
 61
 062            _content = content;
 063            CompressedContentCore.InitializeHeaders(this, content, Encoding);
 064        }
 65
 66        /// <summary>
 67        /// Initializes a new instance of the <see cref="ZstandardCompressedContent"/> class that compresses the
 68        /// provided content using the Zstandard content coding and the specified compression options.
 69        /// </summary>
 70        /// <param name="content">The HTTP content to compress.</param>
 71        /// <param name="compressionOptions">The options used to fine-tune the compression.</param>
 72        /// <remarks>
 73        /// RFC 9659 requires that the "zstd" content coding be decodable with a window size of 8 MB (2^23) and
 74        /// recommends that encoders not produce frames requiring a larger window. When supplying custom options,
 75        /// consider limiting <see cref="ZstandardCompressionOptions.WindowLog2"/> to 23 or less so that the
 76        /// produced content is accepted by servers that enforce this limit.
 77        /// </remarks>
 078        public ZstandardCompressedContent(HttpContent content, ZstandardCompressionOptions compressionOptions)
 079        {
 080            ArgumentNullException.ThrowIfNull(content);
 081            ArgumentNullException.ThrowIfNull(compressionOptions);
 82
 083            _compressionOptions = compressionOptions;
 084            _content = content;
 085            CompressedContentCore.InitializeHeaders(this, content, Encoding);
 086        }
 87
 88        protected override void SerializeToStream(Stream stream, TransportContext? context, CancellationToken cancellati
 089            CompressedContentCore.SerializeToStream(_content, CreateCompressionStream(stream), context, cancellationToke
 90
 91        protected override Task SerializeToStreamAsync(Stream stream, TransportContext? context) =>
 092            CompressedContentCore.SerializeToStreamAsync(_content, CreateCompressionStream(stream), context, Cancellatio
 93
 94        protected override Task SerializeToStreamAsync(Stream stream, TransportContext? context, CancellationToken cance
 095            CompressedContentCore.SerializeToStreamAsync(_content, CreateCompressionStream(stream), context, cancellatio
 96
 97        protected internal override bool TryComputeLength(out long length)
 098        {
 99            // Compressed size is not known without actually compressing.
 0100            length = 0;
 0101            return false;
 0102        }
 103
 0104        internal override bool AllowDuplex => false;
 105
 106        protected override void Dispose(bool disposing)
 0107        {
 0108            if (disposing)
 0109            {
 0110                _content.Dispose();
 0111            }
 112
 0113            base.Dispose(disposing);
 0114        }
 115
 116        private ZstandardStream CreateCompressionStream(Stream outputStream) =>
 0117            _compressionOptions is null
 0118                ? new ZstandardStream(outputStream, _compressionLevel, leaveOpen: true)
 0119                : new ZstandardStream(outputStream, _compressionOptions, leaveOpen: true);
 120    }
 121}