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) })); }
public DynamicController(IRecordStore store, ICacheRegion <SyndicationFeed> feeds) { _store = store; _feeds = feeds; _example = new T(); ObjectValidator = new DynamicModelValidator(); }
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); }
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); }
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)); }
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); }
public RemoteAddressFilter(ICacheRegion <HttpContext> cache) { _cache = cache; }
public InvalidateCachesWhenRecordAdded(ICacheRegion <SyndicationFeed> cache) { _cache = cache; }
public static string StrongETag <TRegion>(this byte[] data, ICacheRegion <TRegion> cache) { var value = WyHash64.ComputeHash64(data, cache.GetSeed()); return($"\"{value}\""); }
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); }
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}\""); }