protected virtual async Task <CachedProxyContent> GetOrStoreData(string remotePath) { CachedProxyContent cached = memoryCache.Get <CachedProxyContent>(remotePath); if (cached == null) { try { HttpClient client = new HttpClient(); var response = await client.GetAsync(remotePath); if (!response.IsSuccessStatusCode) { return(null); } byte[] innerBuffer = await response.Content.ReadAsByteArrayAsync(); cached = new CachedProxyContent() { Content = ReEncodeImage(innerBuffer, response.Content.Headers.ContentType.MediaType), ContentType = response.Content.Headers.ContentType.MediaType, Etag = innerBuffer.GetHash(), DateGenerated = DateTimeOffset.UtcNow, }; WriteCache(remotePath, cached, response.Headers.CacheControl); } catch (Exception e) { throw new AggregateException($"Cannot fetch data from {remotePath}", e); } } return(cached); }
//private Task WriteCache(string path, string contentType, byte[] buffer, CacheControlHeaderValue headersCacheControl) //{ // var pxy = new CachedProxyContent() // { // Content = buffer, // ContentType = contentType, // Etag = buffer.GetHash() // }; // return WriteCache(path, pxy, headersCacheControl); //} protected void WriteCache(string path, CachedProxyContent proxyContent, CacheControlHeaderValue headersCacheControl) { TimeSpan expire = headersCacheControl?.MaxAge ?? DefaultExpire; proxyContent.Expires = expire; memoryCache.Store(path, proxyContent, expire); }
protected async Task GetFromCacheOrRemote(string[] uriSegments, HttpContext context) { var segments = uriSegments.Skip(1).ToArray(); var uri = RelayDomain + string.Join("/", segments); CachedProxyContent cached = await GetOrStoreData(uri); if (cached == null) { await context.Response.WriteNotFoundAsync(); } else { context.Request.Headers.Add("X-MEMORY-X", "fetched"); await ResizeStoreWrite(cached, context, uriSegments[0], uri); } }
private async Task ResizeStoreWrite(CachedProxyContent cached, HttpContext context, string strSize, string ressourceUri) { try { string xmemValue = "first-pass"; var size = ConvertStrSize(strSize); string resizedCacheKey = $"{ressourceUri}/{strSize}"; var resizedCached = this.memoryCache.Get <CachedProxyContent>(resizedCacheKey); if (resizedCached == null) { var resized = JustResize(cached, size); resizedCached = new CachedProxyContent() { Content = resized, ContentType = cached.ContentType, Etag = resized.GetHash() }; WriteCache(resizedCacheKey, resizedCached, null); } else { xmemValue = "sized"; } var ifNoneMatch = context.Request.Headers["If-none-match"].FirstOrDefault(); context.Response.Headers.Add("Content-Type", resizedCached?.ContentType); context.Response.Headers.Add("Content-Length", (resizedCached?.Content.Length).GetValueOrDefault(0).ToString()); if (resizedCached.Etag.Equals(ifNoneMatch)) { await context.Response.WriteEmptyAsync(304); } else { AddHeaderCache(context.Response.Headers, resizedCached.Etag); context.Response.Headers.Add("X-MEMORY-X", xmemValue); await context.Response.Body.WriteAsync(resizedCached.Content, 0, resizedCached.Content.Length); } } catch (InvalidSegmentSizeException) { await context.Response.WriteEmptyAsync(406); } }
protected virtual async Task GetFromCacheOrRemote(string remotePath, HttpContext context) { CachedProxyContent cached = await GetOrStoreData(remotePath); if (cached == null) { await context.Response.WriteEmptyAsync(404); } else { if (cached.Etag.Equals(context.Request.Headers["If-none-match"].FirstOrDefault())) { await context.Response.WriteEmptyAsync(304); } else { context.Response.Headers.Add("Content-Type", cached.ContentType); AddHeaderCache(context.Response.Headers, cached.Etag); await context.Response.Body.WriteAsync(cached.Content, 0, cached.Content.Length); } } }
private byte[] JustResize(CachedProxyContent cached, (int, int) size)