public static CacheResponseDirective ReadCacheResponseDirective(this HttpResponseMessage responseMessage)
        {
            var directive = new CacheResponseDirective();
            var cacheControl = responseMessage.Headers.CacheControl;

            if (cacheControl != null)
            {
                directive.MustRevalidate = cacheControl.MustRevalidate;
                directive.NoCache = cacheControl.NoCache;
                // TODO deal with no-cache field names?
                directive.NoStore = cacheControl.NoStore;
                // TODO deal with no-transform?
                directive.Public = cacheControl.Public;
                directive.Private = cacheControl.Private;
                // TODO deal with private field names?
                // TODO deal with proxy-revalidate?
                directive.MaxAge = cacheControl.MaxAge;
                directive.SharedMaxAge = cacheControl.SharedMaxAge;
                // TODO deal with cacheControl.Extensions
            }
            // TODO handle Expires, Age, Date

            directive.LastModified = responseMessage.Content?.Headers.LastModified;
            directive.ETag = responseMessage.Headers.ETag.ToETag();

            // TODO handle responseMessage.Headers.Vary;
            // TODO handle responseMessage.Headers.Warning;

            return directive;
        }
            public void AppliesDirectiveToResponse()
            {
                var dateTime1 = new DateTimeOffset(2015, 10, 20, 15, 42, 31, TimeSpan.Zero);
                var response = new TestableHttpResponse();
                var cacheResponseDirective = new CacheResponseDirective();
                cacheResponseDirective.LastModified = dateTime1;
                cacheResponseDirective.MaxAge = TimeSpan.FromMinutes(15);
                cacheResponseDirective.MustRevalidate = true;
                cacheResponseDirective.NoCache = true;
                cacheResponseDirective.NoStore = true;
                cacheResponseDirective.Private = true;
                cacheResponseDirective.Public = true;
                cacheResponseDirective.SharedMaxAge = TimeSpan.FromHours(1);

                DnxExtensions.ApplyCacheResponseDirective(response, cacheResponseDirective);

                var responseHeaders = response.GetTypedHeaders();
                Assert.NotNull(responseHeaders.CacheControl);
                Assert.Equal(dateTime1, responseHeaders.LastModified);
                Assert.Equal(TimeSpan.FromMinutes(15), responseHeaders.CacheControl.MaxAge);
                Assert.True(responseHeaders.CacheControl.MustRevalidate);
                Assert.True(responseHeaders.CacheControl.NoCache);
                Assert.True(responseHeaders.CacheControl.NoStore);
                Assert.True(responseHeaders.CacheControl.Private);
                Assert.True(responseHeaders.CacheControl.Public);
                Assert.Equal(TimeSpan.FromHours(1), responseHeaders.CacheControl.SharedMaxAge);
            }
Exemple #3
0
        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();
        }
        /// <summary>
        /// Combines two <see cref="CacheResponseDirective"/> instances into a new one, using the most restrictive value from each pair of input properties.
        /// </summary>
        /// <remarks>
        /// <see cref="LastModified"/> is only set if both inputs specify a value.
        /// <see cref="Public"/> is only set if the result does not have <see cref="Private"/> set.
        /// </remarks>
        public static CacheResponseDirective Combine(CacheResponseDirective a, CacheResponseDirective b, Func<ETag, ETag, ETag> etagCombiner = null)
        {
            var result = new CacheResponseDirective();
            if (a.LastModified.HasValue && b.LastModified.HasValue)
            {
                // Only set LastModified if both sides specify it. If either side does not specify then LastModified of the combined result is indeterminate.
                result.LastModified = Max(a.LastModified, b.LastModified);
            }
            result.MaxAge = Min(a.MaxAge, b.MaxAge);
            result.MustRevalidate = a.MustRevalidate || b.MustRevalidate;
            result.NoCache = a.NoCache || b.NoCache;
            result.NoStore = a.NoStore || b.NoStore;
            result.Private = a.Private || b.Private;
            result.Public = !result.Private && (a.Public || b.Public); // TODO: Is this correct? Does it make sense for a response to be marked both as Public and Private?
            result.SharedMaxAge = Min(a.SharedMaxAge, b.SharedMaxAge);

            if (etagCombiner != null && a.ETag != null && b.ETag != null)
                result.ETag = etagCombiner(a.ETag, b.ETag);

            return result;
        }