public static ConditionalRequestDirective ReadConditionalReqeustDirective(this HttpRequest request) { var isSafe = safeMethods.Contains(request.Method); var result = new ConditionalRequestDirective(isSafe); var typedHeaders = request.GetTypedHeaders(); result.IfModifiedSince = typedHeaders.IfModifiedSince; result.IfUnmodifiedSince = typedHeaders.IfUnmodifiedSince; CopyETags(typedHeaders.IfMatch, result.IfMatch); CopyETags(typedHeaders.IfNoneMatch, result.IfNoneMatch); return result; }
public void MaintainsValueOfIsSafePropertyInNewObjects(bool methodIsSafe) { var directive = new ConditionalRequestDirective(methodIsSafe); var result = directive.SplitETag(3, t => null); Assert.All(result, d => { Assert.Equal(methodIsSafe, d.IsSafe); }); }
public void WhenDirectiveHasNoPropertiesSet_ReturnsExpectedNumberOfNewDirectivesWithNoPropertiesSet(int count) { var directive = new ConditionalRequestDirective(true); var result = directive.SplitETag(count, t => null); Assert.Equal(count, result.Length); Assert.All(result, d => { Assert.NotNull(d); Assert.NotSame(directive, d); Assert.Null(d.IfModifiedSince); Assert.Null(d.IfUnmodifiedSince); Assert.Empty(d.IfMatch); Assert.Empty(d.IfNoneMatch); }); }
public static void ApplyCacheRequestDirective(this HttpRequestMessage requestMessage, CacheRequestDirective cacheDirective, ConditionalRequestDirective conditionalDirective) { var cacheControlHeader = new CacheControlHeaderValue(); cacheControlHeader.MaxAge = cacheDirective.MaxAge; cacheControlHeader.MaxStale = cacheDirective.MaxStale.HasValue; if (cacheDirective.MaxStale != TimeSpan.MaxValue) cacheControlHeader.MaxStaleLimit = cacheDirective.MaxStale; cacheControlHeader.MinFresh = cacheDirective.MinFresh; cacheControlHeader.NoCache = cacheDirective.NoCache; if (cacheDirective.NoCache) requestMessage.Headers.Pragma.Add(new NameValueHeaderValue("no-cache")); cacheControlHeader.NoStore = cacheDirective.NoStore; // TODO deal with no-transform cacheControlHeader.OnlyIfCached = cacheDirective.OnlyIfCached; requestMessage.Headers.CacheControl = cacheControlHeader; requestMessage.Headers.IfModifiedSince = conditionalDirective.IfModifiedSince; requestMessage.Headers.IfUnmodifiedSince = conditionalDirective.IfUnmodifiedSince; CopyETags(conditionalDirective.IfMatch, requestMessage.Headers.IfMatch); CopyETags(conditionalDirective.IfNoneMatch, requestMessage.Headers.IfNoneMatch); }
public void WhenDirectiveHasPropertiesSet_ReturnsExpectedNumberOfNewDirectivesWithPropertiesSet() { var dateTime1 = new DateTimeOffset(2015, 10, 1, 1, 2, 3, TimeSpan.Zero); var dateTime2 = new DateTimeOffset(2015, 11, 1, 1, 2, 3, TimeSpan.Zero); var directive = new ConditionalRequestDirective(true); directive.IfModifiedSince = dateTime1; directive.IfUnmodifiedSince = dateTime2; directive.IfMatch.Add(new ETag("ifMatch1", isWeak: false)); directive.IfMatch.Add(new ETag("ifMatch2", isWeak: false)); directive.IfNoneMatch.Add(new ETag("ifNoneMatch1", isWeak: false)); directive.IfNoneMatch.Add(new ETag("ifNoneMatch2", isWeak: false)); var result = directive.SplitETag(2, t => { return new[] { new ETag(t.Value + "copy1", false), new ETag(t.Value + "copy2", false) }; }); Assert.All(result, d => { Assert.NotNull(d); Assert.NotSame(directive, d); Assert.Equal(dateTime1, d.IfModifiedSince); Assert.Equal(dateTime2, d.IfUnmodifiedSince); }); Assert.Collection(result, d1 => { Assert.Equal(new[] { new ETag("ifMatch1copy1", false), new ETag("ifMatch2copy1", false) }, d1.IfMatch.ToArray()); Assert.Equal(new[] { new ETag("ifNoneMatch1copy1", false), new ETag("ifNoneMatch2copy1", false) }, d1.IfNoneMatch.ToArray()); }, d2 => { Assert.Equal(new[] { new ETag("ifMatch1copy2", false), new ETag("ifMatch2copy2", false) }, d2.IfMatch.ToArray()); Assert.Equal(new[] { new ETag("ifNoneMatch1copy2", false), new ETag("ifNoneMatch2copy2", false) }, d2.IfNoneMatch.ToArray()); }); }
public void WhenIfModifiedIsPresent_AndMethodIsUnsafe_ReturnsTrueRegardlessOfLastModified(int? seconds) { var unsafeDirective = new ConditionalRequestDirective(isSafe: false); safeRequestDirective.IfModifiedSince = date; var lastModified = seconds.HasValue ? date.AddSeconds(seconds.Value) : (DateTimeOffset?)null; var result = unsafeDirective.ShouldPerformRequest(CurrentRepresentation.Existing(lastModified)); Assert.True(result); }
public void WhenMatchConditionContainsAnyTag_DoesNotInvokeSplitterFunction_AndReturnsDuplicatesWithAnyTag() { var directive = new ConditionalRequestDirective(true); directive.IfMatch.Add(ETag.Any); directive.IfNoneMatch.Add(ETag.Any); var result = directive.SplitETag(2, t => { throw new Exception("Should not be called"); }); Assert.All(result, d => { Assert.Equal(ETag.Any, d.IfMatch.Single()); Assert.Equal(ETag.Any, d.IfNoneMatch.Single()); }); }
public void WhenSplitterFunctionReturnsUnexpectedNumber_Throws() { var directive = new ConditionalRequestDirective(true); directive.IfNoneMatch.Add(new ETag("abc", false)); var ex = Assert.Throws<InvalidOperationException>(() => directive.SplitETag(2, e => new ETag[3])); Assert.Equal("The tag \"abc\" was split into an unexpected number of components. Expected 2 and received 3.", ex.Message); }
public void WhenSplitterFunctionReturnsNull_Throws() { var directive = new ConditionalRequestDirective(true); directive.IfNoneMatch.Add(new ETag("abc", false)); var ex = Assert.Throws<InvalidOperationException>(() => directive.SplitETag(2, e => null)); Assert.Equal("The result of a tag split cannot be null.", ex.Message); }
/// <summary> /// Duplicates the current instances into <paramref name="splitCount"/> number of copies by splitting the ETags in /// <see cref="IfMatch"/> and <see cref="IfNoneMatch"/> using the <paramref name="etagSplitter"/> function. /// </summary> /// <param name="splitCount">The number of items to return in the result.</param> /// <param name="etagSplitter">The function to use to split a single etag into two or more derived etags. Can return a result where certain positions are <c>null</c>.</param> /// <exception cref="ArgumentOutOfRangeException">When <paramref name="splitCount"/> is less than <c>1</c>.</exception> /// <exception cref="ArgumentNullException">When <paramref name="etagSplitter"/> is <c>null</c>.</exception> /// <exception cref="InvalidOperationException">When <paramref name="etagSplitter"/> returns <c>null</c> or unexpected number of elements.</exception> public ConditionalRequestDirective[] SplitETag(int splitCount, Func<ETag, ETag[]> etagSplitter) { if (splitCount <= 1) throw new ArgumentOutOfRangeException(nameof(splitCount), splitCount, "The count must be greater than 1."); if (etagSplitter == null) throw new ArgumentNullException(nameof(etagSplitter)); var ifMatchSplits = SplitTagsInCollection(splitCount, etagSplitter, IfMatch); var ifNoneMatchSplits = SplitTagsInCollection(splitCount, etagSplitter, IfNoneMatch); var result = new ConditionalRequestDirective[splitCount]; for (int i = 0; i < splitCount; i++) { var directive = new ConditionalRequestDirective(IsSafe); foreach (var s in ifMatchSplits) { directive.IfMatch.Add(s[i]); } directive.IfModifiedSince = this.IfModifiedSince; foreach (var s in ifNoneMatchSplits) { directive.IfNoneMatch.Add(s[i]); } directive.IfUnmodifiedSince = this.IfUnmodifiedSince; result[i] = directive; } return result; }