PageRenderTime 36ms CodeModel.GetById 10ms RepoModel.GetById 1ms app.codeStats 0ms

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