コード例 #1
0
 public static void AppendETags <TRegion>(this HttpResponse response, ICacheRegion <TRegion> cache, string cacheKey, byte[] stream)
 {
     response.Headers.TryAdd(HeaderNames.ETag, new StringValues(new[]
     {
         cacheKey.WeakETag(true, cache), stream.StrongETag(cache)
     }));
 }
コード例 #2
0
        public DynamicController(IRecordStore store, ICacheRegion <SyndicationFeed> feeds)
        {
            _store   = store;
            _feeds   = feeds;
            _example = new T();

            ObjectValidator = new DynamicModelValidator();
        }
コード例 #3
0
        public static ulong GetSeed <T>(this ICacheRegion <T> cache)
        {
            if (!cache.TryGetValue(nameof(GetSeed), out ulong seed))
            {
                cache.Set(nameof(GetSeed), seed = BitConverter.ToUInt64(Encoding.UTF8.GetBytes(typeof(T).Name), 0));
            }

            return(seed);
        }
コード例 #4
0
        public static bool IfModifiedSince <TRegion>(this HttpRequest request, string cacheKey,
                                                     ICacheRegion <TRegion> cache, out DateTimeOffset?lastModified, out IActionResult result)
        {
            var headers         = request.GetTypedHeaders();
            var ifModifiedSince = headers.IfModifiedSince;

            if (cache.TryGetValue($"{cacheKey}:{HeaderNames.LastModified}", out lastModified) &&
                lastModified <= ifModifiedSince)
            {
                result = new StatusCodeResult((int)HttpStatusCode.NotModified);
                return(false);
            }

            result = default;
            return(true);
        }
コード例 #5
0
        public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
        {
            if (IsMethodCachable(input))
            {
                string regionName = _cacheRegionNameGenerator.CreateRegionName(
                    string.Format("{0}.{1}", input.Target.GetType().FullName, input.MethodBase.Name));

                string cacheKey = _cacheKeyGenerator.CreateCacheKey(input.Inputs);

                ICacheRegion cacheRegion = _cacheProvider.GetRegion(regionName);

                return(cacheRegion.GetOrAdd(cacheKey,
                                            () => getNext.Invoke().Invoke(input, getNext)
                                            ));
            }

            return(getNext()
                   .Invoke(input, getNext));
        }
コード例 #6
0
        public static bool IsContentStale <TRegion>(this HttpRequest request, string cacheKey,
                                                    ICacheRegion <TRegion> cache, out byte[] stream, out DateTimeOffset?lastModified, out IActionResult result)
        {
            // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-None-Match
            if (!request.IfNoneMatch(cacheKey, cache, out stream, out result))
            {
                lastModified = default;
                return(false);
            }

            // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-Modified-Since
            // "When used in combination with If-None-Match, it is ignored, unless the server doesn't support If-None-Match."
            if (!request.IfModifiedSince(cacheKey, cache, out lastModified, out result))
            {
                return(false);
            }

            return(true);
        }
コード例 #7
0
 public RemoteAddressFilter(ICacheRegion <HttpContext> cache)
 {
     _cache = cache;
 }
コード例 #8
0
 public InvalidateCachesWhenRecordAdded(ICacheRegion <SyndicationFeed> cache)
 {
     _cache = cache;
 }
コード例 #9
0
        public static string StrongETag <TRegion>(this byte[] data, ICacheRegion <TRegion> cache)
        {
            var value = WyHash64.ComputeHash64(data, cache.GetSeed());

            return($"\"{value}\"");
        }
コード例 #10
0
        public static bool IfNoneMatch <TRegion>(this HttpRequest request, string cacheKey, ICacheRegion <TRegion> cache,
                                                 out byte[] stream, out IActionResult result)
        {
            var headers = request.GetTypedHeaders();

            foreach (var etag in headers.IfNoneMatch)
            {
                if (etag.IsWeak)
                {
                    if (!etag.Tag.Equals(cacheKey.WeakETag(false, cache)))
                    {
                        continue;
                    }
                    result = new StatusCodeResult((int)HttpStatusCode.NotModified);
                    stream = default;
                    return(false);
                }

                if (!cache.TryGetValue(cacheKey, out stream) || !etag.Tag.Equals(stream.StrongETag(cache)))
                {
                    continue;
                }
                result = new StatusCodeResult((int)HttpStatusCode.NotModified);
                return(false);
            }

            result = default;
            stream = default;
            return(true);
        }
コード例 #11
0
        public static string WeakETag <TRegion>(this string key, bool prefix, ICacheRegion <TRegion> cache)
        {
            var value = WyHash64.ComputeHash64(Encoding.UTF8.GetBytes(key), cache.GetSeed());

            return(prefix ? $"W/\"{value}\"" : $"\"{value}\"");
        }