public void ContentIsNotModified_IfModifiedSince_LastModifiedOverridesDateHeader()
        {
            var utcNow  = DateTimeOffset.UtcNow;
            var sink    = new TestSink();
            var context = TestUtils.CreateTestContext(sink);

            context.CachedResponseHeaders = new HeaderDictionary();

            context.HttpContext.Request.Headers[HeaderNames.IfModifiedSince] = HeaderUtilities.FormatDate(utcNow);

            // Verify modifications in the past succeeds
            context.CachedResponseHeaders[HeaderNames.Date]         = HeaderUtilities.FormatDate(utcNow + TimeSpan.FromSeconds(10));
            context.CachedResponseHeaders[HeaderNames.LastModified] = HeaderUtilities.FormatDate(utcNow - TimeSpan.FromSeconds(10));
            Assert.True(ResponseCachingMiddleware.ContentIsNotModified(context));
            Assert.Single(sink.Writes);

            // Verify modifications at present
            context.CachedResponseHeaders[HeaderNames.Date]         = HeaderUtilities.FormatDate(utcNow + TimeSpan.FromSeconds(10));
            context.CachedResponseHeaders[HeaderNames.LastModified] = HeaderUtilities.FormatDate(utcNow);
            Assert.True(ResponseCachingMiddleware.ContentIsNotModified(context));
            Assert.Equal(2, sink.Writes.Count);

            // Verify modifications in the future fails
            context.CachedResponseHeaders[HeaderNames.Date]         = HeaderUtilities.FormatDate(utcNow - TimeSpan.FromSeconds(10));
            context.CachedResponseHeaders[HeaderNames.LastModified] = HeaderUtilities.FormatDate(utcNow + TimeSpan.FromSeconds(10));
            Assert.False(ResponseCachingMiddleware.ContentIsNotModified(context));

            // Verify logging
            TestUtils.AssertLoggedMessages(
                sink.Writes,
                LoggedMessage.NotModifiedIfModifiedSinceSatisfied,
                LoggedMessage.NotModifiedIfModifiedSinceSatisfied);
        }
        public void ContentIsNotModified_NotConditionalRequest_False()
        {
            var sink    = new TestSink();
            var context = TestUtils.CreateTestContext(sink);

            context.CachedResponseHeaders = new HeaderDictionary();

            Assert.False(ResponseCachingMiddleware.ContentIsNotModified(context));
            Assert.Empty(sink.Writes);
        }
        public void ContentIsNotModified_IfNoneMatch_AnyWithoutETagInResponse_False()
        {
            var sink    = new TestSink();
            var context = TestUtils.CreateTestContext(sink);

            context.CachedResponseHeaders = new HeaderDictionary();
            context.HttpContext.Request.Headers[HeaderNames.IfNoneMatch] = "\"E1\"";

            Assert.False(ResponseCachingMiddleware.ContentIsNotModified(context));
            Assert.Empty(sink.Writes);
        }
        public void ContentIsNotModified_IfNoneMatch_MatchesAtLeastOneValue_True()
        {
            var sink    = new TestSink();
            var context = TestUtils.CreateTestContext(sink);

            context.CachedResponseHeaders = new HeaderDictionary();
            context.CachedResponseHeaders[HeaderNames.ETag] = "\"E2\"";
            context.HttpContext.Request.Headers[HeaderNames.IfNoneMatch] = new string[] { "\"E0\", \"E1\"", "\"E1\", \"E2\"" };

            Assert.True(ResponseCachingMiddleware.ContentIsNotModified(context));
            TestUtils.AssertLoggedMessages(
                sink.Writes,
                LoggedMessage.NotModifiedIfNoneMatchMatched);
        }
        public void  ContentIsNotModified_IfNoneMatch_ExplicitWithMatch_True(EntityTagHeaderValue responseETag, EntityTagHeaderValue requestETag)
        {
            var sink    = new TestSink();
            var context = TestUtils.CreateTestContext(sink);

            context.CachedResponseHeaders = new HeaderDictionary();
            context.CachedResponseHeaders[HeaderNames.ETag] = responseETag.ToString();
            context.HttpContext.Request.Headers[HeaderNames.IfNoneMatch] = requestETag.ToString();

            Assert.True(ResponseCachingMiddleware.ContentIsNotModified(context));
            TestUtils.AssertLoggedMessages(
                sink.Writes,
                LoggedMessage.NotModifiedIfNoneMatchMatched);
        }
        public void ContentIsNotModified_IfNoneMatch_Overrides_IfModifiedSince_ToFalse()
        {
            var utcNow  = DateTimeOffset.UtcNow;
            var sink    = new TestSink();
            var context = TestUtils.CreateTestContext(sink);

            context.CachedResponseHeaders = new HeaderDictionary();

            // This would pass the IfModifiedSince checks
            context.HttpContext.Request.Headers[HeaderNames.IfModifiedSince] = HeaderUtilities.FormatDate(utcNow);
            context.CachedResponseHeaders[HeaderNames.LastModified]          = HeaderUtilities.FormatDate(utcNow - TimeSpan.FromSeconds(10));

            context.HttpContext.Request.Headers[HeaderNames.IfNoneMatch] = "\"E1\"";
            Assert.False(ResponseCachingMiddleware.ContentIsNotModified(context));
            Assert.Empty(sink.Writes);
        }
        public void ContentIsNotModified_IfNoneMatch_Overrides_IfModifiedSince_ToTrue()
        {
            var utcNow  = DateTimeOffset.UtcNow;
            var sink    = new TestSink();
            var context = TestUtils.CreateTestContext(sink);

            context.CachedResponseHeaders = new HeaderDictionary();

            // This would fail the IfModifiedSince checks
            context.HttpContext.Request.Headers[HeaderNames.IfModifiedSince] = HeaderUtilities.FormatDate(utcNow);
            context.CachedResponseHeaders[HeaderNames.LastModified]          = HeaderUtilities.FormatDate(utcNow + TimeSpan.FromSeconds(10));

            context.HttpContext.Request.Headers[HeaderNames.IfNoneMatch] = EntityTagHeaderValue.Any.ToString();
            Assert.True(ResponseCachingMiddleware.ContentIsNotModified(context));
            TestUtils.AssertLoggedMessages(
                sink.Writes,
                LoggedMessage.NotModifiedIfNoneMatchStar);
        }