0

I have implemented a VirtualPathProvider to return Theme files (images,css) for an Azure web site from the Azure CDN. It is working fine apart from one thing: the files that are coming from the CDN all have their cache control property set to "private" and so are never cached.

The actual blobs have their properties set correctly and if I access one by it's direct URL (i.e. not through the VPP) then the cache control is correct.

The problem seems to be in the Open() method of the VirtualFile class I have to implement to return the file as a Stream?

public override Stream Open()
    {
        CloudBlobClient client = new CloudBlobClient(cdnURL);
        CloudBlob blob = client.GetBlobReference(blobURL);
        blob.FetchAttributes();
        MemoryStream stream = new MemoryStream();
        BlobRequestOptions options = new BlobRequestOptions();
        options.BlobListingDetails = BlobListingDetails.Metadata;
        blob.DownloadToStream(stream,options);
        stream.Seek(0, SeekOrigin.Begin);
        return stream;
    }

Searching on this and I find most people have the problem the other way - i.e. files are cached when they don't want them to be. However none of the examples I can find are referencing a file from another URL. They all seem to use databases or just different physical paths.

Mad Pierre
  • 440
  • 2
  • 11

2 Answers2

2

Thanks to this answer on the asp.net forum http://forums.asp.net/post/4716700.aspx

I have resolved the issue by adding in my Open() method:

HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.Public);
HttpContext.Current.Response.Cache.AppendCacheExtension("max-age=86400");
Mad Pierre
  • 440
  • 2
  • 11
1

I think you may have missed a crucial point in how the CDN gains it's advantage. The CDN helps by putting the resources closer to the client requesting the file. i.e when the client requests the file it goes straight to the CDN URL. What seems to be happening here is you're downloading the file from the CDN to you code that's running web server and then returning the stream to the client from there.

Please correct me if I'm wrong.

It's also worth noting that the cache properties are not part of the file stream that you're returning, they're additional properties that can be found in CloudBlob.Properties.CacheControl

knightpfhor
  • 9,299
  • 3
  • 29
  • 42
  • I understand that the CDN is designed to do that. However I have a requirement to put all the Theme files in the CDN and a VirtualPathProvider seems to be the only way to do it? Any other suggestions gratefully received.... The reason I call GetProperties() is to populate CloudBlob.Properties.CacheControl Does that not get put into the stream when the blob is converted? I did another test project to read the stream myself and it would appear it is. – Mad Pierre Nov 23 '11 at 08:13
  • You have raised a good point in that we are efectively defating the point of the CDN though! I'll raise it like that with the supplier of my requirements! – Mad Pierre Nov 23 '11 at 08:29
  • Rather than returning the stream of the file in the CDN, if you refactor your code so that you return the path to the file in the CDN, the client can then be responsible for retrieving it. This is without knowing exactly how you're using this function though. – knightpfhor Nov 23 '11 at 09:55
  • Can't do that knightpfhor. when implementing a VirtualPathProvider the necessary override returns a stream. – Mad Pierre Nov 23 '11 at 13:10
  • My question then would be do you need to use the VirtualPathProvider? What advantages is it giving you at the moment? – knightpfhor Nov 23 '11 at 18:39
  • The main advantage is that we can add/remove/change themes without re-deploying the site – Mad Pierre Nov 25 '11 at 08:57
  • We are now just using this to get the css files. The urls to the images are absolute to the images in the cdn. This means we do benefit from the cdn for the images. The problem still remains for the css files though. – Mad Pierre Nov 25 '11 at 09:05