< Summary

Information
Class: System.Net.Http.Headers.HttpRequestHeaders
Assembly: System.Net.Http
File(s): D:\runner\runtime\src\libraries\System.Net.Http\src\System\Net\Http\Headers\HttpRequestHeaders.cs
Line coverage
2%
Covered lines: 3
Uncovered lines: 114
Coverable lines: 117
Total lines: 294
Line coverage: 2.5%
Branch coverage
0%
Covered branches: 0
Total branches: 32
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
GetSpecializedCollection(...)0%440%
.ctor()100%11100%
AddHeaders(...)0%440%

File(s)

D:\runner\runtime\src\libraries\System.Net.Http\src\System\Net\Http\Headers\HttpRequestHeaders.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.Diagnostics;
 5
 6namespace System.Net.Http.Headers
 7{
 8    public sealed class HttpRequestHeaders : HttpHeaders
 9    {
 10        private const int AcceptSlot = 0;
 11        private const int AcceptCharsetSlot = 1;
 12        private const int AcceptEncodingSlot = 2;
 13        private const int AcceptLanguageSlot = 3;
 14        private const int IfMatchSlot = 4;
 15        private const int IfNoneMatchSlot = 5;
 16        private const int TransferEncodingSlot = 6;
 17        private const int UserAgentSlot = 7;
 18        private const int ExpectSlot = 8;
 19        private const int ProtocolSlot = 9;
 20        private const int NumCollectionsSlots = 10;
 21
 22        private object?[]? _specialCollectionsSlots;
 23        private HttpGeneralHeaders? _generalHeaders;
 24        private bool _expectContinueSet;
 25
 26        #region Request Headers
 27
 28        private T GetSpecializedCollection<T>(int slot, Func<HttpRequestHeaders, T> creationFunc)
 029        {
 30            // 8 properties each lazily allocate a collection to store the value(s) for that property.
 31            // Rather than having a field for each of these, store them untyped in an array that's lazily
 32            // allocated.  Then we only pay for the 64 bytes for those fields when any is actually accessed.
 033            _specialCollectionsSlots ??= new object[NumCollectionsSlots];
 034            return (T)(_specialCollectionsSlots[slot] ??= creationFunc(this)!);
 035        }
 36
 37        public HttpHeaderValueCollection<MediaTypeWithQualityHeaderValue> Accept =>
 038            GetSpecializedCollection(AcceptSlot, static thisRef => new HttpHeaderValueCollection<MediaTypeWithQualityHea
 39
 40        public HttpHeaderValueCollection<StringWithQualityHeaderValue> AcceptCharset =>
 041            GetSpecializedCollection(AcceptCharsetSlot, static thisRef => new HttpHeaderValueCollection<StringWithQualit
 42
 43        public HttpHeaderValueCollection<StringWithQualityHeaderValue> AcceptEncoding =>
 044            GetSpecializedCollection(AcceptEncodingSlot, static thisRef => new HttpHeaderValueCollection<StringWithQuali
 45
 46        public HttpHeaderValueCollection<StringWithQualityHeaderValue> AcceptLanguage =>
 047            GetSpecializedCollection(AcceptLanguageSlot, static thisRef => new HttpHeaderValueCollection<StringWithQuali
 48
 49        public AuthenticationHeaderValue? Authorization
 50        {
 051            get { return (AuthenticationHeaderValue?)GetSingleParsedValue(KnownHeaders.Authorization.Descriptor); }
 052            set { SetOrRemoveParsedValue(KnownHeaders.Authorization.Descriptor, value); }
 53        }
 54
 55        public bool? ExpectContinue
 56        {
 57            get
 058            {
 059                if (ContainsParsedValue(KnownHeaders.Expect.Descriptor, HeaderUtilities.ExpectContinue))
 060                {
 061                    return true;
 62                }
 063                if (_expectContinueSet)
 064                {
 065                    return false;
 66                }
 67
 068                return null;
 069            }
 70            set
 071            {
 072                if (value == true)
 073                {
 074                    _expectContinueSet = true;
 075                    if (!ContainsParsedValue(KnownHeaders.Expect.Descriptor, HeaderUtilities.ExpectContinue))
 076                    {
 077                        AddParsedValue(KnownHeaders.Expect.Descriptor, HeaderUtilities.ExpectContinue);
 078                    }
 079                }
 80                else
 081                {
 082                    _expectContinueSet = value != null;
 83                    // We intentionally ignore the return value. It's OK if "100-continue" wasn't in the store.
 084                    RemoveParsedValue(KnownHeaders.Expect.Descriptor, HeaderUtilities.ExpectContinue);
 085                }
 086            }
 87        }
 88
 89        public string? From
 90        {
 091            get { return (string?)GetSingleParsedValue(KnownHeaders.From.Descriptor); }
 92            set
 093            {
 94                // Null and empty string are equivalent. In this case it means, remove the From header value (if any).
 095                if (value == string.Empty)
 096                {
 097                    value = null;
 098                }
 99
 0100                CheckContainsNewLineOrNull(value);
 101
 0102                SetOrRemoveParsedValue(KnownHeaders.From.Descriptor, value);
 0103            }
 104        }
 105
 106        public string? Host
 107        {
 0108            get { return (string?)GetSingleParsedValue(KnownHeaders.Host.Descriptor); }
 109            set
 0110            {
 111                // Null and empty string are equivalent. In this case it means, remove the Host header value (if any).
 0112                if (value == string.Empty)
 0113                {
 0114                    value = null;
 0115                }
 116
 0117                if ((value != null) && (HttpRuleParser.GetHostLength(value, 0, false) != value.Length))
 0118                {
 0119                    throw new FormatException(SR.net_http_headers_invalid_host_header);
 120                }
 0121                SetOrRemoveParsedValue(KnownHeaders.Host.Descriptor, value);
 0122            }
 123        }
 124
 125        public HttpHeaderValueCollection<EntityTagHeaderValue> IfMatch =>
 0126            GetSpecializedCollection(IfMatchSlot, static thisRef => new HttpHeaderValueCollection<EntityTagHeaderValue>(
 127
 128        public DateTimeOffset? IfModifiedSince
 129        {
 0130            get { return HeaderUtilities.GetDateTimeOffsetValue(KnownHeaders.IfModifiedSince.Descriptor, this); }
 0131            set { SetOrRemoveParsedValue(KnownHeaders.IfModifiedSince.Descriptor, value); }
 132        }
 133
 134        public HttpHeaderValueCollection<EntityTagHeaderValue> IfNoneMatch =>
 0135            GetSpecializedCollection(IfNoneMatchSlot, static thisRef => new HttpHeaderValueCollection<EntityTagHeaderVal
 136
 137        public RangeConditionHeaderValue? IfRange
 138        {
 0139            get { return (RangeConditionHeaderValue?)GetSingleParsedValue(KnownHeaders.IfRange.Descriptor); }
 0140            set { SetOrRemoveParsedValue(KnownHeaders.IfRange.Descriptor, value); }
 141        }
 142
 143        public DateTimeOffset? IfUnmodifiedSince
 144        {
 0145            get { return HeaderUtilities.GetDateTimeOffsetValue(KnownHeaders.IfUnmodifiedSince.Descriptor, this); }
 0146            set { SetOrRemoveParsedValue(KnownHeaders.IfUnmodifiedSince.Descriptor, value); }
 147        }
 148
 149        public int? MaxForwards
 150        {
 151            get
 0152            {
 0153                object? storedValue = GetSingleParsedValue(KnownHeaders.MaxForwards.Descriptor);
 0154                if (storedValue != null)
 0155                {
 0156                    return (int)storedValue;
 157                }
 0158                return null;
 0159            }
 0160            set { SetOrRemoveParsedValue(KnownHeaders.MaxForwards.Descriptor, value); }
 161        }
 162
 163        /// <summary>Gets or sets the value of the <see langword=":protocol" /> pseudo-header for an HTTP request.</summ
 164        /// <value>The value of the <see langword=":protocol" /> pseudo-header for an HTTP request.</value>
 165        public string? Protocol
 166        {
 0167            get => _specialCollectionsSlots is null ? null : (string?)_specialCollectionsSlots[ProtocolSlot];
 168            set
 0169            {
 0170                CheckContainsNewLineOrNull(value);
 0171                _specialCollectionsSlots ??= new object[NumCollectionsSlots];
 0172                _specialCollectionsSlots[ProtocolSlot] = value;
 0173            }
 174        }
 175
 176        public AuthenticationHeaderValue? ProxyAuthorization
 177        {
 0178            get { return (AuthenticationHeaderValue?)GetSingleParsedValue(KnownHeaders.ProxyAuthorization.Descriptor); }
 0179            set { SetOrRemoveParsedValue(KnownHeaders.ProxyAuthorization.Descriptor, value); }
 180        }
 181
 182        public RangeHeaderValue? Range
 183        {
 0184            get { return (RangeHeaderValue?)GetSingleParsedValue(KnownHeaders.Range.Descriptor); }
 0185            set { SetOrRemoveParsedValue(KnownHeaders.Range.Descriptor, value); }
 186        }
 187
 188        public Uri? Referrer
 189        {
 0190            get { return (Uri?)GetSingleParsedValue(KnownHeaders.Referer.Descriptor); }
 0191            set { SetOrRemoveParsedValue(KnownHeaders.Referer.Descriptor, value); }
 192        }
 193
 194        public HttpHeaderValueCollection<TransferCodingWithQualityHeaderValue> TE =>
 0195            GetSpecializedCollection(TransferEncodingSlot, static thisRef => new HttpHeaderValueCollection<TransferCodin
 196
 197        public HttpHeaderValueCollection<ProductInfoHeaderValue> UserAgent =>
 0198            GetSpecializedCollection(UserAgentSlot, static thisRef => new HttpHeaderValueCollection<ProductInfoHeaderVal
 199
 200        public HttpHeaderValueCollection<NameValueWithParametersHeaderValue> Expect =>
 0201            GetSpecializedCollection(ExpectSlot, static thisRef => new HttpHeaderValueCollection<NameValueWithParameters
 202
 203        #endregion
 204
 205        #region General Headers
 206
 207        public CacheControlHeaderValue? CacheControl
 208        {
 0209            get { return GeneralHeaders.CacheControl; }
 0210            set { GeneralHeaders.CacheControl = value; }
 211        }
 212
 213        public HttpHeaderValueCollection<string> Connection
 214        {
 0215            get { return GeneralHeaders.Connection; }
 216        }
 217
 218        public bool? ConnectionClose
 219        {
 0220            get { return HttpGeneralHeaders.GetConnectionClose(this, _generalHeaders); } // special-cased to avoid forci
 0221            set { GeneralHeaders.ConnectionClose = value; }
 222        }
 223
 224        public DateTimeOffset? Date
 225        {
 0226            get { return GeneralHeaders.Date; }
 0227            set { GeneralHeaders.Date = value; }
 228        }
 229
 230        public HttpHeaderValueCollection<NameValueHeaderValue> Pragma
 231        {
 0232            get { return GeneralHeaders.Pragma; }
 233        }
 234
 235        public HttpHeaderValueCollection<string> Trailer
 236        {
 0237            get { return GeneralHeaders.Trailer; }
 238        }
 239
 240        public HttpHeaderValueCollection<TransferCodingHeaderValue> TransferEncoding
 241        {
 0242            get { return GeneralHeaders.TransferEncoding; }
 243        }
 244
 245        public bool? TransferEncodingChunked
 246        {
 0247            get { return HttpGeneralHeaders.GetTransferEncodingChunked(this, _generalHeaders); } // special-cased to avo
 0248            set { GeneralHeaders.TransferEncodingChunked = value; }
 249        }
 250
 251        public HttpHeaderValueCollection<ProductHeaderValue> Upgrade
 252        {
 0253            get { return GeneralHeaders.Upgrade; }
 254        }
 255
 256        public HttpHeaderValueCollection<ViaHeaderValue> Via
 257        {
 0258            get { return GeneralHeaders.Via; }
 259        }
 260
 261        public HttpHeaderValueCollection<WarningHeaderValue> Warning
 262        {
 0263            get { return GeneralHeaders.Warning; }
 264        }
 265
 266        #endregion
 267
 268        internal HttpRequestHeaders()
 1269            : base(HttpHeaderType.General | HttpHeaderType.Request | HttpHeaderType.Custom, HttpHeaderType.Response)
 1270        {
 1271        }
 272
 273        internal override void AddHeaders(HttpHeaders sourceHeaders)
 0274        {
 0275            base.AddHeaders(sourceHeaders);
 0276            HttpRequestHeaders? sourceRequestHeaders = sourceHeaders as HttpRequestHeaders;
 0277            Debug.Assert(sourceRequestHeaders != null);
 278
 279            // Copy special values but do not overwrite.
 0280            if (sourceRequestHeaders._generalHeaders != null)
 0281            {
 0282                GeneralHeaders.AddSpecialsFrom(sourceRequestHeaders._generalHeaders);
 0283            }
 284
 0285            bool? expectContinue = ExpectContinue;
 0286            if (!expectContinue.HasValue)
 0287            {
 0288                ExpectContinue = sourceRequestHeaders.ExpectContinue;
 0289            }
 0290        }
 291
 0292        private HttpGeneralHeaders GeneralHeaders => _generalHeaders ??= new HttpGeneralHeaders(this);
 293    }
 294}