PageRenderTime 39ms CodeModel.GetById 14ms app.highlight 19ms RepoModel.GetById 1ms app.codeStats 1ms

/WCFWebApi/src/System.Net.Http/System/Net/Http/Headers/GenericHeaderParser.cs

#
C# | 176 lines | 140 code | 31 blank | 5 comment | 5 complexity | 8ee5e47d7481be6f6372367b3a510e37 MD5 | raw file
  1using System.Collections;
  2using System.Diagnostics.Contracts;
  3
  4namespace System.Net.Http.Headers
  5{
  6    internal sealed class GenericHeaderParser : BaseHeaderParser
  7    {
  8        private delegate int GetParsedValueLengthDelegate(string value, int startIndex, out object parsedValue);
  9
 10        #region Parser instances
 11
 12        internal static readonly HttpHeaderParser HostParser = new GenericHeaderParser(false, ParseHost,
 13            HeaderUtilities.CaseInsensitiveStringComparer);
 14        internal static readonly HttpHeaderParser TokenListParser = new GenericHeaderParser(true, ParseTokenList,
 15            HeaderUtilities.CaseInsensitiveStringComparer);
 16        internal static readonly HttpHeaderParser SingleValueNameValueWithParametersParser = new GenericHeaderParser(false,
 17            NameValueWithParametersHeaderValue.GetNameValueWithParametersLength);
 18        internal static readonly HttpHeaderParser MultipleValueNameValueWithParametersParser = new GenericHeaderParser(true,
 19            NameValueWithParametersHeaderValue.GetNameValueWithParametersLength);
 20        internal static readonly HttpHeaderParser SingleValueNameValueParser = new GenericHeaderParser(false, ParseNameValue);
 21        internal static readonly HttpHeaderParser MultipleValueNameValueParser = new GenericHeaderParser(true, ParseNameValue);
 22        internal static readonly HttpHeaderParser MailAddressParser = new GenericHeaderParser(false, ParseMailAddress);
 23        internal static readonly HttpHeaderParser SingleValueProductParser = new GenericHeaderParser(false, ParseProduct);
 24        internal static readonly HttpHeaderParser MultipleValueProductParser = new GenericHeaderParser(true, ParseProduct);
 25        internal static readonly HttpHeaderParser RangeConditionParser = new GenericHeaderParser(false, 
 26            RangeConditionHeaderValue.GetRangeConditionLength);
 27        internal static readonly HttpHeaderParser SingleValueAuthenticationParser = new GenericHeaderParser(false, 
 28            AuthenticationHeaderValue.GetAuthenticationLength);
 29        internal static readonly HttpHeaderParser MultipleValueAuthenticationParser = new GenericHeaderParser(true, 
 30            AuthenticationHeaderValue.GetAuthenticationLength);
 31        internal static readonly HttpHeaderParser RangeParser = new GenericHeaderParser(false, 
 32            RangeHeaderValue.GetRangeLength);
 33        internal static readonly HttpHeaderParser RetryConditionParser = new GenericHeaderParser(false,
 34            RetryConditionHeaderValue.GetRetryConditionLength);
 35        internal static readonly HttpHeaderParser ContentRangeParser = new GenericHeaderParser(false, 
 36            ContentRangeHeaderValue.GetContentRangeLength);
 37        internal static readonly HttpHeaderParser ContentDispositionParser = new GenericHeaderParser(false,
 38            ContentDispositionHeaderValue.GetDispositionTypeLength);
 39        internal static readonly HttpHeaderParser SingleValueStringWithQualityParser = new GenericHeaderParser(false,
 40            StringWithQualityHeaderValue.GetStringWithQualityLength);
 41        internal static readonly HttpHeaderParser MultipleValueStringWithQualityParser = new GenericHeaderParser(true, 
 42            StringWithQualityHeaderValue.GetStringWithQualityLength);
 43        internal static readonly HttpHeaderParser SingleValueEntityTagParser = new GenericHeaderParser(false, 
 44            ParseSingleEntityTag);
 45        internal static readonly HttpHeaderParser MultipleValueEntityTagParser = new GenericHeaderParser(true, 
 46            ParseMultipleEntityTags);
 47        internal static readonly HttpHeaderParser SingleValueViaParser = new GenericHeaderParser(false,
 48            ViaHeaderValue.GetViaLength);
 49        internal static readonly HttpHeaderParser MultipleValueViaParser = new GenericHeaderParser(true,
 50            ViaHeaderValue.GetViaLength);
 51        internal static readonly HttpHeaderParser SingleValueWarningParser = new GenericHeaderParser(false,
 52            WarningHeaderValue.GetWarningLength);
 53        internal static readonly HttpHeaderParser MultipleValueWarningParser = new GenericHeaderParser(true,
 54            WarningHeaderValue.GetWarningLength);
 55
 56        #endregion
 57
 58        private GetParsedValueLengthDelegate getParsedValueLength;
 59        private IEqualityComparer comparer;
 60
 61        public override IEqualityComparer Comparer
 62        {
 63            get { return comparer; }
 64        }
 65
 66        private GenericHeaderParser(bool supportsMultipleValues, GetParsedValueLengthDelegate getParsedValueLength)
 67            : this(supportsMultipleValues, getParsedValueLength, null)
 68        {
 69        }
 70
 71        private GenericHeaderParser(bool supportsMultipleValues, GetParsedValueLengthDelegate getParsedValueLength,
 72            IEqualityComparer comparer)
 73            : base(supportsMultipleValues)
 74        {
 75            Contract.Assert(getParsedValueLength != null);
 76
 77            this.getParsedValueLength = getParsedValueLength;
 78            this.comparer = comparer;
 79        }
 80
 81        protected override int GetParsedValueLength(string value, int startIndex, object storeValue,
 82            out object parsedValue)
 83        {
 84            return getParsedValueLength(value, startIndex, out parsedValue);
 85        }
 86
 87        #region Parse methods
 88
 89        private static int ParseNameValue(string value, int startIndex, out object parsedValue)
 90        {
 91            NameValueHeaderValue temp = null;
 92            int resultLength = NameValueHeaderValue.GetNameValueLength(value, startIndex, out temp);
 93
 94            parsedValue = temp;
 95            return resultLength;
 96        }
 97
 98        private static int ParseProduct(string value, int startIndex, out object parsedValue)
 99        {
100            ProductHeaderValue temp = null;
101            int resultLength = ProductHeaderValue.GetProductLength(value, startIndex, out temp);
102
103            parsedValue = temp;
104            return resultLength;
105        }
106
107        private static int ParseSingleEntityTag(string value, int startIndex, out object parsedValue)
108        {
109            EntityTagHeaderValue temp = null;
110            parsedValue = null;
111
112            int resultLength = EntityTagHeaderValue.GetEntityTagLength(value, startIndex, out temp);
113
114            // If we don't allow '*' ("Any") as valid ETag value, return false (e.g. 'ETag' header)
115            if (temp == EntityTagHeaderValue.Any)
116            {
117                return 0;
118            }
119
120            parsedValue = temp;
121            return resultLength;
122        }
123
124        // Note that if multiple ETag values are allowed (e.g. 'If-Match', 'If-None-Match'), according to the RFC
125        // the value must either be '*' or a list of ETag values. It's not allowed to have both '*' and a list of 
126        // ETag values. We're not that strict: We allow both '*' and ETag values in a list. If the server sends such
127        // an invalid list, we want to be able to represent it using the corresponding header property.
128        private static int ParseMultipleEntityTags(string value, int startIndex, out object parsedValue)
129        {
130            EntityTagHeaderValue temp = null;
131            int resultLength = EntityTagHeaderValue.GetEntityTagLength(value, startIndex, out temp);
132
133            parsedValue = temp;
134            return resultLength;
135        }
136
137        private static int ParseMailAddress(string value, int startIndex, out object parsedValue)
138        {
139            parsedValue = null;
140
141            if (HttpRuleParser.ContainsInvalidNewLine(value, startIndex))
142            {
143                return 0;
144            }
145
146            string result = value.Substring(startIndex);
147
148            if (!HeaderUtilities.IsValidEmailAddress(result))
149            {
150                return 0;
151            }
152
153            parsedValue = result;
154            return result.Length;
155        }
156
157        private static int ParseHost(string value, int startIndex, out object parsedValue)
158        {
159            string host = null;
160            int hostLength = HttpRuleParser.GetHostLength(value, startIndex, false, out host);
161
162            parsedValue = host;
163            return hostLength;
164        }
165
166        private static int ParseTokenList(string value, int startIndex, out object parsedValue)
167        {
168            int resultLength = HttpRuleParser.GetTokenLength(value, startIndex);
169
170            parsedValue = value.Substring(startIndex, resultLength);
171            return resultLength;
172        }
173
174        #endregion
175    }
176}