private Stream getUrlStream(String url, out ResourceWebResponse response)
        {
            Uri uri = new Uri(url);

            response = null;
            try { response = WebRequest.Create(uri).GetResponse() as ResourceWebResponse; }
            catch { }
            var stream = response?.GetResponseStream();

            return(stream);
        }
        private Task handleResource(IOwinContext context, Stream stream, ResourceWebResponse resourceResponse, double expires, IDictionary <string, string> addonHttpHeaders)
        {
            var req = context.Request;
            var rep = context.Response;

            //验证缓存有效
            {
                //===================
                //先验证最后修改时间
                //===================
                var resourceLastModified = resourceResponse.LastModified;
                //最后修改时间判断部分
                var clientLastModified = req.Headers.Get("If-Modified-Since");
                if (clientLastModified != null)
                {
                    if (clientLastModified == resourceLastModified.ToString("R"))
                    {
                        rep.StatusCode = 304;
                        return(Task.Run(() => stream.Dispose()));
                    }
                }
                //===================
                //然后验证ETag
                //===================
                //ETag设置判断部分
                String serverETag = null;
                if (UseMd5ETag)
                {
                    serverETag = HashUtils.ComputeETagByMd5(stream);
                }
                else
                {
                    serverETag = resourceResponse.LastModified.Ticks.ToString();
                }
                var clientETag = req.Headers.Get("If-None-Match");
                //如果客户端的ETag值与服务端相同,则返回304,表示资源未修改
                if (serverETag == clientETag)
                {
                    rep.StatusCode = 304;
                    return(Task.Run(() => stream.Dispose()));
                }
                rep.ETag        = serverETag;
                stream.Position = 0;
            }
            rep.Expires = new DateTimeOffset(DateTime.Now.AddSeconds(expires));
            rep.Headers["Cache-Control"] = $"max-age={expires}";
            rep.Headers["Last-Modified"] = resourceResponse.LastModified.ToUniversalTime().ToString("R");
            return(context.Output(stream, true, EnableCompress, resourceResponse.Uri.LocalPath, addonHttpHeaders));
        }