Search code examples
azureazure-blob-storagecdncloudflareimageresizer

Pass thru data/time modified from Azure Blobstore to CDN via Imageresizer


We've just moved our image hosting to Azure with Imageresizer (v 4.0.5.942) fronted by Cloudflare's CDN but are finding the CDN retains a cached image when the image has changed back on the Azure blobstore.

We used the same CF CDN and Imageresizer on our outgoing image hosting which was an iis box with Imageresizer diskcaching set and didn't have the issue.

The plugin section of our Azure imageresizer config files is -

<add name="AzureReader2" prefix="~/"connectionString=
"DefaultEndpointsProtocol=httpsAccountName=reiwastorstagimg
 AccountKey=xyzxyxyyz"`
checkForModifiedFiles="true" />

A test image is via CDN - http://azstagingimage.reiwa.com.au/listing/09/2635009-04.jpg?maxwidth=724&maxheight=543&quality=100

Direct to Imaresizer App - http://azstagingimage3.reiwa.com.au/listing/09/2635009-04.jpg?maxwidth=724&maxheight=543&quality=100

On prem the config contained -

<resizer>
    <plugins> 
     <add name="DiskCache" />
    </plugins>


<diskCache autoClean="false" hashModifiedDate="true" subfolders="1024" />
</resizer>

My thinking is when we were on prem with diskcaching turned on, Imageresizer would check the original images date/time stamp, compare it to its cached versions date/time and if changed, would re process the image thereby changing the cached images date/time modified stamp which in turn was picked up by the CDN, causing a re-read.

Looking at the Imageresizer documentation, I believe checkForModifiedFiles="true" would cause Imageresizer to go back to the blob store, get the originating files modified date and pass that to the CF CDN (or browser) but we have it set and it's not doing as we expected.

Does anyone know if there's a way around this or do I need to turn diskcache on in the cloud too?

Thank you in advance. Kieron


Solution

  • ImageResizer stopped serving the "original image" modified date in v3 (for processed requests) - it seems harmless but caused widespread breakage. Some browsers and proxies unfortunately compare last-modified to last fetch dates. It would be nicer to have it behave like an etag, but it doesn't. Last-modified has to be date of output generation or a wide range of side effects start occurring.

    checkForModifiedFiles won't have much relevance without DiskCache enabled.

    When disk cache is enabled, ImageResizer serves a stable modified date/etag based on when the result was cached. Without disk cache, ImageResizer doesn't send a last-modified date. Typically this doesn't have the effect of causing a CDN to never validate, though, but rather the opposite - too frequent invalidation.

    ImageResizer usually plays nice with IIS and ASP.NET header configuration, and in some configurations a last-modified is always set to utcnow. But that's not happening on your server.

    The path of least pain is usually the utilization of cache-breakers (like &r=31512351), or treating all blobs as immutable. The high latency of invalidation checks is usually unacceptable for ImageResizer users, and the immutable blob approach is quite popular.

    ImageResizer is decent at caching headers with DiskCache, but when there's no storage or way to preserve state - it's hard to have a solution that isn't breaking something with its cache choices.

    ImageResizer could do better, though.

    If you want custom behavior, PreSendRequestHeaders is an easy spot to make changes. It's also pretty easy to swap out the NoCache and ClientCache plugins for your own classes if you want full control.