private static bool TrySetCacheControlValues( CacheControlHeaderValue cc, List <NameValueHeaderValue> nameValueList) { for (var i = 0; i < nameValueList.Count; i++) { var nameValue = nameValueList[i]; var name = nameValue.Name; var success = true; switch (name.Length) { case 6: if (StringSegment.Equals(PublicString, name, StringComparison.OrdinalIgnoreCase)) { success = TrySetTokenOnlyValue(nameValue, ref cc._public); } else { goto default; } break; case 7: if (StringSegment.Equals(MaxAgeString, name, StringComparison.OrdinalIgnoreCase)) { success = TrySetTimeSpan(nameValue, ref cc._maxAge); } else if (StringSegment.Equals(PrivateString, name, StringComparison.OrdinalIgnoreCase)) { success = TrySetOptionalTokenList(nameValue, ref cc._private, ref cc._privateHeaders); } else { goto default; } break; case 8: if (StringSegment.Equals(NoCacheString, name, StringComparison.OrdinalIgnoreCase)) { success = TrySetOptionalTokenList(nameValue, ref cc._noCache, ref cc._noCacheHeaders); } else if (StringSegment.Equals(NoStoreString, name, StringComparison.OrdinalIgnoreCase)) { success = TrySetTokenOnlyValue(nameValue, ref cc._noStore); } else if (StringSegment.Equals(SharedMaxAgeString, name, StringComparison.OrdinalIgnoreCase)) { success = TrySetTimeSpan(nameValue, ref cc._sharedMaxAge); } else { goto default; } break; case 9: if (StringSegment.Equals(MaxStaleString, name, StringComparison.OrdinalIgnoreCase)) { success = ((nameValue.Value == null) || TrySetTimeSpan(nameValue, ref cc._maxStaleLimit)); if (success) { cc._maxStale = true; } } else if (StringSegment.Equals(MinFreshString, name, StringComparison.OrdinalIgnoreCase)) { success = TrySetTimeSpan(nameValue, ref cc._minFresh); } else { goto default; } break; case 12: if (StringSegment.Equals(NoTransformString, name, StringComparison.OrdinalIgnoreCase)) { success = TrySetTokenOnlyValue(nameValue, ref cc._noTransform); } else { goto default; } break; case 14: if (StringSegment.Equals(OnlyIfCachedString, name, StringComparison.OrdinalIgnoreCase)) { success = TrySetTokenOnlyValue(nameValue, ref cc._onlyIfCached); } else { goto default; } break; case 15: if (StringSegment.Equals(MustRevalidateString, name, StringComparison.OrdinalIgnoreCase)) { success = TrySetTokenOnlyValue(nameValue, ref cc._mustRevalidate); } else { goto default; } break; case 16: if (StringSegment.Equals(ProxyRevalidateString, name, StringComparison.OrdinalIgnoreCase)) { success = TrySetTokenOnlyValue(nameValue, ref cc._proxyRevalidate); } else { goto default; } break; default: cc.Extensions.Add(nameValue); // success is always true break; } if (!success) { return(false); } } return(true); }
private static int GetCacheControlLength(StringSegment input, int startIndex, out CacheControlHeaderValue parsedValue) { Contract.Requires(startIndex >= 0); parsedValue = null; if (StringSegment.IsNullOrEmpty(input) || (startIndex >= input.Length)) { return(0); } // Cache-Control header consists of a list of name/value pairs, where the value is optional. So use an // instance of NameValueHeaderParser to parse the string. var current = startIndex; NameValueHeaderValue nameValue = null; var nameValueList = new List <NameValueHeaderValue>(); while (current < input.Length) { if (!NameValueHeaderValue.MultipleValueParser.TryParseValue(input, ref current, out nameValue)) { return(0); } nameValueList.Add(nameValue); } // If we get here, we were able to successfully parse the string as list of name/value pairs. Now analyze // the name/value pairs. // Cache-Control is a header supporting lists of values. However, expose the header as an instance of // CacheControlHeaderValue. var result = new CacheControlHeaderValue(); if (!TrySetCacheControlValues(result, nameValueList)) { return(0); } parsedValue = result; // If we get here we successfully parsed the whole string. return(input.Length - startIndex); }