Esempio n. 1
0
        public SterlingCacheContentTest()
        {
            primaryKey   = new PrimaryCacheKey("https://localhost/test", "POST");
            secondaryKey = TestHelper.CreateContentKey();
            entry        = new CacheEntry(primaryKey, new string[0]);
            response     = new HttpResponseMessage(HttpStatusCode.BadRequest)
            {
                Content = new StringContent("42")
            };

            response.Headers.CacheControl = new CacheControlHeaderValue()
            {
                MaxAge = TimeSpan.FromHours(1)
            };
            response.Content.Headers.ContentLanguage.Add("de");

            // We need to add this here, since the header will be added during reconstruction in any case
            // That is (hopefully) not a problem, however, since it does not contribute to the "content" as such.
            response.Content.Headers.ContentLength = 2;

            content = new CacheContent()
            {
                PrimaryKey = primaryKey,
                ContentKey = secondaryKey,
                Response   = response
            };
        }
        public async Task UpdateEntryAsync(CacheContent content)
        {
            CacheEntry entry = content.CacheEntry;

            InMemmoryCacheEntry inMemoryCacheEntry = null;

            if (!_responseCache.ContainsKey(entry.Key))
            {
                inMemoryCacheEntry = new InMemmoryCacheEntry(entry);
                lock (syncRoot)
                {
                    _responseCache[entry.Key] = inMemoryCacheEntry;
                }
            }
            else
            {
                inMemoryCacheEntry = _responseCache[entry.Key];
            }
            
            var newContent = await CloneAsync(content);
            lock (syncRoot)
            {
                inMemoryCacheEntry.Responses[content.Key] = newContent;
            }
        }
Esempio n. 3
0
        public void Creation_fails_for_invalid_CacheContent()
        {
            // Arrange
            var primaryKey   = new PrimaryCacheKey("https://localhost/test", "POST");
            var secondaryKey = TestHelper.CreateContentKey();
            var entry        = new CacheEntry(primaryKey, new string[0]);
            var response     = new HttpResponseMessage();

            var noPrimary = new CacheContent()
            {
                ContentKey = secondaryKey,
                Response   = response
            };

            var noContentKey = new CacheContent()
            {
                Response = response
            };

            var noResponse = new CacheContent()
            {
                PrimaryKey = primaryKey,
                ContentKey = secondaryKey,
            };

            // Act

            // Assert
            Assert.Throws <ArgumentException>(() => SterlingCacheContent.CreateAsync(noPrimary).Result);
            Assert.Throws <ArgumentException>(() => SterlingCacheContent.CreateAsync(noContentKey).Result);
            Assert.Throws <ArgumentException>(() => SterlingCacheContent.CreateAsync(noResponse).Result);
        }
 public static CacheQueryResult Revalidate(CacheContent cacheContent)
 {
     return(new CacheQueryResult()
     {
         Status = CacheStatus.Revalidate,
         SelectedVariant = cacheContent
     });
 }
 public static CacheQueryResult ReturnStored(CacheContent cacheContent)
 {
     return(new CacheQueryResult()
     {
         Status = CacheStatus.ReturnStored,
         SelectedVariant = cacheContent
     });
 }
        private async Task<CacheContent> CloneAsync(CacheContent cacheContent)
        {
            var newResponse = await new HttpMessageContent(cacheContent.Response).ReadAsHttpResponseMessageAsync();

            var newContent = new CacheContent()
            {
                CacheEntry = cacheContent.CacheEntry,
                Key = cacheContent.Key,
                Expires = cacheContent.Expires,
                HasValidator = cacheContent.HasValidator,
                CacheControl = cacheContent.CacheControl,
                Response = newResponse
            };
            return newContent;
        }
Esempio n. 7
0
        public async Task Creation_does_not_fail_with_empty_message()
        {
            // Arrange
            var primaryKey   = new PrimaryCacheKey("https://localhost/test", "POST");
            var secondaryKey = TestHelper.CreateContentKey();
            var entry        = new CacheEntry(primaryKey, new string[0]);
            var response     = new HttpResponseMessage();

            var content = new CacheContent()
            {
                PrimaryKey = primaryKey,
                ContentKey = secondaryKey,
                Response   = response
            };

            // Act
            var sterlingContent = await SterlingCacheContent.CreateAsync(content);

            // Assert
            Assert.NotNull(sterlingContent);
        }
        public async Task Creation_does_not_fail_with_empty_message()
        {
            // Arrange
            var primaryKey = new PrimaryCacheKey("https://localhost/test", "POST");
            var secondaryKey = TestHelper.CreateContentKey();
            var entry = new CacheEntry(primaryKey, new string[0]);
            var response = new HttpResponseMessage();

            var content = new CacheContent()
            {
                PrimaryKey = primaryKey,
                ContentKey = secondaryKey,                
                Response = response
            };

            // Act
            var sterlingContent = await SterlingCacheContent.CreateAsync(content);

            // Assert
            Assert.NotNull(sterlingContent);
        }
        public static async Task <SterlingCacheContent> CreateAsync(CacheContent content)
        {
            Contract.Requires <ArgumentException>(content.PrimaryKey != null, "content");
            Contract.Requires <ArgumentException>(content.ContentKey != null, "content");
            Contract.Requires <ArgumentException>(content.Response != null, "content");

            var sterlingContent = new SterlingCacheContent();

            //if (content.CacheEntry is SterlingCacheEntry)
            //{
            //    sterlingContent.CacheEntry = content.CacheEntry as SterlingCacheEntry;
            //}
            //else
            //{
            //    sterlingContent.CacheEntry = new SterlingCacheEntry(content.CacheEntry);
            //}

            //sterlingContent.Key = content.Key;

            //var response = content.Response;

            //sterlingContent.StatusCode = response.StatusCode;

            //foreach (var keyValue in response.Headers)
            //{
            //    sterlingContent.ResponseHeaders.Add(keyValue.Key, keyValue.Value);
            //}

            //if (response.Content != null)
            //{
            //    foreach (var keyValue in response.Content.Headers)
            //    {
            //        sterlingContent.ContentHeaders.Add(keyValue.Key, keyValue.Value);
            //    }

            //    sterlingContent.Content = await response.Content.ReadAsByteArrayAsync();
            //}

            return(sterlingContent);
        }
        public static async Task<SterlingCacheContent> CreateAsync(CacheContent content)
        {
            Contract.Requires<ArgumentException>(content.PrimaryKey != null, "content");
            Contract.Requires<ArgumentException>(content.ContentKey != null, "content");
            Contract.Requires<ArgumentException>(content.Response != null, "content");

            var sterlingContent = new SterlingCacheContent();

            //if (content.CacheEntry is SterlingCacheEntry)
            //{
            //    sterlingContent.CacheEntry = content.CacheEntry as SterlingCacheEntry;
            //}
            //else
            //{
            //    sterlingContent.CacheEntry = new SterlingCacheEntry(content.CacheEntry);
            //}

            //sterlingContent.Key = content.Key;

            //var response = content.Response;

            //sterlingContent.StatusCode = response.StatusCode;

            //foreach (var keyValue in response.Headers)
            //{
            //    sterlingContent.ResponseHeaders.Add(keyValue.Key, keyValue.Value);
            //}

            //if (response.Content != null)
            //{
            //    foreach (var keyValue in response.Content.Headers)
            //    {
            //        sterlingContent.ContentHeaders.Add(keyValue.Key, keyValue.Value);
            //    }

            //    sterlingContent.Content = await response.Content.ReadAsByteArrayAsync();
            //}

            return sterlingContent;
        }
Esempio n. 11
0
    public void LoadTexture(string path_, Action <Texture> cb_)
    {
        Texture tex = null;

        if (_cache.ContainsKey(path_))
        {
            _cache[path_].count += 1;
            cb_(_cache[path_].tex);
            return;
        }
        tex = Resources.Load(path_) as Texture;
        if (null == tex)
        {
            tex = _defaultTex;
        }
        var content = new CacheContent();

        content.count = 0;
        content.path  = path_;
        content.tex   = tex;
        _cache[path_] = content;
        cb_(tex);
    }
        public SterlingCacheContentTest()
        {
            primaryKey = new PrimaryCacheKey("https://localhost/test", "POST");
            secondaryKey = TestHelper.CreateContentKey();
            entry = new CacheEntry(primaryKey, new string[0]);
            response = new HttpResponseMessage(HttpStatusCode.BadRequest)
            {
                Content = new StringContent("42")
            };

            response.Headers.CacheControl = new CacheControlHeaderValue() { MaxAge = TimeSpan.FromHours(1) };
            response.Content.Headers.ContentLanguage.Add("de");

            // We need to add this here, since the header will be added during reconstruction in any case
            // That is (hopefully) not a problem, however, since it does not contribute to the "content" as such. 
            response.Content.Headers.ContentLength = 2;

            content = new CacheContent()
            {
                PrimaryKey = primaryKey,
                ContentKey = secondaryKey,
                Response = response
            };
        }
Esempio n. 13
0
 public void Add(CacheContent item)
 {
     _content.Add(item);
 }
Esempio n. 14
0
 public Task UpdateEntryAsync(CacheContent content)
 {
     throw new NotImplementedException();
 }
Esempio n. 15
0
        private async Task Cache(HttpContext context)
        {
            //bool useMinification = _options.EnableMinification && _minificationManagers.Count > 0;
            //bool useCompression = _options.EnableCompression && _compressionManager != null;
            var useMinification = _options.EnableMinification;
            var useCompression  = _options.EnableCompression;
            var cacheSetting    = _options.Setting;
            var currentUrl      = context.Request.Path.Value;
            var accept          = $"{context.Request.Headers["Accept"]}";
            var isHtml          = context.Request.Method == "GET" && !string.IsNullOrEmpty(accept) && accept.Contains("text/html") && context.Request.Headers["X-Requested-With"] != "XMLHttpRequest";

            #region  做缓存处理
            if (!isHtml || (!useMinification && !useCompression) || !_options.EnableCache || !cacheSetting.IgnorePages.Contains(currentUrl))
            {
                await _next.Invoke(context);

                return;
            }
            #endregion

            var cachePage = cacheSetting.CachePages.FirstOrDefault(a => a.Url == currentUrl);
            if (cachePage == null)
            {
                cachePage = new CachePage()
                {
                    Url = currentUrl
                }
            }
            ;
            if (cachePage.CacheTime == 0)
            {
                cachePage.CacheTime = cacheSetting.CacheTime;
            }
            var cacheKey = GetKey(context.Request, cachePage.VaryByParams);

            #region 判断缓存是否存在
            var cacheContent = _cacheService.Get <CacheContent>(cacheKey);
            if (cacheContent != null)
            {
                context.Response.Headers.Add("C-Cache", "Hit");
                if (cacheContent.Headers != null && cacheContent.Headers.Count > 0)
                {
                    foreach (var ch in cacheContent.Headers)
                    {
                        context.Response.Headers.Add(ch.Key, ch.Value);
                    }
                }
                await context.Response.Body.WriteAsync(cacheContent.Content, 0, cacheContent.Content.Length);

                return;
            }
            #endregion

            HttpRequest  request  = context.Request;
            HttpResponse response = context.Response;

            using (var cachedStream = new MemoryStream())
            {
                Stream originalStream = response.Body;
                response.Body = cachedStream;

                try
                {
                    await _next.Invoke(context);
                }
                catch (Exception)
                {
                    response.Body = originalStream;
                    cachedStream.Clear();
                    throw;
                }

                byte[] cachedBytes     = cachedStream.ToArray();
                int    cachedByteCount = cachedBytes.Length;
                bool   isProcessed     = false;

                response.Body = originalStream;
                cachedStream.Clear();

                if (cachedByteCount == 0)
                {
                    return;
                }

                if (response.StatusCode == 200)
                {
                    string   httpMethod  = request.Method;
                    string   contentType = response.ContentType;
                    string   mediaType   = null;
                    Encoding encoding    = null;
                    if (contentType != null)
                    {
                        MediaTypeHeaderValue mediaTypeHeader;

                        if (MediaTypeHeaderValue.TryParse(contentType, out mediaTypeHeader))
                        {
                            mediaType = mediaTypeHeader.MediaType.Value;
                            encoding  = mediaTypeHeader.Encoding;
                        }
                    }
                    encoding = encoding ?? Encoding.GetEncoding(0);

                    string            content          = encoding.GetString(cachedBytes);
                    string            processedContent = content;
                    IHeaderDictionary responseHeaders  = response.Headers;
                    bool isEncodedContent = responseHeaders.IsEncodedContent();
                    Action <string, string> appendHttpHeader = (key, value) =>
                    {
                        responseHeaders.Append(key, new StringValues(value));
                    };

                    #region Html压缩
                    if (useMinification && _options.IsAllowableResponseSize(cachedByteCount))
                    {
                        var htmlMinifier = new HtmlMinifier();
                        var result       = htmlMinifier.Minify(processedContent);
                        if (result.Errors.Count == 0)
                        {
                            processedContent = result.MinifiedContent;
                            isProcessed      = true;
                        }
                        //foreach (IMarkupMinificationManager minificationManager in _minificationManagers)
                        //{
                        //    if (minificationManager.IsSupportedHttpMethod(httpMethod)
                        //        && mediaType != null && minificationManager.IsSupportedMediaType(mediaType)
                        //        && minificationManager.IsProcessablePage(currentUrl))
                        //    {
                        //        if (isEncodedContent)
                        //        {
                        //            throw new InvalidOperationException(
                        //                string.Format(
                        //                    AspNetCommonStrings.MarkupMinificationIsNotApplicableToEncodedContent,
                        //                    responseHeaders["Content-Encoding"]
                        //                )
                        //            );
                        //        }

                        //        IMarkupMinifier minifier = minificationManager.CreateMinifier();

                        //        MarkupMinificationResult minificationResult = minifier.Minify(processedContent,
                        //            currentUrl, encoding, minificationManager.GenerateStatistics);
                        //        if (minificationResult.Errors.Count == 0)
                        //        {
                        //            processedContent = minificationResult.MinifiedContent;
                        //            isProcessed = true;
                        //        }
                        //    }

                        //    if (isProcessed)
                        //    {
                        //        break;
                        //    }
                        //}
                    }
                    #endregion

                    byte[] processedBytes;
                    if (isProcessed)
                    {
                        processedBytes = encoding.GetBytes(processedContent);
                    }
                    else
                    {
                        processedBytes = cachedBytes;
                    }
                    #region GZip压缩
                    if (useCompression && !isEncodedContent)
                    {
                        string   acceptEncoding = request.Headers["Accept-Encoding"];
                        string[] encodingTokens = acceptEncoding
                                                  .Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
                                                  .Select(e => e.Trim().ToLowerInvariant())
                                                  .ToArray();
                        ICompressor compressor = null;
                        foreach (var et in encodingTokens)
                        {
                            if (et == EncodingTokenConstants.Deflate)
                            {
                                compressor = new DeflateCompressor(new DeflateCompressionSettings()
                                {
                                    Level = System.IO.Compression.CompressionLevel.Fastest
                                });
                                break;
                            }
                            else if (et == EncodingTokenConstants.GZip)
                            {
                                compressor = new GZipCompressor(new GZipCompressionSettings()
                                {
                                    Level = System.IO.Compression.CompressionLevel.Fastest
                                });
                            }
                        }
                        if (compressor != null)
                        {
                            using (var inputStream = new MemoryStream(processedBytes))
                                using (var outputStream = new MemoryStream())
                                {
                                    using (Stream compressedStream = compressor.Compress(outputStream))
                                    {
                                        await inputStream.CopyToAsync(compressedStream);
                                    }
                                    byte[] compressedBytes = outputStream.ToArray();
                                    processedBytes = compressedBytes;
                                    outputStream.Clear();
                                    inputStream.Clear();
                                    responseHeaders["Content-Length"] = compressedBytes.Length.ToString();
                                    compressor.AppendHttpHeaders(appendHttpHeader);
                                    await originalStream.WriteAsync(compressedBytes, 0, compressedBytes.Length);
                                }
                        }
                        //using (var inputStream = new MemoryStream(processedBytes))
                        //using (var outputStream = new MemoryStream())
                        //{
                        //    string acceptEncoding = request.Headers["Accept-Encoding"];
                        //    ICompressor compressor = _compressionManager.CreateCompressor(acceptEncoding);

                        //    using (Stream compressedStream = compressor.Compress(outputStream))
                        //    {
                        //        await inputStream.CopyToAsync(compressedStream);
                        //    }

                        //    byte[] compressedBytes = outputStream.ToArray();
                        //    processedBytes = compressedBytes;
                        //    int compressedByteCount = compressedBytes.Length;

                        //    outputStream.Clear();
                        //    inputStream.Clear();

                        //    responseHeaders["Content-Length"] = compressedByteCount.ToString();
                        //    compressor.AppendHttpHeaders(appendHttpHeader);
                        //    await originalStream.WriteAsync(compressedBytes, 0, compressedByteCount);
                        //}
                        isProcessed = true;
                    }
                    #endregion
                    else
                    {
                        if (isProcessed)
                        {
                            int processedByteCount = processedBytes.Length;

                            responseHeaders["Content-Length"] = processedByteCount.ToString();
                            await originalStream.WriteAsync(processedBytes, 0, processedByteCount);
                        }
                    }

                    #region 保存到缓存中
                    cacheContent = new CacheContent()
                    {
                        Content     = processedBytes,
                        ContentType = contentType,
                        Headers     = new Dictionary <string, string>()
                    };
                    foreach (var rh in responseHeaders)
                    {
                        cacheContent.Headers.Add(rh.Key, rh.Value);
                    }
                    await _cacheService.SetAsync(cacheKey, cacheContent, TimeSpan.FromSeconds(cachePage.CacheTime));

                    context.Response.Headers.Add("C-Cache", "Cached");
                    //Task.Factory.StartNew(obj =>
                    //{
                    //    var cc = (CacheContent)obj;

                    //}, cacheContent);
                    #endregion
                }
                if (!isProcessed)
                {
                    await originalStream.WriteAsync(cachedBytes, 0, cachedByteCount);
                }
            }
        }
        public void Creation_fails_for_invalid_CacheContent()
        {
            // Arrange
            var primaryKey = new PrimaryCacheKey("https://localhost/test", "POST");
            var secondaryKey = TestHelper.CreateContentKey();
            var entry = new CacheEntry(primaryKey, new string[0]);
            var response = new HttpResponseMessage();

            var noPrimary = new CacheContent()
            {
                ContentKey = secondaryKey,
                Response = response
            };

            var noContentKey = new CacheContent()
            {
                Response = response
            };

            var noResponse = new CacheContent()
            {
                PrimaryKey = primaryKey,
                ContentKey = secondaryKey,
            };

            // Act

            // Assert
            Assert.Throws<ArgumentException>(() => SterlingCacheContent.CreateAsync(noPrimary).Result);
            Assert.Throws<ArgumentException>(() => SterlingCacheContent.CreateAsync(noContentKey).Result);
            Assert.Throws<ArgumentException>(() => SterlingCacheContent.CreateAsync(noResponse).Result);
        }
Esempio n. 17
0
 public void Add(CacheContent content)
 {
     _contents.Add(content);
 }
Esempio n. 18
0
 public void PersistAdd(CacheContent content)
 {
     PersistContents.Add(content);
     SavePersistContents();
 }