public override bool StreamOutput(int tabId, string cacheKey, HttpContext context)
        {
            bool Succes = false;

            try
            {
                string attribFileName       = OpenFileProvider.GetAttribFileName(tabId, cacheKey);
                string cachedOutputFileName = OpenFileProvider.GetCachedOutputFileName(tabId, cacheKey);
                if (File.Exists(attribFileName) && File.Exists(cachedOutputFileName) && !IsFileExpired(attribFileName))
                {
                    var      Response         = context.Response;
                    DateTime lastWriteTimeUtc = File.GetLastWriteTimeUtc(cachedOutputFileName);
                    Response.Cache.SetLastModified(lastWriteTimeUtc);
                    bool        send304 = false;
                    HttpRequest request = context.Request;
                    string      ifModifiedSinceHeader = request.Headers["If-Modified-Since"];
                    string      etag = request.Headers["If-None-Match"];
                    if (ifModifiedSinceHeader != null && etag != null)
                    {
                        etag = etag.Trim('"');
                        try
                        {
                            DateTime utcIfModifiedSince = DateTime.Parse(ifModifiedSinceHeader);
                            if (lastWriteTimeUtc <= utcIfModifiedSince && etag == cacheKey)
                            {
                                Response.StatusCode        = 304;
                                Response.StatusDescription = "Not Modified";
                                Response.SuppressContent   = true;
                                //Response.ClearContent();
                                Response.AddHeader("Content-Length", "0");
                                send304 = true;
                            }
                        }
                        catch
                        {
                            DnnLog.Error("Ignore If-Modified-Since header, invalid format: " + ifModifiedSinceHeader);
                        }
                    }

                    if (!send304)
                    {
                        context.Response.TransmitFile(cachedOutputFileName);
                    }

                    Succes = true;
                }
                else
                {
                    FileSystemUtils.DeleteFileWithWait(attribFileName, 100, 200);
                    FileSystemUtils.DeleteFileWithWait(cachedOutputFileName, 100, 200);
                    Succes = false;
                }
            }
            catch (Exception ex)
            {
                Succes = false;
                DnnLog.Error(ex);
            }
            return(Succes);
        }
        public override bool IsExpired(int tabId, string cacheKey, out DateTime LastModified)
        {
            LastModified = Null.NullDate;

            string attribFileName       = OpenFileProvider.GetAttribFileName(tabId, cacheKey);
            string cachedOutputFileName = OpenFileProvider.GetCachedOutputFileName(tabId, cacheKey);

            if (File.Exists(attribFileName) && File.Exists(cachedOutputFileName) && !IsFileExpired(attribFileName))
            {
                LastModified = File.GetLastWriteTimeUtc(cachedOutputFileName);
                return(false);
            }
            return(true);
        }