Serve images directly from cache with Responses


#1

I’m wondering if it’s possible to serve a static image file using a custom response setup in the web interface. I see that we have the ability to change the mime type, but it looks like the response only allows for text.

Is there any way to get it to serve a static image when certain conditions are matched, or do we have to present that from our host in order to get it cached?


#2

Hi James,

Since the Responses are put into the VCL, and the VCL is compiled to C and then to machine code, they have to be text.

However, there’s a few tricks you can use:

  1. Use SVG images, since they’re basically XML.

  2. If the images are used by HTML Responses, use data URLs instead. See http://www.websiteoptimization.com/speed/tweak/inline-images/

  3. If you manage to make an image file without any NULL bytes in it, you could base64 encode it and use our base64 decoder. In the Response you would put something like:

    "} digest.base64_decode("MrGUN17QSAtJ5UfyQOwt9A==") "{
    

    The "} at the start is to close the long string (that’s a Varnish term) that the Response is contained in, so we can use functions and variables, and the "{ at the end is to start the containing long string again, to keep the compiler happy. But because VCL doesn’t do binary, but only deals with strings, the image must not contain any NULL bytes, since NULL bytes are string terminators.

I hope that helps.


#3

I did some additional research into this today and thought I’d add to the thread. The problem of not being able to represent data in our STRING data type if it contains a null byte is something we hope to address soon. In the meantime, it’s worth documenting that

  • PNG format images are impossible to represent without null bytes, because each chunk starts with a fixed 8 byte header that specifies the length of the chunk as a 4-byte sequence. If any chunk is shorter than 16MB, the highest order byte in that chunk’s header will be a null byte.
  • GIF also requires null bytes. The first nulls in a GIF are the terminators for the width and height of the canvas, so it’s also impossible to create a GIF without nulls.
  • JPEG uses null bytes to separate image chunks.

So all conventional image formats are going to fall foul of this. The only option that would work is an SVG containing an embedded image, inlined using a data: uri. This would mean that the image data would leave the Fastly server still in base64 encoded form, and would only be decoded on the browser. However, there’s really no sensible reason to do this!