Ted
Ted

Reputation: 7251

Using ImageResizer to resize PDF sometimes leads to exception which does not resolve until restart application pool

We're using ImageResizer (imageresizing.net) to generate thumbnails of the front page of PDFs. It works great (as does pretty much everything else to do with ImageResizer) except for the following scenarios which I'm posting here with likely inadequate information in the hopes that someone has experienced the same issue/s with a proper resolution.

1) Out of several thousand PDFs, there a couple PDFs that will not allow thumbnail generation. Each attempt leads to the following exception:

Message :  An error occurred while parsing EntityName. Line 3, position 85.
Source: System.Xml
Stack Trace : 
at System.Xml.XmlTextReaderImpl.Throw(String res, String arg)
at System.Xml.XmlTextReaderImpl.ParseEntityName()
at System.Xml.XmlTextReaderImpl.ParseEntityReference()
at System.Xml.XmlTextReaderImpl.Read()
at System.Xml.XmlReader.ReadString()
at System.Xml.XmlReader.ReadElementString()
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderPdfInfo.Read4_PdfInfo(Boolean isNullable, Boolean checkType)
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderPdfInfo.Read5_pdf()

TargetSite : Void Throw(System.String, System.String)

Our assumption is that the actual PDF file is actually corrupt in some way (whether metadata or otherwise) leading to an exception when attempting to parse it in. Unfortunately, regenerating them from source is not possible (source no longer available).

There doesn't appear to be any GhostScript or ImageResizer bugs posted with this problem.

2) When attempting to generate thumbnails on multiple PDFs at once (i.e. batches of > ~100), it usually works fine, but occasionally it kicks the can on one PDF (no rhyme or reason) and all subsequent thumbnail generation attempts fail until the application pool is restarted. Ouch. Initially we weren't too concerned because we were only doing batch generation at the beginning and subsequent thumbnail generations would be on much smaller numbers. However, we've since discovered even with smaller numbers this problem occasionally pops up. We're automatically alerted, but having to reset the app is a pretty big sledgehammer to have to use.

Source: ImageResizer
Stack Trace : 
 at ImageResizer.ImageBuilder.LoadImage(Object source, ResizeSettings settings, Boolean restoreStreamPos)
 at ImageResizer.ImageBuilder.BuildJob(ImageJob job)
 at ImageResizer.ImageBuilder.Build(ImageJob job)
 at ImageResizer.ImageBuilder.Build(Object source, Object dest, ResizeSettings settings, Boolean disposeSource, Boolean addFileExtension)
 at ImageResizer.ImageBuilder.Build(Object source, Object dest, ResizeSettings settings, Boolean disposeSource)
 at ImageResizer.ImageBuilder.Build(Object source, Object dest, ResizeSettings settings)
 at ImageResizer.InterceptModule.<>c__DisplayClass2.<HandleRequest>b__1(Stream stream)
 at ImageResizer.Plugins.DiskCache.CustomDiskCache.<>c__DisplayClasse.<TryWriteFile>b__d()
 at ImageResizer.Plugins.DiskCache.LockProvider.TryExecute(String key, Int32 timeoutMs, LockCallback success)
 at ImageResizer.Plugins.DiskCache.CustomDiskCache.TryWriteFile(CacheResult result, String physicalPath, String relativePath, ResizeImageDelegate writeCallback, DateTime sourceModifiedUtc, Int32 timeoutMs, Boolean recheckFS)
 at ImageResizer.Plugins.DiskCache.CustomDiskCache.GetCachedFile(String keyBasis, String extension, ResizeImageDelegate writeCallback, DateTime sourceModifiedUtc, Int32 timeoutMs, Boolean asynchronous)
 at ImageResizer.Plugins.DiskCache.DiskCache.Process(IResponseArgs e)
 at ImageResizer.Plugins.DiskCache.DiskCache.Process(HttpContext context, IResponseArgs e)
 at ImageResizer.InterceptModule.HandleRequest(HttpContext context, String virtualPath, NameValueCollection queryString, IVirtualFile vf)
 at ImageResizer.InterceptModule.CheckRequest_PostAuthorizeRequest(Object sender, EventArgs e)
 at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
 at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
 TargetSite : System.Drawing.Bitmap LoadImage(System.Object, ImageResizer.ResizeSettings, Boolean)

On this one, we assume it's a memory/resource issue, but again, without being able to faithfully reproduce the problem here's hoping somebody else has run into the problem and has tracked down a solution.

Utilizing the following in App Start to force image generation of a specific size and type of all PDFs in specified folder (handling actual access to PDFs via a different route for authentication and download tracking):

        Config.Current.Pipeline.Rewrite += delegate(IHttpModule sender, HttpContext context, IUrlEventArgs ev)
        {
            if (!ev.VirtualPath.StartsWith(VirtualPathUtility.ToAbsolute("~/pdf/"), StringComparison.OrdinalIgnoreCase))
                return;

            ev.QueryString["width"] = "160";
            ev.QueryString["format"] = "png";
        };

Upvotes: 2

Views: 555

Answers (1)

Lilith River
Lilith River

Reputation: 16468

GhostScript will crash permanently if more than one instance is started in the same executable.

  • This will happen if you have more than one application or application folder in a app pool
  • Or if you have not manually disabled overlapped recycling.

[Update]

The PDF-specific issue is due to un-encoded ampersands in the metadata; this is a flaw in the PostScript script which returns info about a PDF, and should be fixable.

Upvotes: 4

Related Questions