// Add the given parameter to the list. Remove if date is null.
    private void SetDate(string parameter, DateTimeOffset?date)
    {
        var dateParameter = NameValueHeaderValue.Find(_parameters, parameter);

        if (date == null)
        {
            // Remove parameter
            if (dateParameter != null)
            {
                _parameters !.Remove(dateParameter);
            }
        }
        else
        {
            // Must always be quoted
            var dateString = HeaderUtilities.FormatDate(date.GetValueOrDefault(), quoted: true);
            if (dateParameter != null)
            {
                dateParameter.Value = dateString;
            }
            else
            {
                Parameters.Add(new NameValueHeaderValue(parameter, dateString));
            }
        }
    }
        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 async Task FinalizeCacheHeadersAsync_ResponseValidity_UseSharedMaxAgeIfAvailable()
        {
            var clock = new TestClock
            {
                UtcNow = DateTimeOffset.UtcNow
            };
            var sink       = new TestSink();
            var middleware = TestUtils.CreateTestMiddleware(testSink: sink, options: new ResponseCachingOptions
            {
                SystemClock = clock
            });
            var context = TestUtils.CreateTestContext();

            context.ResponseTime = clock.UtcNow;
            context.HttpContext.Response.Headers[HeaderNames.CacheControl] = new CacheControlHeaderValue()
            {
                MaxAge       = TimeSpan.FromSeconds(12),
                SharedMaxAge = TimeSpan.FromSeconds(13)
            }.ToString();
            context.HttpContext.Response.Headers[HeaderNames.Expires] = HeaderUtilities.FormatDate(clock.UtcNow + TimeSpan.FromSeconds(11));

            await middleware.FinalizeCacheHeadersAsync(context);

            Assert.Equal(TimeSpan.FromSeconds(13), context.CachedResponseValidFor);
            Assert.Empty(sink.Writes);
        }
    public void ReturnsSameResultAsRfc1123String(DateTimeOffset dateTime, bool quoted)
    {
        var formatted = dateTime.ToString(Rfc1123Format);
        var expected  = quoted ? $"\"{formatted}\"" : formatted;
        var actual    = HeaderUtilities.FormatDate(dateTime, quoted);

        Assert.Equal(expected, actual);
    }
Exemple #5
0
    public void ToString_UseDifferentValues_MatchExpectation()
    {
        Assert.Equal("Sat, 31 Jul 2010 15:38:57 GMT",
                     HeaderUtilities.FormatDate(new DateTimeOffset(2010, 7, 31, 15, 38, 57, TimeSpan.Zero)));

        Assert.Equal("Fri, 01 Jan 2010 01:01:01 GMT",
                     HeaderUtilities.FormatDate(new DateTimeOffset(2010, 1, 1, 1, 1, 1, TimeSpan.Zero)));
    }
Exemple #6
0
 /// <inheritdoc />
 public override string ToString()
 {
     if (_entityTag == null)
     {
         return(HeaderUtilities.FormatDate(_lastModified.GetValueOrDefault()));
     }
     return(_entityTag.ToString());
 }
Exemple #7
0
    /// <summary>
    /// Append string representation of this <see cref="SetCookieHeaderValue"/> to given
    /// <paramref name="builder"/>.
    /// </summary>
    /// <param name="builder">
    /// The <see cref="StringBuilder"/> to receive the string representation of this
    /// <see cref="SetCookieHeaderValue"/>.
    /// </param>
    public void AppendToStringBuilder(StringBuilder builder)
    {
        builder.Append(_name.AsSpan());
        builder.Append('=');
        builder.Append(_value.AsSpan());

        if (Expires.HasValue)
        {
            AppendSegment(builder, ExpiresToken, HeaderUtilities.FormatDate(Expires.GetValueOrDefault()));
        }

        if (MaxAge.HasValue)
        {
            AppendSegment(builder, MaxAgeToken, HeaderUtilities.FormatNonNegativeInt64((long)MaxAge.GetValueOrDefault().TotalSeconds));
        }

        if (Domain != null)
        {
            AppendSegment(builder, DomainToken, Domain);
        }

        if (Path != null)
        {
            AppendSegment(builder, PathToken, Path);
        }

        if (Secure)
        {
            AppendSegment(builder, SecureToken, null);
        }

        // Allow for Unspecified (-1) to skip SameSite
        if (SameSite == SameSiteMode.None)
        {
            AppendSegment(builder, SameSiteToken, SameSiteNoneToken);
        }
        else if (SameSite == SameSiteMode.Lax)
        {
            AppendSegment(builder, SameSiteToken, SameSiteLaxToken);
        }
        else if (SameSite == SameSiteMode.Strict)
        {
            AppendSegment(builder, SameSiteToken, SameSiteStrictToken);
        }

        if (HttpOnly)
        {
            AppendSegment(builder, HttpOnlyToken, null);
        }

        foreach (var extension in Extensions)
        {
            AppendSegment(builder, extension, null);
        }
    }
Exemple #8
0
 internal static void SetDate([NotNull] this IHeaderDictionary headers, [NotNull] string name, DateTimeOffset?value)
 {
     if (value.HasValue)
     {
         headers[name] = HeaderUtilities.FormatDate(value.Value);
     }
     else
     {
         headers.Remove(name);
     }
 }
Exemple #9
0
        /// <summary>
        /// Sets date values from a provided ticks value
        /// </summary>
        /// <param name="value">A DateTimeOffset value</param>
        private void SetDateValues(DateTimeOffset value)
        {
            var dateValue = HeaderUtilities.FormatDate(value);
            var dateBytes = new byte[DatePreambleBytes.Length + dateValue.Length];

            DatePreambleBytes.CopyTo(dateBytes);
            Encoding.ASCII.GetBytes(dateValue, dateBytes.AsSpan(DatePreambleBytes.Length));

            var dateValues = new DateHeaderValues(dateBytes, dateValue);

            Volatile.Write(ref _dateValues, dateValues);
        }
        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);
        }
Exemple #11
0
        /// <summary>
        /// Sets date values from a provided ticks value
        /// </summary>
        /// <param name="value">A DateTimeOffset value</param>
        private void SetDateValues(DateTimeOffset value)
        {
            var dateValue = HeaderUtilities.FormatDate(value);
            var dateBytes = new byte[_datePreambleBytes.Length + dateValue.Length];

            Buffer.BlockCopy(_datePreambleBytes, 0, dateBytes, 0, _datePreambleBytes.Length);
            Encoding.ASCII.GetBytes(dateValue, 0, dateValue.Length, dateBytes, _datePreambleBytes.Length);

            var dateValues = new DateHeaderValues
            {
                Bytes  = dateBytes,
                String = dateValue
            };

            Volatile.Write(ref _dateValues, dateValues);
        }
        public async Task FinalizeCacheHeadersAsync_AddsDate_IfNoneSpecified()
        {
            var utcNow     = DateTimeOffset.UtcNow;
            var sink       = new TestSink();
            var middleware = TestUtils.CreateTestMiddleware(testSink: sink);
            var context    = TestUtils.CreateTestContext();

            // ResponseTime is the actual value that's used to set the Date header in FinalizeCacheHeadersAsync
            context.ResponseTime = utcNow;

            Assert.True(StringValues.IsNullOrEmpty(context.HttpContext.Response.Headers[HeaderNames.Date]));

            await middleware.FinalizeCacheHeadersAsync(context);

            Assert.Equal(HeaderUtilities.FormatDate(utcNow), context.HttpContext.Response.Headers[HeaderNames.Date]);
            Assert.Empty(sink.Writes);
        }
        public async Task FinalizeCacheHeadersAsync_DoNotAddDate_IfSpecified()
        {
            var utcNow     = DateTimeOffset.MinValue;
            var sink       = new TestSink();
            var middleware = TestUtils.CreateTestMiddleware(testSink: sink);
            var context    = TestUtils.CreateTestContext();

            context.HttpContext.Response.Headers[HeaderNames.Date] = HeaderUtilities.FormatDate(utcNow);
            context.ResponseTime = utcNow + TimeSpan.FromSeconds(10);

            Assert.Equal(HeaderUtilities.FormatDate(utcNow), context.HttpContext.Response.Headers[HeaderNames.Date]);

            await middleware.FinalizeCacheHeadersAsync(context);

            Assert.Equal(HeaderUtilities.FormatDate(utcNow), context.HttpContext.Response.Headers[HeaderNames.Date]);
            Assert.Empty(sink.Writes);
        }
        public async Task PreconditionIfUnmodifiedSinceSuccessEqualTest()
        {
            // Arrange
            Client.DefaultRequestHeaders.Add("If-Unmodified-Since", HeaderUtilities.FormatDate(LastModified));

            // Act
            HttpResponseMessage response = await Client.GetAsync("/file/physical/true/true");

            string responseString = await response.Content.ReadAsStringAsync();

            // Assert
            Assert.Equal(HttpStatusCode.OK, response.StatusCode);
            Assert.Equal("0123456789abcdefghijklmnopgrstuvwxyzABCDEFGHIJKLMNOPGRSTUVWXYZ", responseString);
            Assert.Equal("bytes", response.Headers.AcceptRanges.ToString());
            Assert.Equal(EntityTag, response.Headers.ETag);
            Assert.Null(response.Content.Headers.ContentRange);
        }
        public async Task PreconditionIfUnmodifiedSinceFailTest()
        {
            // Arrange
            Client.DefaultRequestHeaders.Add("If-Unmodified-Since", HeaderUtilities.FormatDate(LastModified.AddSeconds(-1)));

            // Act
            HttpResponseMessage response = await Client.GetAsync("/file/physical/true/true");

            string responseString = await response.Content.ReadAsStringAsync();

            // Assert
            Assert.Equal(HttpStatusCode.PreconditionFailed, response.StatusCode);
            Assert.Equal(string.Empty, responseString);
            Assert.NotEqual("bytes", response.Headers.AcceptRanges.ToString());
            Assert.Equal(EntityTag, response.Headers.ETag);
            Assert.Null(response.Content.Headers.ContentRange);
        }
        public async Task PreconditionIfUnmodifiedSinceSuccessEqualTest()
        {
            // Arrange
            this.Client.DefaultRequestHeaders.Add("If-Unmodified-Since", HeaderUtilities.FormatDate(this.LastModified));

            // Act
            HttpResponseMessage response = await this.Client.GetAsync("/test/file/physical/true/true");

            string responseString = await response.Content.ReadAsStringAsync();

            // Assert
            Assert.AreEqual(HttpStatusCode.OK, response.StatusCode, "StatusCode != OK");
            Assert.AreEqual("0123456789abcdefghijklmnopgrstuvwxyzABCDEFGHIJKLMNOPGRSTUVWXYZ", responseString, "no full file");
            Assert.AreEqual("bytes", response.Headers.AcceptRanges.ToString(), "AcceptRanges != bytes");
            Assert.AreEqual(this.EntityTag, response.Headers.ETag, "ETag != EntityTag");
            Assert.IsNull(response.Content.Headers.ContentRange, "Content-Range != null");
            Assert.AreEqual("attachment", response.Content.Headers.ContentDisposition.DispositionType, "DispositionType != attachment");
        }
Exemple #17
0
        public async Task PreconditionIfUnmodifiedSinceFailTest()
        {
            // Arrange
            this.Client.DefaultRequestHeaders.Add("If-Unmodified-Since", HeaderUtilities.FormatDate(this.LastModified.AddSeconds(-1)));

            // Act
            HttpResponseMessage response = await this.Client.GetAsync("/test/file/physical/true/true");

            string responseString = await response.Content.ReadAsStringAsync();

            // Assert
            Assert.AreEqual(HttpStatusCode.PreconditionFailed, response.StatusCode, "StatusCode != PreconditionFailed");
            Assert.AreEqual(string.Empty, responseString, "response is not empty");
            Assert.AreNotEqual("bytes", response.Headers.AcceptRanges.ToString(), "AcceptRanges == bytes");
            Assert.AreEqual(this.EntityTag, response.Headers.ETag, "ETag != EntityTag");
            Assert.IsNull(response.Content.Headers.ContentRange, "Content-Range != null");
            Assert.AreEqual("attachment", response.Content.Headers.ContentDisposition.DispositionType, "DispositionType != attachment");
        }
        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);
        }
        public void IsResponseCacheable_NoExpiryRequirements_IsAllowed()
        {
            var sink    = new TestSink();
            var context = TestUtils.CreateTestContext(sink);

            context.HttpContext.Response.StatusCode           = StatusCodes.Status200OK;
            context.HttpContext.Response.Headers.CacheControl = new CacheControlHeaderValue()
            {
                Public = true
            }.ToString();

            var utcNow = DateTimeOffset.UtcNow;

            context.HttpContext.Response.Headers.Date = HeaderUtilities.FormatDate(utcNow);
            context.ResponseTime = DateTimeOffset.MaxValue;

            Assert.True(new ResponseCachingPolicyProvider().IsResponseCacheable(context));
            Assert.Empty(sink.Writes);
        }
        public void IsResponseCacheable_SharedMaxAgeOverridesMaxAge_ToAllowed()
        {
            var utcNow  = DateTimeOffset.UtcNow;
            var sink    = new TestSink();
            var context = TestUtils.CreateTestContext(sink);

            context.HttpContext.Response.StatusCode           = StatusCodes.Status200OK;
            context.HttpContext.Response.Headers.CacheControl = new CacheControlHeaderValue()
            {
                Public       = true,
                MaxAge       = TimeSpan.FromSeconds(10),
                SharedMaxAge = TimeSpan.FromSeconds(15)
            }.ToString();
            context.HttpContext.Response.Headers.Date = HeaderUtilities.FormatDate(utcNow);
            context.ResponseTime = utcNow + TimeSpan.FromSeconds(11);

            Assert.True(new ResponseCachingPolicyProvider().IsResponseCacheable(context));
            Assert.Empty(sink.Writes);
        }
    public async Task IsResponseCacheable_NoExpiryRequirements_IsAllowed()
    {
        var sink    = new TestSink();
        var context = TestUtils.CreateTestContext(testSink: sink);

        context.HttpContext.Response.StatusCode = StatusCodes.Status200OK;

        var utcNow = DateTimeOffset.UtcNow;

        context.HttpContext.Response.Headers.Date = HeaderUtilities.FormatDate(utcNow);
        context.ResponseTime = DateTimeOffset.MaxValue;

        var policy = new OutputCachePolicyBuilder().Build();
        await policy.ServeResponseAsync(context, default);

        Assert.True(context.AllowCacheStorage);
        Assert.True(context.AllowCacheLookup);
        Assert.Empty(sink.Writes);
    }
        public void IsCachedEntryFresh_MaxAgeOverridesExpiry_ToFresh()
        {
            var utcNow  = DateTimeOffset.UtcNow;
            var sink    = new TestSink();
            var context = TestUtils.CreateTestContext(sink);

            context.CachedEntryAge        = TimeSpan.FromSeconds(9);
            context.ResponseTime          = utcNow + context.CachedEntryAge;
            context.CachedResponseHeaders = new HeaderDictionary();
            context.CachedResponseHeaders[HeaderNames.CacheControl] = new CacheControlHeaderValue()
            {
                Public = true,
                MaxAge = TimeSpan.FromSeconds(10)
            }.ToString();
            context.HttpContext.Response.Headers.Expires = HeaderUtilities.FormatDate(utcNow);

            Assert.True(new ResponseCachingPolicyProvider().IsCachedEntryFresh(context));
            Assert.Empty(sink.Writes);
        }
        public async Task FinalizeCacheHeadersAsync_AddsDate_IfNoneSpecified()
        {
            var clock = new TestClock
            {
                UtcNow = DateTimeOffset.UtcNow
            };
            var sink       = new TestSink();
            var middleware = TestUtils.CreateTestMiddleware(testSink: sink, options: new ResponseCachingOptions
            {
                SystemClock = clock
            });
            var context = TestUtils.CreateTestContext();

            Assert.True(StringValues.IsNullOrEmpty(context.HttpContext.Response.Headers[HeaderNames.Date]));

            await middleware.FinalizeCacheHeadersAsync(context);

            Assert.Equal(HeaderUtilities.FormatDate(clock.UtcNow), context.HttpContext.Response.Headers[HeaderNames.Date]);
            Assert.Empty(sink.Writes);
        }
Exemple #24
0
        public async Task PreconditionIfModifiedSinceSuccessPutTest()
        {
            // Arrange
            Client.DefaultRequestHeaders.Add("If-Modified-Since", HeaderUtilities.FormatDate(LastModified.AddSeconds(-1)));

            // Act
            HttpResponseMessage response = await Client.PutAsync("/file/file", new StringContent(string.Empty));

            response.EnsureSuccessStatusCode();

            string responseString = await response.Content.ReadAsStringAsync();

            // Assert
            Assert.Equal(HttpStatusCode.OK, response.StatusCode);
            Assert.Equal("0123456789abcdefghijklmnopgrstuvwxyzABCDEFGHIJKLMNOPGRSTUVWXYZ", responseString);
            Assert.Equal("bytes", response.Headers.AcceptRanges.ToString());
            Assert.Equal(EntityTag, response.Headers.ETag);
            Assert.Null(response.Content.Headers.ContentRange);
            Assert.Equal("attachment", response.Content.Headers.ContentDisposition.DispositionType);
        }
        public void IsCachedEntryFresh_AtExpiry_IsNotFresh()
        {
            var utcNow  = DateTimeOffset.UtcNow;
            var sink    = new TestSink();
            var context = TestUtils.CreateTestContext(sink);

            context.ResponseTime          = utcNow;
            context.CachedEntryAge        = TimeSpan.Zero;
            context.CachedResponseHeaders = new HeaderDictionary();
            context.CachedResponseHeaders[HeaderNames.CacheControl] = new CacheControlHeaderValue()
            {
                Public = true
            }.ToString();
            context.CachedResponseHeaders[HeaderNames.Expires] = HeaderUtilities.FormatDate(utcNow);

            Assert.False(new ResponseCachingPolicyProvider().IsCachedEntryFresh(context));
            TestUtils.AssertLoggedMessages(
                sink.Writes,
                LoggedMessage.ExpirationExpiresExceeded);
        }
        public void IsResponseCacheable_MaxAgeOverridesExpiry_ToNotAllowed()
        {
            var utcNow  = DateTimeOffset.UtcNow;
            var sink    = new TestSink();
            var context = TestUtils.CreateTestContext(sink);

            context.HttpContext.Response.StatusCode           = StatusCodes.Status200OK;
            context.HttpContext.Response.Headers.CacheControl = new CacheControlHeaderValue()
            {
                Public = true,
                MaxAge = TimeSpan.FromSeconds(10)
            }.ToString();
            context.HttpContext.Response.Headers.Expires = HeaderUtilities.FormatDate(utcNow);
            context.HttpContext.Response.Headers.Date    = HeaderUtilities.FormatDate(utcNow);
            context.ResponseTime = utcNow + TimeSpan.FromSeconds(10);

            Assert.False(new ResponseCachingPolicyProvider().IsResponseCacheable(context));
            TestUtils.AssertLoggedMessages(
                sink.Writes,
                LoggedMessage.ExpirationMaxAgeExceeded);
        }
        internal static void SetDate(this IHeaderDictionary headers, string name, DateTimeOffset?value)
        {
            if (headers == null)
            {
                throw new ArgumentNullException(nameof(headers));
            }

            if (name == null)
            {
                throw new ArgumentNullException(nameof(name));
            }

            if (value.HasValue)
            {
                headers[name] = HeaderUtilities.FormatDate(value.Value);
            }
            else
            {
                headers.Remove(name);
            }
        }
        public async Task PreconditionIfRangeLastModifiedEqualTest()
        {
            // Arrange
            Client.DefaultRequestHeaders.Add("Range", "bytes=1-1");
            Client.DefaultRequestHeaders.Add("If-Range", HeaderUtilities.FormatDate(LastModified));

            // Act
            HttpResponseMessage response = await Client.GetAsync("/file/physical/true/true");

            response.EnsureSuccessStatusCode();

            string responseString = await response.Content.ReadAsStringAsync();

            // Assert
            Assert.Equal(HttpStatusCode.PartialContent, response.StatusCode);
            Assert.Equal("1", responseString);
            Assert.Equal("bytes", response.Headers.AcceptRanges.ToString());
            Assert.Equal(EntityTag, response.Headers.ETag);
            Assert.NotNull(response.Content.Headers.ContentRange);
            Assert.Equal("bytes 1-1/62", response.Content.Headers.ContentRange.ToString());
        }
        public async Task IfUnmodifiedSinceComparison_OnlyUsesWholeSeconds(DateTimeOffset ifUnmodifiedSince, int expectedStatusCode)
        {
            // Arrange
            var httpContext = GetHttpContext();

            httpContext.Request.Headers[HeaderNames.IfUnmodifiedSince] = HeaderUtilities.FormatDate(ifUnmodifiedSince);
            var actionContext = CreateActionContext(httpContext);
            // Represents 4/9/2018 11:24:22 AM +00:00
            // Ticks rounded down to seconds: 636588698620000000
            var ticks  = 636588698625969382;
            var result = new EmptyFileResult("application/test")
            {
                LastModified = new DateTimeOffset(ticks, TimeSpan.Zero)
            };

            // Act
            await result.ExecuteResultAsync(actionContext);

            // Assert
            Assert.Equal(expectedStatusCode, httpContext.Response.StatusCode);
        }
Exemple #30
0
        public void FinalizeCacheHeadersAsync_ResponseValidity_UseExpiryIfAvailable()
        {
            var clock = new TestClock
            {
                UtcNow = DateTimeOffset.MinValue
            };
            var sink       = new TestSink();
            var middleware = TestUtils.CreateTestMiddleware(testSink: sink, options: new ResponseCachingOptions
            {
                SystemClock = clock
            });
            var context = TestUtils.CreateTestContext();

            context.ResponseTime = clock.UtcNow;
            context.HttpContext.Response.Headers.Expires = HeaderUtilities.FormatDate(clock.UtcNow + TimeSpan.FromSeconds(11));

            middleware.FinalizeCacheHeaders(context);

            Assert.Equal(TimeSpan.FromSeconds(11), context.CachedResponseValidFor);
            Assert.Empty(sink.Writes);
        }