/// <summary> /// Try to find a target header value among the set of given header values and parse it as a /// <see cref="TimeSpan"/>. /// </summary> /// <param name="headerValues"> /// The <see cref="StringValues"/> containing the set of header values to search. /// </param> /// <param name="targetValue"> /// The target header value to look for. /// </param> /// <param name="value"> /// When this method returns, contains the parsed <see cref="TimeSpan"/>, if the parsing succeeded, or /// null if the parsing failed. The conversion fails if the <paramref name="targetValue"/> was not /// found or could not be parsed as a <see cref="TimeSpan"/>. This parameter is passed uninitialized; /// any value originally supplied in result will be overwritten. /// </param> /// <returns> /// <code>true</code> if <paramref name="targetValue"/> is found and successfully parsed; otherwise, /// <code>false</code>. /// </returns> // e.g. { "headerValue=10, targetHeaderValue=30" } public static bool TryParseSeconds(StringValues headerValues, string targetValue, out TimeSpan?value) { if (StringValues.IsNullOrEmpty(headerValues) || string.IsNullOrEmpty(targetValue)) { value = null; return(false); } for (var i = 0; i < headerValues.Count; i++) { // Trim leading white space var current = HttpRuleParser.GetWhitespaceLength(headerValues[i], 0); while (current < headerValues[i].Length) { long seconds; var initial = current; var tokenLength = HttpRuleParser.GetTokenLength(headerValues[i], current); if (tokenLength == targetValue.Length && string.Compare(headerValues[i], current, targetValue, 0, tokenLength, StringComparison.OrdinalIgnoreCase) == 0 && TryParseNonNegativeInt64FromHeaderValue(current + tokenLength, headerValues[i], out seconds)) { // Token matches target value and seconds were parsed value = TimeSpan.FromSeconds(seconds); return(true); } current = AdvanceCacheDirectiveIndex(current + tokenLength, headerValues[i]); // Ensure index was advanced if (current <= initial) { Debug.Assert(false, $"Index '{nameof(current)}' not advanced, this is a bug."); value = null; return(false); } } } value = null; return(false); }
internal static int GetValueLength(StringSegment input, int startIndex) { Contract.Requires(input != null); if (startIndex >= input.Length) { return(0); } var valueLength = HttpRuleParser.GetTokenLength(input, startIndex); if (valueLength == 0) { // A value can either be a token or a quoted string. Check if it is a quoted string. if (HttpRuleParser.GetQuotedStringLength(input, startIndex, out valueLength) != HttpParseResult.Parsed) { // We have an invalid value. Reset the name and return. return(0); } } return(valueLength); }
/// <summary> /// Check if a target directive exists among the set of given cache control directives. /// </summary> /// <param name="cacheControlDirectives"> /// The <see cref="StringValues"/> containing the set of cache control directives. /// </param> /// <param name="targetDirectives"> /// The target cache control directives to look for. /// </param> /// <returns> /// <code>true</code> if <paramref name="targetDirectives"/> is contained in <paramref name="cacheControlDirectives"/>; /// otherwise, <code>false</code>. /// </returns> public static bool ContainsCacheDirective(StringValues cacheControlDirectives, string targetDirectives) { if (StringValues.IsNullOrEmpty(cacheControlDirectives) || string.IsNullOrEmpty(targetDirectives)) { return(false); } for (var i = 0; i < cacheControlDirectives.Count; i++) { // Trim leading white space var current = HttpRuleParser.GetWhitespaceLength(cacheControlDirectives[i], 0); while (current < cacheControlDirectives[i].Length) { var initial = current; var tokenLength = HttpRuleParser.GetTokenLength(cacheControlDirectives[i], current); if (tokenLength == targetDirectives.Length && string.Compare(cacheControlDirectives[i], current, targetDirectives, 0, tokenLength, StringComparison.OrdinalIgnoreCase) == 0) { // Token matches target value return(true); } current = AdvanceCacheDirectiveIndex(current + tokenLength, cacheControlDirectives[i]); // Ensure index was advanced if (current <= initial) { Debug.Assert(false, $"Index '{nameof(current)}' not advanced, this is a bug."); return(false); } } } return(false); }