public void Process(HttpContext context, IResponseArgs e) { var file = GetFile(e.RequestKey, null); var reprocessCache = false; if (file != null) { try { var stream = file.Open(); ((ResponseArgs)e).ResizeImageToStream = s => stream.CopyTo(s); } catch (FileNotFoundException) { reprocessCache = true; } } if (file == null || reprocessCache) { var stream = new MemoryStream(4096); e.ResizeImageToStream(stream); Upload(e.RequestKey, stream, null); } context.RemapHandler(new NoCacheHandler(e)); }
/// <summary> /// We don't actually send the data - but we still want to control the headers on the data. /// PreSendRequestHeaders allows us to change the content-type and cache headers at exactly the last moment /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void context_PreSendRequestHeaders(object sender, EventArgs e) { //Skip requests if the Request object isn't populated HttpApplication app = sender as HttpApplication; if (app == null || app.Context == null || app.Context.Items == null || app.Context.Request == null || app.Context.Response == null) { return; } HttpContext context = app.Context; //Skip requests if we don't have an object to work with. if (context.Items[conf.ResponseArgsKey] == null) { return; } //Try to cast the object. IResponseArgs obj = context.Items[conf.ResponseArgsKey] as IResponseArgs; if (obj == null) { return; } //Apply the headers if (obj.ResponseHeaders.ApplyDuringPreSendRequestHeaders) { obj.ResponseHeaders.ApplyToResponse(obj.ResponseHeaders, app.Context); } }
public void Process(System.Web.HttpContext current, IResponseArgs e) { //Use alternate cache key if provided string key = e.RequestKey + (e.HasModifiedDate ? e.GetModifiedDateUTC().Ticks.ToString() : ""); //If cached, serve it. var c = cache.Get(key); if (c != null) { Serve(current, e, c); return; } //If not, let's cache it. locks.TryExecute(key, 3000, delegate() { c = cache.Get(key); if (c == null) { using (var data = new MemoryStream()){ e.ResizeImageToStream(data);//Very long-running call c = new MemCacheResult(StreamExtensions.CopyToBytes(data, true)); } cache.Set(key, c);//Save to cache (may trigger cleanup) } Serve(current, e, c); return; }); }
public CacheResult Process(IResponseArgs e) { //Query for the modified date of the source file. If the source file changes on us during the write, //we (may) end up saving the newer version in the cache properly, but with an older modified date. //This will not cause any actual problems from a behavioral standpoint - the next request for the //image will cause the file to be overwritten and the modified date updated. DateTime modDate = e.HasModifiedDate ? e.GetModifiedDateUTC() : DateTime.MinValue; //Verify web.config exists in the cache folder. writer.CheckWebConfigEvery5(); //Cache the data to disk and return a path. CacheResult r = cache.GetCachedFile(e.RequestKey, e.SuggestedExtension, e.ResizeImageToStream, modDate, CacheAccessTimeout, AsyncWrites); //Fail if (r.Result == CacheQueryResult.Failed) { throw new ImageResizer.ImageProcessingException("Failed to acquire a lock on file \"" + r.PhysicalPath + "\" within " + CacheAccessTimeout + "ms. Caching failed."); } if (r.Result == CacheQueryResult.Hit && cleaner != null) { cleaner.UsedFile(r.RelativePath, r.PhysicalPath); } return(r); }
public void Process(System.Web.HttpContext current, IResponseArgs e) { //Use alternate cache key if provided string key = e.RequestKey; //If cached, serve it. var c = cache.Get(key); if (c != null) { Serve(current, e, c); return; } //If not, let's cache it. locks.TryExecute(key, 3000, delegate() { c = cache.Get(key); if (c == null) { using (var data = new MemoryStream()){ e.ResizeImageToStream(data);//Very long-running call c = new MemCacheResult(data.CopyToBytes(true)); } cache.Set(key, c);//Save to cache (may trigger cleanup) } Serve(current, e, c); return; }); }
public CacheResult Process(IResponseArgs e) { //Verify web.config exists in the cache folder. writer.CheckWebConfigEvery5(); //Cache the data to disk and return a path. CacheResult r = cache.GetCachedFile(e.RequestKey, e.SuggestedExtension, e.ResizeImageToStream, CacheAccessTimeout, AsyncWrites); //Fail if (r.Result == CacheQueryResult.Failed) { GlobalPerf.Singleton.IncrementCounter("diskcache_timeout"); throw new ImageResizer.ImageProcessingException("Failed to acquire a lock on file \"" + r.PhysicalPath + "\" within " + CacheAccessTimeout + "ms. Caching failed."); } if (r.Result == CacheQueryResult.Hit && cleaner != null) { cleaner.UsedFile(r.RelativePath, r.PhysicalPath); } GlobalPerf.Singleton.IncrementCounter((r.Result == CacheQueryResult.Hit) ? "diskcache_hit" : "diskcache_miss"); return(r); }
public void Process(HttpContext context, IResponseArgs e) { if (this.AsyncModuleMode) { throw new InvalidOperationException("DiskCache cannot be used in synchronous mode if AsyncModuleMode=true"); } CacheResult r = Process(e); context.Items["FinalCachedFile"] = r.PhysicalPath; if (r.Data == null) { //Calculate the virtual path string virtualPath = VirtualCacheDir.TrimEnd('/') + '/' + r.RelativePath.Replace('\\', '/').TrimStart('/'); //Rewrite to cached, resized image. context.RewritePath(virtualPath, false); } else { //Remap the response args writer to use the existing stream. ((ResponseArgs)e).ResizeImageToStream = delegate(Stream s) { ((MemoryStream)r.Data).WriteTo(s); }; context.RemapHandler(new NoCacheHandler(e)); } }
public bool CanProcess(System.Web.HttpContext current, IResponseArgs e) { if (((ResizeSettings)e.RewrittenQuerystring).Cache == ServerCacheMode.No) { return(false); } return(CanOperate); }
public bool CanProcess(HttpContext context, IResponseArgs e) { if (((ResizeSettings)e.RewrittenQuerystring).Cache == ServerCacheMode.No) { return(false); } return(true); }
public bool CanProcess(HttpContext current, IResponseArgs e) { // Blob storage caching will 'pass on' caching requests if 'cache=no'. if (((ResizeSettings)e.RewrittenQuerystring).Cache == ServerCacheMode.No) { return(false); } return(Started); //Add support for nocache }
public bool CanProcess(System.Web.HttpContext current, IResponseArgs e) { string match = GetUnquotedEtag(current); string eTag = CalcualteETag(e); string quotedTag = "\"" + eTag + "\""; e.ResponseHeaders.Headers["X-ETag"] = quotedTag; e.ResponseHeaders.Headers["ETag"] = quotedTag; return (match != null && match.Equals(eTag)); }
public bool CanProcess(System.Web.HttpContext current, IResponseArgs e) { string match = GetUnquotedEtag(current); string eTag = CalcualteETag(e); string quotedTag = "\"" + eTag + "\""; e.ResponseHeaders.Headers["X-ETag"] = quotedTag; e.ResponseHeaders.Headers["ETag"] = quotedTag; return(match != null && match.Equals(eTag)); }
public void Process(HttpContext current, IResponseArgs e) { var blobName = ResolveBlobName(e.RequestKey, e.SuggestedExtension); var cachedStream = this.cacheProvider.Resolve(blobName, outputStream => { e.ResizeImageToStream(outputStream); // long-running call }); Serve(current, e, cachedStream); }
/// <summary> /// Handles the response stream for the request to images. /// </summary> /// <param name="context">The context.</param> /// <param name="args">The arguments.</param> /// <param name="stream">The stream.</param> private void HandleResponseStream(HttpContext context, IResponseArgs args, Stream stream) { context.Response.Clear(); context.Response.StatusCode = 200; context.Response.BufferOutput = true; args.ResponseHeaders.ApplyDuringPreSendRequestHeaders = false; args.ResponseHeaders.ApplyToResponse(args.ResponseHeaders, context); stream.CopyTo(context.Response.OutputStream); context.Response.OutputStream.Flush(); context.Response.End(); }
public CacheResult Process(IResponseArgs e) { // Cache the data to blob and return a cached result. CacheResult r = cache.GetCachedFile(e.RequestKey, e.SuggestedExtension, e.ResizeImageToStream, CacheAccessTimeout, AsyncWrites); // Fail if (r.Result == CacheQueryResult.Failed) { throw new ImageProcessingException("Failed to acquire a lock on blob \"" + r.Path + "\" within " + CacheAccessTimeout + "ms. Caching failed."); } return(r); }
public bool CanProcess(System.Web.HttpContext current, IResponseArgs e) { if (e == null) { throw new ArgumentNullException("e"); } if (((ResizeSettings)e.RewrittenQuerystring).Cache == ServerCacheMode.No) { return(false); } return(CanOperate); }
public void Process(System.Web.HttpContext current, IResponseArgs e) { var modDate = e.HasModifiedDate ? e.GetModifiedDateUTC() : DateTime.MinValue; var key = e.RequestKey + "|" + modDate.Ticks.ToString(NumberFormatInfo.InvariantInfo); CacheEntry entry; byte[] data; //Ensure cache is loaded if (!loaded) { Load(); } if (!TryGetData(key, out data, out entry)) { Stopwatch sw = new Stopwatch(); sw.Start(); //Cache miss - process request, outside of lock MemoryStream ms = new MemoryStream(4096); e.ResizeImageToStream(ms); data = StreamExtensions.CopyToBytes(ms, true); sw.Stop(); //Save to cache entry = PutData(key, data, sw.ElapsedMilliseconds); } ((ResponseArgs)e).ResizeImageToStream = delegate(Stream s) { s.Write(data, 0, data.Length); }; current.RemapHandler(new NoCacheHandler(e)); if (cache.changes_since_cleanse > ChangeThreshold) { CleanseAndFlush(); } else if (cache.changes_since_cleanse > 0 && DateTime.UtcNow.Subtract(lastFlush) > new TimeSpan(0, 0, 30)) { Flush(); } }
/// <summary> /// Cache selection occurs as follows: (1) The first registered CachingSystem that returns true from .CanProcess() is the default /// (2) The SelectCachingSystem event is fired, allowing handlers to modify the selected cache. /// This method may return null. /// </summary> /// <param name="context"></param> /// <param name="args"></param> /// <returns></returns> public ICache GetCachingSystem(System.Web.HttpContext context, IResponseArgs args) { ICache defaultCache = null; //Grab the first cache that claims it can process the request. foreach (ICache cache in c.Plugins.CachingSystems) { if (cache.CanProcess(context, args)) { defaultCache = cache; break; } } CacheSelectionEventArgs e = new CacheSelectionEventArgs(context, args, defaultCache); if (SelectCachingSystem != null) { SelectCachingSystem(this, e); } return(e.SelectedCache); }
public void Process(HttpContext context, IResponseArgs e) { CacheResult r = Process(e); context.Items["FinalCachedFile"] = r.PhysicalPath; if (r.Data == null) { //Calculate the virtual path string virtualPath = VirtualCacheDir.TrimEnd('/') + '/' + r.RelativePath.Replace('\\', '/').TrimStart('/'); //Rewrite to cached, resized image. context.RewritePath(virtualPath, false); } else { //Remap the response args writer to use the existing stream. ((ResponseArgs)e).ResizeImageToStream = delegate(Stream s) { ((MemoryStream)r.Data).WriteTo(s); }; context.RemapHandler(new NoCacheHandler(e)); } }
public void Process(HttpContext context, IResponseArgs e) { CacheResult r = Process(e); context.Items["FinalCachedFile"] = r.Path; if (r.Data == null) { var keyBasis = e.RequestKey; // Path to the file in the blob container string path = new UrlHasher().Hash(keyBasis) + '.' + e.SuggestedExtension; var container = GetBlobContainer(); using (var stream = container.GetBlockBlobReference(path).OpenRead()) { HandleResponseStream(context, e, stream); } } else { HandleResponseStream(context, e, (MemoryStream)r.Data); } }
public void FirePreHandleImage(System.Web.IHttpModule sender, System.Web.HttpContext context, IResponseArgs e) { System.Threading.Interlocked.Increment(ref processedCount); if (PreHandleImage != null) PreHandleImage(sender, context, e); }
/// <summary> /// Cache selection occurs as follows: (1) The first registered CachingSystem that returns true from .CanProcess() is the default /// (2) The SelectCachingSystem event is fired, allowing handlers to modify the selected cache. /// This method may return null. /// </summary> /// <param name="context"></param> /// <param name="args"></param> /// <returns></returns> public ICache GetCachingSystem(System.Web.HttpContext context, IResponseArgs args) { ICache defaultCache = null; //Grab the first cache that claims it can process the request. foreach (ICache cache in c.Plugins.CachingSystems) { if (cache.CanProcess(context, args)) { defaultCache = cache; break; } } CacheSelectionEventArgs e = new CacheSelectionEventArgs(context, args, defaultCache); if (SelectCachingSystem != null) SelectCachingSystem(this, e); return e.SelectedCache; }
/// <summary> /// Sends the response directly to the client with no caching logic. /// </summary> /// <param name="context"></param> /// <param name="e"></param> public void Process(System.Web.HttpContext context, IResponseArgs e) { context.RemapHandler(new NoCacheHandler(e)); // The following line of code does nothing. I don't think there is any way to make this work before .NET 2.0 SP2 //context.Handler = new NoCacheHandler(e); }
private void Serve(HttpContext context, IResponseArgs e, MemCacheResult result) { context.RemapHandler(new MemCacheHandler(e,result.Data)); }
public static string CalcualteETag(IResponseArgs e) { return (e.RequestKey + (e.HasModifiedDate ? e.GetModifiedDateUTC().Ticks.ToString() : "")).GetHashCode().ToString("x"); }
public void Process(System.Web.HttpContext current, IResponseArgs e) { var modDate = e.HasModifiedDate ? e.GetModifiedDateUTC() : DateTime.MinValue; var key = e.RequestKey + "|" + modDate.Ticks.ToString(NumberFormatInfo.InvariantInfo); CacheEntry entry; byte[] data; //Ensure cache is loaded if (!loaded) Load(); if (!TryGetData(key ,out data, out entry)){ Stopwatch sw = new Stopwatch(); sw.Start(); //Cache miss - process request, outside of lock MemoryStream ms = new MemoryStream(4096); e.ResizeImageToStream(ms); data = StreamExtensions.CopyToBytes(ms,true); sw.Stop(); //Save to cache entry = PutData(key,data, sw.ElapsedMilliseconds); } ((ResponseArgs)e).ResizeImageToStream = delegate(Stream s) { s.Write(data,0,data.Length); }; current.RemapHandler(new NoCacheHandler(e)); if (cache.changes_since_cleanse > ChangeThreshold) CleanseAndFlush(); else if (cache.changes_since_cleanse > 0 && DateTime.UtcNow.Subtract(lastFlush) > new TimeSpan(0, 0, 30)) { Flush(); } }
public bool CanProcess(System.Web.HttpContext current, IResponseArgs e) { return true; }
private static void Serve(HttpContext context, IResponseArgs e, Stream data) { context.RemapHandler(new AzureBlobHandler(e, data)); }
public static string CalcualteETag(IResponseArgs e) { return((e.RequestKey + (e.HasModifiedDate ? e.GetModifiedDateUTC().Ticks.ToString() : "")).GetHashCode().ToString("x")); }
private void Serve(HttpContext context, IResponseArgs e, MemCacheResult result) { context.RemapHandler(new MemCacheHandler(e, result.Data)); }
public void Process(System.Web.HttpContext current, IResponseArgs e) { current.RemapHandler(new Return304Handler(e)); }
public CacheSelectionEventArgs(System.Web.HttpContext context, IResponseArgs responseArgs, ICache defaultCache) { this.context = context; this.responseArgs = responseArgs; this.selectedCache = defaultCache; }
public bool CanProcess(System.Web.HttpContext current, IResponseArgs e) { return(true); }
public void Process(HttpContext current, IResponseArgs e) { var modifiedTime = e.HasModifiedDate ? e.GetModifiedDateUTC() : DateTime.MinValue; var hash = DateTime.MinValue.Equals(modifiedTime) ? this.GetHash(e.RequestKey) : this.GetHash(string.Format("{0}|={1}", e.RequestKey, modifiedTime)); var subDir = string.Format("{0}{1}{2}", this.PhysicalCacheDir, Path.DirectorySeparatorChar, this.GetSubDir(hash)); if (!Directory.Exists(subDir)) { Directory.CreateDirectory(subDir); } var physicalPath = string.Format("{0}{1}{2}.{3}", subDir, Path.DirectorySeparatorChar, this.GetHashString(hash), e.SuggestedExtension); Stream stream; if (File.Exists(physicalPath)) { var data = File.ReadAllBytes(physicalPath); stream = new MemoryStream(data); ((ResponseArgs)e).ResizeImageToStream = s => ((MemoryStream)stream).WriteTo(s); current.RemapHandler(new NoCacheHandler(e)); if (logger.IsDebugEnabled) { logger.Debug("Get image from cached file: " + physicalPath); } } else { var memoryStream = new MemoryStream(4096); e.ResizeImageToStream(memoryStream); memoryStream.Position = 0; var imageWriterKey = ImageWriterManager.GetImageWriterKey(physicalPath, modifiedTime); var imageWriter = this.imageWriterManager.Get(imageWriterKey); if (imageWriter == null) { imageWriter = new ImageWriter(physicalPath, memoryStream, modifiedTime); this.imageWriterManager.Queue(imageWriter, delegate(ImageWriter job) { try { if (logger.IsDebugEnabled) { logger.Debug("Begin writing image to file: " + job.PhysicalPath); } using ( var fileStream = new FileStream(job.PhysicalPath, FileMode.Create, FileAccess.Write, FileShare.None)) { job.GetReadonlyStream().WriteTo(fileStream); fileStream.Flush(); } if (logger.IsDebugEnabled) { logger.Debug("End writing image to file: " + job.PhysicalPath); } } catch (Exception ex) { if (logger.IsErrorEnabled) { logger.Error(ex); } } finally { this.imageWriterManager.Remove(imageWriterKey); } }); } stream = imageWriter.GetReadonlyStream(); } if (stream != null) { ((ResponseArgs)e).ResizeImageToStream = s => ((MemoryStream)stream).WriteTo(s); current.RemapHandler(new NoCacheHandler(e)); } }
public NoCacheHandler(IResponseArgs e) { this.e = e; }
public Return304Handler(IResponseArgs e) { this.e = e; }
public bool CanProcess(System.Web.HttpContext current, IResponseArgs e) { return("true".Equals(e.RewrittenQuerystring["mcache"], StringComparison.OrdinalIgnoreCase)); }
public CacheResult Process(IResponseArgs e) { //Query for the modified date of the source file. If the source file changes on us during the write, //we (may) end up saving the newer version in the cache properly, but with an older modified date. //This will not cause any actual problems from a behavioral standpoint - the next request for the //image will cause the file to be overwritten and the modified date updated. DateTime modDate = e.HasModifiedDate ? e.GetModifiedDateUTC() : DateTime.MinValue; //Verify web.config exists in the cache folder. writer.CheckWebConfigEvery5(); //Cache the data to disk and return a path. CacheResult r = cache.GetCachedFile(e.RequestKey, e.SuggestedExtension, e.ResizeImageToStream, modDate, CacheAccessTimeout,AsyncWrites); //Fail if (r.Result == CacheQueryResult.Failed) throw new ImageResizer.ImageProcessingException("Failed to acquire a lock on file \"" + r.PhysicalPath + "\" within " + CacheAccessTimeout + "ms. Caching failed."); if (r.Result == CacheQueryResult.Hit && cleaner != null) cleaner.UsedFile(r.RelativePath, r.PhysicalPath); return r; }
public void FirePreHandleImage(System.Web.IHttpModule sender, System.Web.HttpContext context, IResponseArgs e) { System.Threading.Interlocked.Increment(ref processedCount); if (PreHandleImage != null) { PreHandleImage(sender, context, e); } }
public MemCacheHandler(IResponseArgs e, byte[] data) { this.e = e; this.data = data; }
public bool CanProcess(System.Web.HttpContext current, IResponseArgs e) { return "true".Equals(e.RewrittenQuerystring["mcache"], StringComparison.OrdinalIgnoreCase); }
public bool CanProcess(System.Web.HttpContext current, IResponseArgs e) { if (((ResizeSettings)e.RewrittenQuerystring).Cache == ServerCacheMode.No) return false; return CanOperate; }
public bool CanProcess(HttpContext current, IResponseArgs e) { //Disk caching will 'pass on' caching requests if 'cache=no'. if (((ResizeSettings)e.RewrittenQuerystring).Cache == ServerCacheMode.No) return false; return Started;//Add support for nocache }