Exemple #1
0
        public IVirtualFile GetFileIfCached(string virtualPath, System.Collections.Specialized.NameValueCollection queryString, IVirtualFile original)
        {
            //Use alternate cache key if provided
            string key = original is IVirtualFileSourceCacheKey ? ((IVirtualFileSourceCacheKey)original).GetCacheKey(true) : original.VirtualPath;
            //If cached, serve it.
            CachedVirtualFile c = cache.Get(key);

            if (c != null)
            {
                return(c);
            }
            //If not, let's cache it.
            if ("mem".Equals(queryString["scache"], StringComparison.OrdinalIgnoreCase))
            {
                locks.TryExecute(key, 3000, delegate() {
                    c = cache.Get(key);
                    if (c == null)
                    {
                        using (Stream data = original.Open()) {//Very long-running call
                            c = new CachedVirtualFile(original.VirtualPath, StreamExtensions.CopyToBytes(data, true));
                        }
                        cache.Set(key, c);//Save to cache (may trigger cleanup)
                    }
                });
                return(c);
            }
            return(null);
        }
Exemple #2
0
        public bool WriteToStream(
            BaseCompositeFileProcessingProvider provider,
            StreamWriter sw,
            IVirtualFile vf,
            ClientDependencyType type,
            string origUrl,
            HttpContextBase http)
        {
            try
            {
                using (var readStream = vf.Open())
                    using (var streamReader = new StreamReader(readStream))
                    {
                        var output = streamReader.ReadToEnd();
                        DefaultFileWriter.WriteContentToStream(provider, sw, output, type, http, origUrl);
                        return(true);
                    }
            }
            catch (Exception exception)
            {
                LogHelper.Warn(typeof(EmbeddedResourceVirtualFileWriter), exception.Message);

                return(false);
            }
        }
        /// <inheritdoc/>
        public bool WriteToStream(
            BaseCompositeFileProcessingProvider provider,
            StreamWriter streamWriter,
            IVirtualFile virtualFile,
            ClientDependencyType type,
            string originalUrl,
            HttpContextBase context)
        {
            StreamReader streamReader = null;

            try
            {
                Stream readStream = virtualFile.Open();
                streamReader = new StreamReader(readStream);
                string output = streamReader.ReadToEnd();

                DefaultFileWriter.WriteContentToStream(provider, streamWriter, output, type, context, originalUrl);

                return(true);
            }
            catch (Exception)
            {
                // The file must have failed to open
                return(false);
            }
            finally
            {
                // readStream is disposed by the streamReader.
                streamReader?.Dispose();
            }
        }
        MemCachedFile( IVirtualFile file )
        {
            if (file == null) throw new FileNotFoundException();
            this.path = file.VirtualPath;

            using (Stream s = file.Open()) {
                this.data = StreamExtensions.CopyToBytes(s);
            }
        }
Exemple #5
0
        MemCachedFile(IVirtualFile file)
        {
            if (file == null)
            {
                throw new FileNotFoundException();
            }
            this.path = file.VirtualPath;

            using (Stream s = file.Open()) {
                this.data = StreamExtensions.CopyToBytes(s);
            }
        }
 /// <summary>
 /// The write to stream.
 /// </summary>
 /// <param name="provider">
 /// The provider.
 /// </param>
 /// <param name="sw">
 /// The sw.
 /// </param>
 /// <param name="vf">
 /// The vf.
 /// </param>
 /// <param name="type">
 /// The type.
 /// </param>
 /// <param name="origUrl">
 /// The orig url.
 /// </param>
 /// <param name="http">
 /// The http.
 /// </param>
 /// <returns>
 /// The <see cref="bool"/>.
 /// </returns>
 public bool WriteToStream(BaseCompositeFileProcessingProvider provider, StreamWriter sw, IVirtualFile vf, ClientDependencyType type, string origUrl, HttpContextBase http)
 {
     try
     {
         using (var readStream = vf.Open())
         using (var streamReader = new StreamReader(readStream))
         {
             var output = streamReader.ReadToEnd();
             DefaultFileWriter.WriteContentToStream(provider, sw, output, type, http, origUrl);
             return true;
         }
     }
     catch (Exception)
     {
         // the file must have failed to open
         return false;
     }
 }
 public bool WriteToStream(BaseCompositeFileProcessingProvider provider, StreamWriter sw, IVirtualFile vf, ClientDependencyType type, string origUrl, HttpContextBase http)
 {
     try
     {
         using (var readStream = vf.Open())
             using (var streamReader = new StreamReader(readStream))
             {
                 var output = streamReader.ReadToEnd();
                 DefaultFileWriter.WriteContentToStream(provider, sw, output, type, http, origUrl);
                 return(true);
             }
     }
     catch (Exception)
     {
         // the file must have failed to open
         return(false);
     }
 }
Exemple #8
0
        public IVirtualFile GetFileIfCached(string virtualPath, System.Collections.Specialized.NameValueCollection queryString, IVirtualFile original)
        {
            if (!"disk".Equals(queryString["scache"], StringComparison.OrdinalIgnoreCase))
            {
                return(null);
            }
            if (this.AsyncModuleMode)
            {
                throw new InvalidOperationException("SourceDiskCache cannot be used in synchronous mode if AsyncModuleMode=true");
            }


            //Verify web.config exists in the cache folder.
            writer.CheckWebConfigEvery5();

            //Use alternate cache key if provided
            string key = original is IVirtualFileSourceCacheKey ? ((IVirtualFileSourceCacheKey)original).GetCacheKey(false) : original.VirtualPath;
            //If cached, serve it.

            var r = cache.GetCachedFile(key, ".cache", delegate(Stream target)
            {
                using (Stream data = original.Open())
                { //Very long-running call
                    data.CopyToStream(target);
                }
            }, 15 * 1000, true);

            if (r.Result == CacheQueryResult.Failed)
            {
                return(null);
            }

            if (r.Result == CacheQueryResult.Hit && cleaner != null)
            {
                cleaner.UsedFile(r.RelativePath, r.PhysicalPath);
            }


            return(new SourceVirtualFile(original.VirtualPath, delegate(){
                return r.Data ?? File.Open(r.PhysicalPath, FileMode.Open, FileAccess.Read, FileShare.Read);
            }));
        }
Exemple #9
0
        public IVirtualFile GetFileIfCached(string virtualPath, System.Collections.Specialized.NameValueCollection queryString, IVirtualFile original)
        {
            if (!"disk".Equals(queryString["scache"], StringComparison.OrdinalIgnoreCase))
            {
                return(null);
            }


            //Verify web.config exists in the cache folder.
            writer.CheckWebConfigEvery5();

            //Use alternate cache key if provided
            string key = original is IVirtualFileSourceCacheKey ? ((IVirtualFileSourceCacheKey)original).GetCacheKey(false) : original.VirtualPath;
            //If cached, serve it.
            var r = cache.GetCachedFile(key, ".cache", delegate(Stream target)
            {
                using (Stream data = original.Open())
                {//Very long-running call
                    StreamExtensions.CopyToStream(data, target);
                }
            }, DateTime.MinValue, 15 * 1000, true);

            if (r.Result == CacheQueryResult.Failed)
            {
                throw new ImageResizer.ImageProcessingException("Failed to acquire a lock on file \"" + r.PhysicalPath + "\" within 15 seconds. Source caching failed.");
            }

            if (r.Result == CacheQueryResult.Hit && cleaner != null)
            {
                cleaner.UsedFile(r.RelativePath, r.PhysicalPath);
            }


            return(new SourceVirtualFile(original.VirtualPath, delegate(){
                return r.Data ?? File.Open(r.PhysicalPath, FileMode.Open, FileAccess.Read, FileShare.Read);
            }));
        }
 /// <summary>
 /// Writes the virtual file to a stream for serving.
 /// </summary>
 /// <param name="provider">The file processing provider.</param>
 /// <param name="streamWriter">The <see cref="StreamWriter"/>.</param>
 /// <param name="virtualFile">The <see cref="IVirtualFile"/> to write.</param>
 /// <param name="type">The <see cref="ClientDependencyType"/> the virtual file matches.</param>
 /// <param name="originalUrl">The original url to the virtual file.</param>
 /// <param name="context">The <see cref="HttpContextBase"/>.</param>
 /// <returns>
 /// The <see cref="bool"/>.
 /// </returns>
 public bool WriteToStream(
     BaseCompositeFileProcessingProvider provider, 
     StreamWriter streamWriter, 
     IVirtualFile virtualFile, 
     ClientDependencyType type, 
     string originalUrl, 
     HttpContextBase context)
 {
     try
     {
         using (Stream readStream = virtualFile.Open())
         using (StreamReader streamReader = new StreamReader(readStream))
         {
             string output = streamReader.ReadToEnd();
             DefaultFileWriter.WriteContentToStream(provider, streamWriter, output, type, context, originalUrl);
             return true;
         }
     }
     catch (Exception)
     {
         // The file must have failed to open
         return false;
     }
 }
Exemple #11
0
 public IVirtualFile GetFileIfCached(string virtualPath, System.Collections.Specialized.NameValueCollection queryString, IVirtualFile original)
 {
     //Use alternate cache key if provided
     string key = original is IVirtualFileSourceCacheKey ? ((IVirtualFileSourceCacheKey)original).GetCacheKey(true) : original.VirtualPath;
     //If cached, serve it.
     CachedVirtualFile c = cache.Get(key);
     if (c != null) return c;
     //If not, let's cache it.
     if ("mem".Equals(queryString["scache"], StringComparison.OrdinalIgnoreCase)) {
         locks.TryExecute(key, 3000, delegate() {
             c = cache.Get(key);
             if (c == null) {
                 using (Stream data = original.Open()) {//Very long-running call
                     c = new CachedVirtualFile(original.VirtualPath, StreamExtensions.CopyToBytes(data, true));
                 }
                 cache.Set(key, c);//Save to cache (may trigger cleanup)
             }
         });
         return c;
     }
     return null;
 }
Exemple #12
0
        /// <summary>
        /// Generates the resized image to disk (if needed), then rewrites the request to that location.
        /// Perform 404 checking before calling this method. Assumes file exists.
        /// Called during PostAuthorizeRequest
        /// </summary>
        /// <param name="context"></param>
        /// <param name="ra"></param>
        /// <param name="vf"></param>
        protected virtual void HandleRequest(HttpContext context, HttpModuleRequestAssistant ra, IVirtualFile vf)
        {
            if (!ra.CachingIndicated && !ra.ProcessingIndicated)
            {
                ra.ApplyRewrittenPath(); //This is needed for both physical and virtual files; only makes changes if needed.
                if (vf != null)
                {
                    ra.AssignSFH(); //Virtual files are not served in .NET 4.
                }
                return;
            }

            context.Items[conf.ResponseArgsKey] = ""; //We are handling the request

            //Communicate to the MVC plugin this request should not be affected by the UrlRoutingModule.
            context.Items[conf.StopRoutingKey] = true;


            ra.EstimateResponseInfo();

            //Build CacheEventArgs
            ResponseArgs e = new ResponseArgs();

            //Add the modified date to the request key, if present.
            var modDate = (vf == null) ? System.IO.File.GetLastWriteTimeUtc(ra.RewrittenMappedPath) :
                          (vf is IVirtualFileWithModifiedDate ? ((IVirtualFileWithModifiedDate)vf).ModifiedDateUTC : DateTime.MinValue);

            e.RequestKey = ra.GenerateRequestCachingKey(modDate);


            var settings = new ResizeSettings(ra.RewrittenInstructions);

            e.RewrittenQuerystring        = settings;
            e.ResponseHeaders.ContentType = ra.EstimatedContentType;
            e.SuggestedExtension          = ra.EstimatedFileExtension;


            //A delegate for accessing the source file
            e.GetSourceImage = new GetSourceImageDelegate(delegate() {
                return((vf != null) ? vf.Open() : File.Open(ra.RewrittenMappedPath, FileMode.Open, FileAccess.Read, FileShare.Read));
            });

            //Add delegate for writing the data stream
            e.ResizeImageToStream = new ResizeImageDelegate(delegate(System.IO.Stream stream) {
                //This runs on a cache miss or cache invalid. This delegate is preventing from running in more
                //than one thread at a time for the specified cache key
                try {
                    if (!ra.ProcessingIndicated)
                    {
                        //Just duplicate the data
                        using (Stream source = e.GetSourceImage())
                            source.CopyToStream(stream); //4KiB buffer
                    }
                    else
                    {
                        ImageJob j;
                        //Process the image
                        if (vf != null)
                        {
                            j = new ImageJob(vf, stream, settings);
                        }
                        else
                        {
                            j = new ImageJob(ra.RewrittenMappedPath, stream, settings); //Use a physical path to bypass virtual file system
                        }
                        conf.GetImageBuilder().Build(j);
                    }
                    ra.FireJobSuccess();
                    //Catch not found exceptions
                } catch (System.IO.FileNotFoundException notFound) {
                    if (notFound.Message.Contains(" assembly "))
                    {
                        throw;                                          //If an assembly is missing, it should be a 500, not a 404
                    }
                    //This will be called later, if at all.
                    ra.FireMissing();
                    throw new ImageMissingException("The specified resource could not be located", "File not found", notFound);
                } catch (System.IO.DirectoryNotFoundException notFound) {
                    ra.FireMissing();
                    throw new ImageMissingException("The specified resource could not be located", "File not found", notFound);
                } catch (Exception ex)
                {
                    ra.FireJobException(ex);
                    throw;
                }
            });


            context.Items[conf.ResponseArgsKey] = e; //store in context items

            //Fire events (for client-side caching plugins)
            conf.FirePreHandleImage(this, context, e);

            //Pass the rest of the work off to the caching module. It will handle rewriting/redirecting and everything.
            //We handle request headers based on what is found in context.Items
            ICache cache = conf.GetCacheProvider().GetCachingSystem(context, e);

            //Verify we have a caching system
            if (cache == null)
            {
                throw new ImageProcessingException("Image Resizer: No caching plugin was found for the request");
            }

            cache.Process(context, e); //TODO: Verify that caching systems serves request or transfers to StaticFileHandler
        }
Exemple #13
0
        /// <summary>
        /// Generates the resized image to disk (if needed), then rewrites the request to that location.
        /// Perform 404 checking before calling this method. Assumes file exists.
        /// Called during PostAuthorizeRequest
        /// </summary>
        /// <param name="context"></param>
        /// <param name="virtualPath"></param>
        /// <param name="queryString"></param>
        /// <param name="vf"></param>
        protected virtual void HandleRequest(HttpContext context, string virtualPath, NameValueCollection queryString, IVirtualFile vf)
        {
            Stopwatch s = new Stopwatch();

            s.Start();


            ResizeSettings settings = new ResizeSettings(queryString);

            bool isCaching    = settings.Cache == ServerCacheMode.Always;
            bool isProcessing = settings.Process == ProcessWhen.Always;

            //By default, we process it if is both (a) a recognized image extension, and (b) has a resizing directive (not just 'cache').
            if (settings.Process == ProcessWhen.Default)
            {
                //Check for resize directive by removing ('non-resizing' items from the current querystring)
                NameValueCollection copy = new NameValueCollection(queryString);
                copy.Remove("cache"); copy.Remove("process"); copy.Remove("useresizingpipeline"); copy.Remove("404");
                copy.Remove("404.filterMode"); copy.Remove("404.except");
                //If the 'copy' still has directives, and it's an image request, then let's process it.
                isProcessing = conf.IsAcceptedImageType(virtualPath) && conf.HasPipelineDirective(copy);
            }

            //By default, we only cache it if we're processing it.
            if (settings.Cache == ServerCacheMode.Default && isProcessing)
            {
                isCaching = true;
            }

            //Resolve the 'cache' setting to 'no' unless we want it cache.
            if (!isCaching)
            {
                settings.Cache = ServerCacheMode.No;
            }


            //If we are neither processing nor caching, don't do anything more with the request
            if (!isProcessing && !isCaching)
            {
                return;
            }
            context.Items[conf.ResponseArgsKey] = ""; //We are handling the requests

            //Communicate to the MVC plugin this request should not be affected by the UrlRoutingModule.
            context.Items[conf.StopRoutingKey] = true;

            //Find out if we have a modified date that we can work with
            bool     hasModifiedDate = (vf == null) || vf is IVirtualFileWithModifiedDate;
            DateTime modDate         = DateTime.MinValue;

            if (hasModifiedDate && vf != null)
            {
                modDate = ((IVirtualFileWithModifiedDate)vf).ModifiedDateUTC;
                if (modDate == DateTime.MinValue || modDate == DateTime.MaxValue)
                {
                    hasModifiedDate = false; //Skip modified date checking if the file has no modified date
                }
            }


            IEncoder guessedEncoder = null;

            //Only use an encoder to determine extension/mime-type when it's an image extension or when we've set process = always.
            if (isProcessing)
            {
                guessedEncoder = conf.GetImageBuilder().EncoderProvider.GetEncoder(settings, virtualPath);
                if (guessedEncoder == null)
                {
                    throw new ImageProcessingException("Image Resizer: No image encoder was found for the request.");
                }
            }

            //Determine the file extenson for the caching system to use if we aren't processing the image
            //Use the exsiting one if is an image extension. If not, use "unknown".
            // We don't want to suggest writing .exe or .aspx files to the cache!
            string fallbackExtension = PathUtils.GetFullExtension(virtualPath).TrimStart('.');

            if (!conf.IsAcceptedImageType(virtualPath))
            {
                fallbackExtension = "unknown";
            }

            //Determine the mime-type if we aren't processing the image.
            string fallbackContentType = "application/octet-stream";

            //Support jpeg, png, gif, bmp, tiff mime-types. Otherwise use "application/octet-stream".
            //We can't set it to null - it will default to text/html
            System.Drawing.Imaging.ImageFormat recognizedExtension = DefaultEncoder.GetImageFormatFromExtension(fallbackExtension);
            if (recognizedExtension != null)
            {
                fallbackContentType = DefaultEncoder.GetContentTypeFromImageFormat(recognizedExtension);
            }


            //Build CacheEventArgs
            ResponseArgs e = new ResponseArgs();

            e.RequestKey                  = virtualPath + PathUtils.BuildQueryString(queryString);
            e.RewrittenQuerystring        = settings;
            e.ResponseHeaders.ContentType = isProcessing ? guessedEncoder.MimeType : fallbackContentType;
            e.SuggestedExtension          = isProcessing ? guessedEncoder.Extension : fallbackExtension;
            e.HasModifiedDate             = hasModifiedDate;
            //Add delegate for retrieving the modified date of the source file.
            e.GetModifiedDateUTC = new ModifiedDateDelegate(delegate() {
                if (vf == null)
                {
                    return(System.IO.File.GetLastWriteTimeUtc(HostingEnvironment.MapPath(virtualPath)));
                }
                else if (hasModifiedDate)
                {
                    return(modDate);
                }
                else
                {
                    return(DateTime.MinValue); //Won't be called, no modified date available.
                }
            });

            //A delegate for accessing the source file
            e.GetSourceImage = new GetSourceImageDelegate(delegate() {
                return((vf != null) ? vf.Open() : File.Open(HostingEnvironment.MapPath(virtualPath), FileMode.Open, FileAccess.Read, FileShare.Read));
            });

            //Add delegate for writing the data stream
            e.ResizeImageToStream = new ResizeImageDelegate(delegate(System.IO.Stream stream) {
                //This runs on a cache miss or cache invalid. This delegate is preventing from running in more
                //than one thread at a time for the specified cache key
                try {
                    if (!isProcessing)
                    {
                        //Just duplicate the data
                        using (Stream source = e.GetSourceImage())
                            StreamExtensions.CopyToStream(source, stream); //4KiB buffer
                    }
                    else
                    {
                        //Process the image
                        if (vf != null)
                        {
                            conf.GetImageBuilder().Build(vf, stream, settings);
                        }
                        else
                        {
                            conf.GetImageBuilder().Build(HostingEnvironment.MapPath(virtualPath), stream, settings); //Use a physical path to bypass virtual file system
                        }
                    }

                    //Catch not found exceptions
                } catch (System.IO.FileNotFoundException notFound) {
                    //This will be called later, if at all.
                    FileMissing(context, virtualPath, queryString);
                    throw new ImageMissingException("The specified resource could not be located", "File not found", notFound);
                } catch (System.IO.DirectoryNotFoundException notFound) {
                    FileMissing(context, virtualPath, queryString);
                    throw new ImageMissingException("The specified resource could not be located", "File not found", notFound);
                }
            });


            context.Items[conf.ResponseArgsKey] = e; //store in context items

            //Fire events (for client-side caching plugins)
            conf.FirePreHandleImage(this, context, e);

            //Pass the rest of the work off to the caching module. It will handle rewriting/redirecting and everything.
            //We handle request headers based on what is found in context.Items
            ICache cache = conf.GetCacheProvider().GetCachingSystem(context, e);

            //Verify we have a caching system
            if (cache == null)
            {
                throw new ImageProcessingException("Image Resizer: No caching plugin was found for the request");
            }

            cache.Process(context, e);



            s.Stop();
            context.Items["ResizingTime"] = s.ElapsedMilliseconds;
        }
        public IVirtualFile GetFileIfCached(string virtualPath, System.Collections.Specialized.NameValueCollection queryString, IVirtualFile original)
        {
            if (!"disk".Equals(queryString["scache"], StringComparison.OrdinalIgnoreCase)) return null;

            //Verify web.config exists in the cache folder.
            writer.CheckWebConfigEvery5();

            //Use alternate cache key if provided
            string key = original is IVirtualFileSourceCacheKey ? ((IVirtualFileSourceCacheKey)original).GetCacheKey(false) : original.VirtualPath;
            //If cached, serve it.
            var r = cache.GetCachedFile(key, ".cache", delegate(Stream target)
            {
                using (Stream data = original.Open())
                {//Very long-running call
                    StreamExtensions.CopyToStream(data, target);
                }
            }, DateTime.MinValue, 15 * 1000,true);

            if (r.Result == CacheQueryResult.Failed)
                throw new ImageResizer.ImageProcessingException("Failed to acquire a lock on file \"" + r.PhysicalPath + "\" within 15 seconds. Source caching failed.");

            if (r.Result == CacheQueryResult.Hit && cleaner != null)
                cleaner.UsedFile(r.RelativePath, r.PhysicalPath);

            return new SourceVirtualFile(original.VirtualPath,delegate(){
                return r.Data ?? File.Open(r.PhysicalPath, FileMode.Open, FileAccess.Read, FileShare.Read);
            });
        }
Exemple #15
0
 public override System.IO.Stream Open()
 {
     return(f.Open());
 }
        /// <summary>
        /// Generates the resized image to disk (if needed), then rewrites the request to that location.
        /// Perform 404 checking before calling this method. Assumes file exists.
        /// Called during PostAuthorizeRequest
        /// </summary>
        /// <param name="context"></param>
        /// <param name="virtualPath"></param>
        /// <param name="queryString"></param>
        /// <param name="vf"></param>
        protected virtual void HandleRequest(HttpContext context, string virtualPath, NameValueCollection queryString, IVirtualFile vf)
        {
            Stopwatch s = new Stopwatch();
            s.Start();

            ResizeSettings settings = new ResizeSettings(queryString);

            bool isCaching = settings.Cache == ServerCacheMode.Always;
            bool isProcessing = settings.Process == ProcessWhen.Always;

            //By default, we process it if is both (a) a recognized image extension, and (b) has a resizing directive (not just 'cache').
            if (settings.Process == ProcessWhen.Default){
                //Check for resize directive by removing ('non-resizing' items from the current querystring)
                NameValueCollection copy = new NameValueCollection(queryString);
                copy.Remove("cache"); copy.Remove("process"); copy.Remove("useresizingpipeline"); copy.Remove("404");
                copy.Remove("404.filterMode"); copy.Remove("404.except");
                //If the 'copy' still has directives, and it's an image request, then let's process it.
                isProcessing = conf.IsAcceptedImageType(virtualPath) &&  conf.HasPipelineDirective(copy);
            }

            //By default, we only cache it if we're processing it.
            if (settings.Cache == ServerCacheMode.Default && isProcessing)
                isCaching = true;

            //Resolve the 'cache' setting to 'no' unless we want it cache.
            if (!isCaching) settings.Cache = ServerCacheMode.No;

            //If we are neither processing nor caching, don't do anything more with the request
            if (!isProcessing && !isCaching) return;
            context.Items[conf.ResponseArgsKey] = ""; //We are handling the requests

            //Communicate to the MVC plugin this request should not be affected by the UrlRoutingModule.
            context.Items[conf.StopRoutingKey] = true;

            //Find out if we have a modified date that we can work with
            bool hasModifiedDate = (vf == null) || vf is IVirtualFileWithModifiedDate;
            DateTime modDate = DateTime.MinValue;
            if (hasModifiedDate && vf != null) {
                modDate = ((IVirtualFileWithModifiedDate)vf).ModifiedDateUTC;
                if (modDate == DateTime.MinValue || modDate == DateTime.MaxValue) {
                    hasModifiedDate = false; //Skip modified date checking if the file has no modified date
                }
            }

            IEncoder guessedEncoder = null;
            //Only use an encoder to determine extension/mime-type when it's an image extension or when we've set process = always.
            if (isProcessing) {
                guessedEncoder = conf.GetImageBuilder().EncoderProvider.GetEncoder(settings, virtualPath);
                if (guessedEncoder == null) throw new ImageProcessingException("Image Resizer: No image encoder was found for the request.");
            }

            //Determine the file extenson for the caching system to use if we aren't processing the image
            //Use the exsiting one if is an image extension. If not, use "unknown".
            // We don't want to suggest writing .exe or .aspx files to the cache!
            string fallbackExtension = PathUtils.GetFullExtension(virtualPath).TrimStart('.');
            if (!conf.IsAcceptedImageType(virtualPath)) fallbackExtension = "unknown";

            //Determine the mime-type if we aren't processing the image.
            string fallbackContentType = "application/octet-stream";
            //Support jpeg, png, gif, bmp, tiff mime-types. Otherwise use "application/octet-stream".
            //We can't set it to null - it will default to text/html
            System.Drawing.Imaging.ImageFormat recognizedExtension = DefaultEncoder.GetImageFormatFromExtension(fallbackExtension);
            if (recognizedExtension != null) fallbackContentType = DefaultEncoder.GetContentTypeFromImageFormat(recognizedExtension);

            //Build CacheEventArgs
            ResponseArgs e = new ResponseArgs();
            e.RequestKey = virtualPath + PathUtils.BuildQueryString(queryString);
            e.RewrittenQuerystring = settings;
            e.ResponseHeaders.ContentType = isProcessing ? guessedEncoder.MimeType : fallbackContentType;
            e.SuggestedExtension = isProcessing ? guessedEncoder.Extension : fallbackExtension;
            e.HasModifiedDate = hasModifiedDate;
            //Add delegate for retrieving the modified date of the source file.
            e.GetModifiedDateUTC = new ModifiedDateDelegate(delegate() {
                if (vf == null)
                    return System.IO.File.GetLastWriteTimeUtc(HostingEnvironment.MapPath(virtualPath));
                else if (hasModifiedDate)
                    return modDate;
                else return DateTime.MinValue; //Won't be called, no modified date available.
            });

            //A delegate for accessing the source file
            e.GetSourceImage = new GetSourceImageDelegate(delegate() {
                return (vf != null) ? vf.Open() : File.Open(HostingEnvironment.MapPath(virtualPath), FileMode.Open, FileAccess.Read, FileShare.Read);
            });

            //Add delegate for writing the data stream
            e.ResizeImageToStream = new ResizeImageDelegate(delegate(System.IO.Stream stream) {
                //This runs on a cache miss or cache invalid. This delegate is preventing from running in more
                //than one thread at a time for the specified cache key
                try {
                    if (!isProcessing) {
                        //Just duplicate the data
                        using (Stream source = e.GetSourceImage())
                            StreamExtensions.CopyToStream(source, stream); //4KiB buffer

                    } else {
                        //Process the image
                        if (vf != null)
                            conf.GetImageBuilder().Build(vf, stream, settings);
                        else
                            conf.GetImageBuilder().Build(HostingEnvironment.MapPath(virtualPath), stream, settings); //Use a physical path to bypass virtual file system
                    }

                    //Catch not found exceptions
                } catch (System.IO.FileNotFoundException notFound) {
                    //This will be called later, if at all.
                    FileMissing(context, virtualPath, queryString);
                    throw new ImageMissingException("The specified resource could not be located","File not found", notFound);
                } catch (System.IO.DirectoryNotFoundException notFound) {
                    FileMissing(context, virtualPath, queryString);
                    throw new ImageMissingException("The specified resource could not be located", "File not found", notFound);
                }
            });

            context.Items[conf.ResponseArgsKey] = e; //store in context items

            //Fire events (for client-side caching plugins)
            conf.FirePreHandleImage(this, context, e);

            //Pass the rest of the work off to the caching module. It will handle rewriting/redirecting and everything.
            //We handle request headers based on what is found in context.Items
            ICache cache = conf.GetCacheProvider().GetCachingSystem(context, e);

            //Verify we have a caching system
            if (cache == null) throw new ImageProcessingException("Image Resizer: No caching plugin was found for the request");

            cache.Process(context, e);

            s.Stop();
            context.Items["ResizingTime"] = s.ElapsedMilliseconds;
        }