public void Properties_SetAndGetAllProperties_SetValueReturnedInGetter() { var cacheControl = new CacheControlHeaderValue(); // Bool properties cacheControl.NoCache = true; Assert.True(cacheControl.NoCache, "NoCache"); cacheControl.NoStore = true; Assert.True(cacheControl.NoStore, "NoStore"); cacheControl.MaxStale = true; Assert.True(cacheControl.MaxStale, "MaxStale"); cacheControl.NoTransform = true; Assert.True(cacheControl.NoTransform, "NoTransform"); cacheControl.OnlyIfCached = true; Assert.True(cacheControl.OnlyIfCached, "OnlyIfCached"); cacheControl.Public = true; Assert.True(cacheControl.Public, "Public"); cacheControl.Private = true; Assert.True(cacheControl.Private, "Private"); cacheControl.MustRevalidate = true; Assert.True(cacheControl.MustRevalidate, "MustRevalidate"); cacheControl.ProxyRevalidate = true; Assert.True(cacheControl.ProxyRevalidate, "ProxyRevalidate"); // TimeSpan properties TimeSpan timeSpan = new TimeSpan(1, 2, 3); cacheControl.MaxAge = timeSpan; Assert.Equal(timeSpan, cacheControl.MaxAge); cacheControl.SharedMaxAge = timeSpan; Assert.Equal(timeSpan, cacheControl.SharedMaxAge); cacheControl.MaxStaleLimit = timeSpan; Assert.Equal(timeSpan, cacheControl.MaxStaleLimit); cacheControl.MinFresh = timeSpan; Assert.Equal(timeSpan, cacheControl.MinFresh); // String collection properties Assert.NotNull(cacheControl.NoCacheHeaders); Assert.Throws<ArgumentException>(() => cacheControl.NoCacheHeaders.Add(null)); Assert.Throws<FormatException>(() => cacheControl.NoCacheHeaders.Add("invalid token")); cacheControl.NoCacheHeaders.Add("token"); Assert.Equal(1, cacheControl.NoCacheHeaders.Count); Assert.Equal("token", cacheControl.NoCacheHeaders.First()); Assert.NotNull(cacheControl.PrivateHeaders); Assert.Throws<ArgumentException>(() => cacheControl.PrivateHeaders.Add(null)); Assert.Throws<FormatException>(() => cacheControl.PrivateHeaders.Add("invalid token")); cacheControl.PrivateHeaders.Add("token"); Assert.Equal(1, cacheControl.PrivateHeaders.Count); Assert.Equal("token", cacheControl.PrivateHeaders.First()); // NameValueHeaderValue collection property Assert.NotNull(cacheControl.Extensions); Assert.Throws<ArgumentNullException>(() => cacheControl.Extensions.Add(null)); cacheControl.Extensions.Add(new NameValueHeaderValue("name", "value")); Assert.Equal(1, cacheControl.Extensions.Count); Assert.Equal(new NameValueHeaderValue("name", "value"), cacheControl.Extensions.First()); }
public static void ApplyCacheResponseDirective(this HttpResponse response, CacheResponseDirective directive) { var cacheControl = new CacheControlHeaderValue(); cacheControl.MaxAge = directive.MaxAge; cacheControl.MustRevalidate = directive.MustRevalidate; cacheControl.NoCache = directive.NoCache; cacheControl.NoStore = directive.NoStore; cacheControl.Private = directive.Private; cacheControl.Public = directive.Public; cacheControl.SharedMaxAge = directive.SharedMaxAge; var responseHeaders = response.GetTypedHeaders(); responseHeaders.CacheControl = cacheControl; responseHeaders.LastModified = directive.LastModified; responseHeaders.ETag = directive.ETag.ToETagHeaderValue(); }
public void Equals_CompareCollectionFieldsSet_MatchExpectation() { var cacheControl1 = new CacheControlHeaderValue(); var cacheControl2 = new CacheControlHeaderValue(); var cacheControl3 = new CacheControlHeaderValue(); var cacheControl4 = new CacheControlHeaderValue(); var cacheControl5 = new CacheControlHeaderValue(); var cacheControl6 = new CacheControlHeaderValue(); cacheControl1.NoCache = true; cacheControl1.NoCacheHeaders.Add("PLACEHOLDER2"); Assert.False(cacheControl1.Equals(null), "Compare with 'null'"); cacheControl2.NoCache = true; cacheControl2.NoCacheHeaders.Add("PLACEHOLDER1"); cacheControl2.NoCacheHeaders.Add("PLACEHOLDER2"); CompareValues(cacheControl1 !, cacheControl2, false); cacheControl1 !.NoCacheHeaders.Add("PLACEHOLDER1"); CompareValues(cacheControl1, cacheControl2, true); // Since NoCache and Private generate different hash codes, even if NoCacheHeaders and PrivateHeaders // have the same values, the hash code will be different. cacheControl3.Private = true; cacheControl3.PrivateHeaders.Add("PLACEHOLDER2"); CompareValues(cacheControl1, cacheControl3, false); cacheControl4.Private = true; cacheControl4.PrivateHeaders.Add("PLACEHOLDER3"); CompareValues(cacheControl3, cacheControl4, false); cacheControl5.Extensions.Add(new NameValueHeaderValue("custom")); CompareValues(cacheControl1, cacheControl5, false); cacheControl6.Extensions.Add(new NameValueHeaderValue("customN", "customV")); cacheControl6.Extensions.Add(new NameValueHeaderValue("custom")); CompareValues(cacheControl5, cacheControl6, false); cacheControl5.Extensions.Add(new NameValueHeaderValue("customN", "customV")); CompareValues(cacheControl5, cacheControl6, true); }
public void Equals_CompareValuesWithBoolFieldsSet_MatchExpectation() { // Verify that different bool fields return different hash values. var values = new CacheControlHeaderValue[9]; for (int i = 0; i < values.Length; i++) { values[i] = new CacheControlHeaderValue(); } values[0].ProxyRevalidate = true; values[1].NoCache = true; values[2].NoStore = true; values[3].MaxStale = true; values[4].NoTransform = true; values[5].OnlyIfCached = true; values[6].Public = true; values[7].Private = true; values[8].MustRevalidate = true; // Only one bool field set. All hash codes should differ for (int i = 0; i < values.Length; i++) { for (int j = 0; j < values.Length; j++) { if (i != j) { CompareValues(values[i], values[j], false); } } } // Validate that two instances with the same bool fields set are equal. values[0].NoCache = true; CompareValues(values[0], values[1], false); values[1].ProxyRevalidate = true; CompareValues(values[0], values[1], true); }
public void ToString_UseRequestDirectiveValues_AllSerializedCorrectly() { var cacheControl = new CacheControlHeaderValue(); Assert.Equal("", cacheControl.ToString()); // Note that we allow all combinations of all properties even though the RFC specifies rules what value // can be used together. // Also for property pairs (bool property + collection property) like 'NoCache' and 'NoCacheHeaders' the // caller needs to set the bool property in order for the collection to be populated as string. // Cache Request Directive sample cacheControl.NoStore = true; Assert.Equal("no-store", cacheControl.ToString()); cacheControl.NoCache = true; Assert.Equal("no-store, no-cache", cacheControl.ToString()); cacheControl.MaxAge = new TimeSpan(0, 1, 10); Assert.Equal("no-store, no-cache, max-age=70", cacheControl.ToString()); cacheControl.MaxStale = true; Assert.Equal("no-store, no-cache, max-age=70, max-stale", cacheControl.ToString()); cacheControl.MaxStaleLimit = new TimeSpan(0, 2, 5); Assert.Equal("no-store, no-cache, max-age=70, max-stale=125", cacheControl.ToString()); cacheControl.MinFresh = new TimeSpan(0, 3, 0); Assert.Equal("no-store, no-cache, max-age=70, max-stale=125, min-fresh=180", cacheControl.ToString()); cacheControl = new CacheControlHeaderValue(); cacheControl.NoTransform = true; Assert.Equal("no-transform", cacheControl.ToString()); cacheControl.OnlyIfCached = true; Assert.Equal("no-transform, only-if-cached", cacheControl.ToString()); cacheControl.Extensions.Add(new NameValueHeaderValue("custom")); cacheControl.Extensions.Add(new NameValueHeaderValue("customName", "customValue")); Assert.Equal("no-transform, only-if-cached, custom, customName=customValue", cacheControl.ToString()); cacheControl = new CacheControlHeaderValue(); cacheControl.Extensions.Add(new NameValueHeaderValue("custom")); Assert.Equal("custom", cacheControl.ToString()); }
public void TryParse_SetOfValidValueStrings_ParsedCorrectly() { // Just verify parser is implemented correctly. Don't try to test syntax parsed by CacheControlHeaderValue. var expected = new CacheControlHeaderValue(); expected.NoStore = true; expected.MinFresh = new TimeSpan(0, 2, 3); CheckValidTryParse(" , no-store, min-fresh=123", expected); expected = new CacheControlHeaderValue(); expected.MaxStale = true; expected.NoCache = true; expected.NoCacheHeaders.Add("t"); CheckValidTryParse("max-stale, no-cache=\"t\", ,,", expected); expected = new CacheControlHeaderValue(); expected.Extensions.Add(new NameValueHeaderValue("custom")); CheckValidTryParse("custom = ", expected); expected = new CacheControlHeaderValue(); expected.Extensions.Add(new NameValueHeaderValue("custom", "")); CheckValidTryParse("custom =", expected); }
public void GetHashCode_CompareCollectionFieldsSet_MatchExpectation() { var cacheControl1 = new CacheControlHeaderValue(); var cacheControl2 = new CacheControlHeaderValue(); var cacheControl3 = new CacheControlHeaderValue(); var cacheControl4 = new CacheControlHeaderValue(); var cacheControl5 = new CacheControlHeaderValue(); cacheControl1.NoCache = true; cacheControl1.NoCacheHeaders.Add("PLACEHOLDER2"); cacheControl2.NoCache = true; cacheControl2.NoCacheHeaders.Add("PLACEHOLDER1"); cacheControl2.NoCacheHeaders.Add("PLACEHOLDER2"); CompareHashCodes(cacheControl1, cacheControl2, false); cacheControl1.NoCacheHeaders.Add("PLACEHOLDER1"); CompareHashCodes(cacheControl1, cacheControl2, true); // Since NoCache and Private generate different hash codes, even if NoCacheHeaders and PrivateHeaders // have the same values, the hash code will be different. cacheControl3.Private = true; cacheControl3.PrivateHeaders.Add("PLACEHOLDER2"); CompareHashCodes(cacheControl1, cacheControl3, false); cacheControl4.Extensions.Add(new NameValueHeaderValue("custom")); CompareHashCodes(cacheControl1, cacheControl4, false); cacheControl5.Extensions.Add(new NameValueHeaderValue("customN", "customV")); cacheControl5.Extensions.Add(new NameValueHeaderValue("custom")); CompareHashCodes(cacheControl4, cacheControl5, false); cacheControl4.Extensions.Add(new NameValueHeaderValue("customN", "customV")); CompareHashCodes(cacheControl4, cacheControl5, true); }
public void ToString_UseRequestDirectiveValues_AllSerializedCorrectly() { var cacheControl = new CacheControlHeaderValue(); Assert.Equal("", cacheControl.ToString()); // Note that we allow all combinations of all properties even though the RFC specifies rules what value // can be used together. // Also for property pairs (bool property + collection property) like 'NoCache' and 'NoCacheHeaders' the // caller needs to set the bool property in order for the collection to be populated as string. // Cache Request Directive sample cacheControl.NoStore = true; Assert.Equal("no-store", cacheControl.ToString()); cacheControl.NoCache = true; Assert.Equal("no-store, no-cache", cacheControl.ToString()); cacheControl.MaxAge = new TimeSpan(0, 1, 10); Assert.Equal("no-store, no-cache, max-age=70", cacheControl.ToString()); cacheControl.MaxStale = true; Assert.Equal("no-store, no-cache, max-age=70, max-stale", cacheControl.ToString()); cacheControl.MaxStaleLimit = new TimeSpan(0, 2, 5); Assert.Equal("no-store, no-cache, max-age=70, max-stale=125", cacheControl.ToString()); cacheControl.MinFresh = new TimeSpan(0, 3, 0); Assert.Equal("no-store, no-cache, max-age=70, max-stale=125, min-fresh=180", cacheControl.ToString()); cacheControl = new CacheControlHeaderValue(); cacheControl.NoTransform = true; Assert.Equal("no-transform", cacheControl.ToString()); cacheControl.OnlyIfCached = true; Assert.Equal("no-transform, only-if-cached", cacheControl.ToString()); cacheControl.Extensions.Add(new NameValueHeaderValue("custom")); cacheControl.Extensions.Add(new NameValueHeaderValue("customName", "customValue")); Assert.Equal("no-transform, only-if-cached, custom, customName=customValue", cacheControl.ToString()); cacheControl = new CacheControlHeaderValue(); cacheControl.Extensions.Add(new NameValueHeaderValue("custom")); Assert.Equal("custom", cacheControl.ToString()); }
public void ToString_UseResponseDirectiveValues_AllSerializedCorrectly() { var cacheControl = new CacheControlHeaderValue(); Assert.Equal("", cacheControl.ToString()); cacheControl.NoCache = true; Assert.Equal("no-cache", cacheControl.ToString()); cacheControl.NoCacheHeaders.Add("PLACEHOLDER1"); Assert.Equal("no-cache=\"PLACEHOLDER1\"", cacheControl.ToString()); cacheControl.Public = true; Assert.Equal("public, no-cache=\"PLACEHOLDER1\"", cacheControl.ToString()); cacheControl = new CacheControlHeaderValue(); cacheControl.Private = true; Assert.Equal("private", cacheControl.ToString()); cacheControl.PrivateHeaders.Add("PLACEHOLDER2"); cacheControl.PrivateHeaders.Add("PLACEHOLDER3"); Assert.Equal("private=\"PLACEHOLDER2, PLACEHOLDER3\"", cacheControl.ToString()); cacheControl.MustRevalidate = true; Assert.Equal("must-revalidate, private=\"PLACEHOLDER2, PLACEHOLDER3\"", cacheControl.ToString()); cacheControl.ProxyRevalidate = true; Assert.Equal("must-revalidate, proxy-revalidate, private=\"PLACEHOLDER2, PLACEHOLDER3\"", cacheControl.ToString()); }
public void ForRequestWithBothPragmaNoCacheAndCacheControl_UsesValueFromCacheControl() { var cacheControlHeader = new CacheControlHeaderValue(); cacheControlHeader.NoCache = false; cacheControlHeader.MaxStale = true; // Need this so that Cache-Control is treated as having a value typedHeaders.CacheControl = cacheControlHeader; request.Headers[HeaderNames.Pragma] = "no-cache"; var result = DnxExtensions.ReadCacheRequestDirective(request); Assert.False(result.NoCache); }
public void ToString_UseResponseDirectiveValues_AllSerializedCorrectly() { var cacheControl = new CacheControlHeaderValue(); Assert.Equal("", cacheControl.ToString()); cacheControl.NoCache = true; Assert.Equal("no-cache", cacheControl.ToString()); cacheControl.NoCacheHeaders.Add("token1"); Assert.Equal("no-cache=\"token1\"", cacheControl.ToString()); cacheControl.Public = true; Assert.Equal("public, no-cache=\"token1\"", cacheControl.ToString()); cacheControl = new CacheControlHeaderValue(); cacheControl.Private = true; Assert.Equal("private", cacheControl.ToString()); cacheControl.PrivateHeaders.Add("token2"); cacheControl.PrivateHeaders.Add("token3"); Assert.Equal("private=\"token2, token3\"", cacheControl.ToString()); cacheControl.MustRevalidate = true; Assert.Equal("must-revalidate, private=\"token2, token3\"", cacheControl.ToString()); cacheControl.ProxyRevalidate = true; Assert.Equal("must-revalidate, proxy-revalidate, private=\"token2, token3\"", cacheControl.ToString()); }
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); }
private void CompareValues(CacheControlHeaderValue x, CacheControlHeaderValue y, bool areEqual) { Assert.Equal(areEqual, x.Equals(y)); Assert.Equal(areEqual, y.Equals(x)); }
public void TryParse_SetOfValidValueStrings_ParsedCorrectly() { // Just verify parser is implemented correctly. Don't try to test syntax parsed by CacheControlHeaderValue. var expected = new CacheControlHeaderValue(); expected.NoStore = true; expected.MinFresh = new TimeSpan(0, 2, 3); CheckValidTryParse(" , no-store, min-fresh=123", expected); expected = new CacheControlHeaderValue(); expected.MaxStale = true; expected.NoCache = true; expected.NoCacheHeaders.Add("t"); CheckValidTryParse("max-stale, no-cache=\"t\", ,,", expected); expected = new CacheControlHeaderValue(); expected.Extensions.Add(new NameValueHeaderValue("custom")); CheckValidTryParse("custom = ", expected); expected = new CacheControlHeaderValue(); expected.Extensions.Add(new NameValueHeaderValue("custom", "")); CheckValidTryParse("custom =", expected); }
public void Equals_CompareCollectionFieldsSet_MatchExpectation() { var cacheControl1 = new CacheControlHeaderValue(); var cacheControl2 = new CacheControlHeaderValue(); var cacheControl3 = new CacheControlHeaderValue(); var cacheControl4 = new CacheControlHeaderValue(); var cacheControl5 = new CacheControlHeaderValue(); var cacheControl6 = new CacheControlHeaderValue(); cacheControl1.NoCache = true; cacheControl1.NoCacheHeaders.Add("token2"); Assert.False(cacheControl1.Equals(null), "Compare with 'null'"); cacheControl2.NoCache = true; cacheControl2.NoCacheHeaders.Add("token1"); cacheControl2.NoCacheHeaders.Add("token2"); CompareValues(cacheControl1, cacheControl2, false); cacheControl1.NoCacheHeaders.Add("token1"); CompareValues(cacheControl1, cacheControl2, true); // Since NoCache and Private generate different hash codes, even if NoCacheHeaders and PrivateHeaders // have the same values, the hash code will be different. cacheControl3.Private = true; cacheControl3.PrivateHeaders.Add("token2"); CompareValues(cacheControl1, cacheControl3, false); cacheControl4.Private = true; cacheControl4.PrivateHeaders.Add("token3"); CompareValues(cacheControl3, cacheControl4, false); cacheControl5.Extensions.Add(new NameValueHeaderValue("custom")); CompareValues(cacheControl1, cacheControl5, false); cacheControl6.Extensions.Add(new NameValueHeaderValue("customN", "customV")); cacheControl6.Extensions.Add(new NameValueHeaderValue("custom")); CompareValues(cacheControl5, cacheControl6, false); cacheControl5.Extensions.Add(new NameValueHeaderValue("customN", "customV")); CompareValues(cacheControl5, cacheControl6, true); }
private void CheckValidTryParse(string input, CacheControlHeaderValue expectedResult) { CacheControlHeaderValue result = null; Assert.True(CacheControlHeaderValue.TryParse(input, out result)); Assert.Equal(expectedResult, result); }
private void CompareValues(CacheControlHeaderValue x, CacheControlHeaderValue y, bool areEqual) { Assert.Equal(areEqual, x.Equals(y)); Assert.Equal(areEqual, y.Equals(x)); }
private void CheckInvalidTryParse(string?input) { Assert.False(CacheControlHeaderValue.TryParse(input, out var result)); Assert.Null(result); }
private void CheckValidTryParse(string?input, CacheControlHeaderValue expectedResult) { Assert.True(CacheControlHeaderValue.TryParse(input, out var result)); Assert.Equal(expectedResult, result); }
private void CheckInvalidParse(string?input) { Assert.Throws <FormatException>(() => CacheControlHeaderValue.Parse(input)); }
private void CheckValidParse(string?input, CacheControlHeaderValue expectedResult) { var result = CacheControlHeaderValue.Parse(input); Assert.Equal(expectedResult, result); }
public void Equals_CompareValuesWithBoolFieldsSet_MatchExpectation() { // Verify that different bool fields return different hash values. var values = new CacheControlHeaderValue[9]; for (int i = 0; i < values.Length; i++) { values[i] = new CacheControlHeaderValue(); } values[0].ProxyRevalidate = true; values[1].NoCache = true; values[2].NoStore = true; values[3].MaxStale = true; values[4].NoTransform = true; values[5].OnlyIfCached = true; values[6].Public = true; values[7].Private = true; values[8].MustRevalidate = true; // Only one bool field set. All hash codes should differ for (int i = 0; i < values.Length; i++) { for (int j = 0; j < values.Length; j++) { if (i != j) { CompareValues(values[i], values[j], false); } } } // Validate that two instances with the same bool fields set are equal. values[0].NoCache = true; CompareValues(values[0], values[1], false); values[1].ProxyRevalidate = true; CompareValues(values[0], values[1], true); }
public void Equals_CompareValuesWithTimeSpanFieldsSet_MatchExpectation() { // Verify that different timespan fields return different hash values. var values = new CacheControlHeaderValue[4]; for (int i = 0; i < values.Length; i++) { values[i] = new CacheControlHeaderValue(); } values[0].MaxAge = new TimeSpan(0, 1, 1); values[1].MaxStaleLimit = new TimeSpan(0, 1, 1); values[2].MinFresh = new TimeSpan(0, 1, 1); values[3].SharedMaxAge = new TimeSpan(0, 1, 1); // Only one timespan field set. All hash codes should differ for (int i = 0; i < values.Length; i++) { for (int j = 0; j < values.Length; j++) { if (i != j) { CompareValues(values[i], values[j], false); } } } values[0].MaxStaleLimit = new TimeSpan(0, 1, 2); CompareValues(values[0], values[1], false); values[1].MaxAge = new TimeSpan(0, 1, 1); values[1].MaxStaleLimit = new TimeSpan(0, 1, 2); CompareValues(values[0], values[1], true); var value1 = new CacheControlHeaderValue(); value1.MaxStale = true; var value2 = new CacheControlHeaderValue(); value2.MaxStale = true; CompareValues(value1, value2, true); value2.MaxStaleLimit = new TimeSpan(1, 2, 3); CompareValues(value1, value2, false); }
public void ForRequestWithoutExplicitMaxStaleLimitValue_ReturnsMax() { var cacheControlHeader = new CacheControlHeaderValue(); cacheControlHeader.MaxStale = true; cacheControlHeader.MaxStaleLimit = null; typedHeaders.CacheControl = cacheControlHeader; var result = DnxExtensions.ReadCacheRequestDirective(request); Assert.Equal(TimeSpan.MaxValue, result.MaxStale); }
public void TryParse_DifferentValidScenarios_AllReturnTrue() { var expected = new CacheControlHeaderValue(); expected.NoCache = true; CheckValidTryParse(" , no-cache ,,", expected); expected = new CacheControlHeaderValue(); expected.NoCache = true; expected.NoCacheHeaders.Add("token1"); expected.NoCacheHeaders.Add("token2"); CheckValidTryParse("no-cache=\"token1, token2\"", expected); expected = new CacheControlHeaderValue(); expected.NoStore = true; expected.MaxAge = new TimeSpan(0, 0, 125); expected.MaxStale = true; CheckValidTryParse(" no-store , max-age = 125, max-stale,", expected); expected = new CacheControlHeaderValue(); expected.MinFresh = new TimeSpan(0, 0, 123); expected.NoTransform = true; expected.OnlyIfCached = true; expected.Extensions.Add(new NameValueHeaderValue("custom")); CheckValidTryParse("min-fresh=123, no-transform, only-if-cached, custom", expected); expected = new CacheControlHeaderValue(); expected.Public = true; expected.Private = true; expected.PrivateHeaders.Add("token1"); expected.MustRevalidate = true; expected.ProxyRevalidate = true; expected.Extensions.Add(new NameValueHeaderValue("c", "d")); expected.Extensions.Add(new NameValueHeaderValue("a", "b")); CheckValidTryParse(",public, , private=\"token1\", must-revalidate, c=d, proxy-revalidate, a=b", expected); expected = new CacheControlHeaderValue(); expected.Private = true; expected.SharedMaxAge = new TimeSpan(0, 0, 1234567890); expected.MaxAge = new TimeSpan(0, 0, 987654321); CheckValidTryParse("s-maxage=1234567890, private, max-age = 987654321,", expected); expected = new CacheControlHeaderValue(); expected.Extensions.Add(new NameValueHeaderValue("custom", "")); CheckValidTryParse("custom=", expected); }
private static int GetCacheControlLength(string input, int startIndex, out CacheControlHeaderValue parsedValue) { Contract.Requires(startIndex >= 0); parsedValue = null; if (string.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; }
private void CompareHashCodes(CacheControlHeaderValue x, CacheControlHeaderValue y, bool areEqual) { if (areEqual) { Assert.Equal(x.GetHashCode(), y.GetHashCode()); } else { Assert.NotEqual(x.GetHashCode(), y.GetHashCode()); } }
private static bool TrySetCacheControlValues( CacheControlHeaderValue cc, List<NameValueHeaderValue> nameValueList) { foreach (NameValueHeaderValue nameValue in nameValueList) { var success = true; string name = nameValue.Name.ToLowerInvariant(); switch (name) { case NoCacheString: success = TrySetOptionalTokenList(nameValue, ref cc._noCache, ref cc._noCacheHeaders); break; case NoStoreString: success = TrySetTokenOnlyValue(nameValue, ref cc._noStore); break; case MaxAgeString: success = TrySetTimeSpan(nameValue, ref cc._maxAge); break; case MaxStaleString: success = ((nameValue.Value == null) || TrySetTimeSpan(nameValue, ref cc._maxStaleLimit)); if (success) { cc._maxStale = true; } break; case MinFreshString: success = TrySetTimeSpan(nameValue, ref cc._minFresh); break; case NoTransformString: success = TrySetTokenOnlyValue(nameValue, ref cc._noTransform); break; case OnlyIfCachedString: success = TrySetTokenOnlyValue(nameValue, ref cc._onlyIfCached); break; case PublicString: success = TrySetTokenOnlyValue(nameValue, ref cc._public); break; case PrivateString: success = TrySetOptionalTokenList(nameValue, ref cc._private, ref cc._privateHeaders); break; case MustRevalidateString: success = TrySetTokenOnlyValue(nameValue, ref cc._mustRevalidate); break; case ProxyRevalidateString: success = TrySetTokenOnlyValue(nameValue, ref cc._proxyRevalidate); break; case SharedMaxAgeString: success = TrySetTimeSpan(nameValue, ref cc._sharedMaxAge); break; default: cc.Extensions.Add(nameValue); // success is always true break; } if (!success) { return false; } } return true; }
private void CheckValidParse(string input, CacheControlHeaderValue expectedResult) { var result = CacheControlHeaderValue.Parse(input); Assert.Equal(expectedResult, result); }
private static bool TrySetCacheControlValues(CacheControlHeaderValue cc, List <NameValueHeaderValue> nameValueList) { foreach (NameValueHeaderValue nameValue in nameValueList) { var success = true; string name = nameValue.Name.ToLowerInvariant(); switch (name) { case NoCacheString: success = TrySetOptionalTokenList(nameValue, ref cc._noCache, ref cc._noCacheHeaders); break; case NoStoreString: success = TrySetTokenOnlyValue(nameValue, ref cc._noStore); break; case MaxAgeString: success = TrySetTimeSpan(nameValue, ref cc._maxAge); break; case MaxStaleString: success = ((nameValue.Value == null) || TrySetTimeSpan(nameValue, ref cc._maxStaleLimit)); if (success) { cc._maxStale = true; } break; case MinFreshString: success = TrySetTimeSpan(nameValue, ref cc._minFresh); break; case NoTransformString: success = TrySetTokenOnlyValue(nameValue, ref cc._noTransform); break; case OnlyIfCachedString: success = TrySetTokenOnlyValue(nameValue, ref cc._onlyIfCached); break; case PublicString: success = TrySetTokenOnlyValue(nameValue, ref cc._public); break; case PrivateString: success = TrySetOptionalTokenList(nameValue, ref cc._private, ref cc._privateHeaders); break; case MustRevalidateString: success = TrySetTokenOnlyValue(nameValue, ref cc._mustRevalidate); break; case ProxyRevalidateString: success = TrySetTokenOnlyValue(nameValue, ref cc._proxyRevalidate); break; case SharedMaxAgeString: success = TrySetTimeSpan(nameValue, ref cc._sharedMaxAge); break; default: cc.Extensions.Add(nameValue); // success is always true break; } if (!success) { return(false); } } return(true); }
public static bool TryParse(string input, out CacheControlHeaderValue parsedValue) { int index = 0; // Cache-Control is unusual because there are no required values so the parser will succeed for an empty string, but still return null. if (Parser.TryParseValue(input, ref index, out parsedValue) && parsedValue != null) { return true; } parsedValue = null; return false; }
public void ForRequestWithCacheControl_ReturnsSpecifiedSettigns() { var cacheControlHeader = new CacheControlHeaderValue(); cacheControlHeader.MaxAge = TimeSpan.FromMinutes(15); cacheControlHeader.MaxStale = true; cacheControlHeader.MaxStaleLimit = TimeSpan.FromMinutes(20); cacheControlHeader.MinFresh = TimeSpan.FromMinutes(10); cacheControlHeader.NoCache = true; cacheControlHeader.NoStore = true; cacheControlHeader.OnlyIfCached = true; typedHeaders.CacheControl = cacheControlHeader; var result = DnxExtensions.ReadCacheRequestDirective(request); Assert.Equal(TimeSpan.FromMinutes(15), result.MaxAge); Assert.Equal(TimeSpan.FromMinutes(20), result.MaxStale); Assert.Equal(TimeSpan.FromMinutes(10), result.MinFresh); Assert.True(result.NoCache); Assert.True(result.NoStore); Assert.True(result.OnlyIfCached); }