Examples of ESI Logic in Custom VCL


#1

If you read our first Community Page on ESI, you already know you need to get Custom VCL enabled for your account, and then upload the Fastly boilerplate to your service.

But how do you insert the necessary ESI logic into that boilerplate? Check out the example below.

If you scroll farther down the page, you’ll also see some iterations on that ESI logic, which may be more useful, depending on your particular set-up.

Finally, for a bit more of a deep-dive, take a look at my public repo, which contains the script below. It also holds two brief HTML pages that mirror the structure of how you’d approach CSRF tags in your HTML. At its most basic level, the idea is for your web app to send pages with <esi:include src="/csrf_meta_tags.html" /> and then also send the content to include.

Take a look: https://github.com/andriantoniades/Using-ESI-with-Boilerplate-VCL


Fastly Boilerplate with Basic ESI Logic Inserted:

sub vcl_recv {
#FASTLY recv

    if (req.request != "HEAD" && req.request != "GET" && req.request != "FASTLYPURGE") {
      return(pass);
    }

    return(lookup);
    }

sub vcl_fetch {
#FASTLY fetch

  
  ##############ESI CODE GOES HERE##########################
  if (req.url == "/esi_example") {
    esi;
  }

  if ((beresp.status == 500 || beresp.status == 503) && req.restarts < 1 && (req.request == "GET" || req.request == "HEAD")) {
    restart;
  }

  if(req.restarts > 0 ) {
    set beresp.http.Fastly-Restarts = req.restarts;
  }

  if (beresp.http.Set-Cookie) {
    set req.http.Fastly-Cachetype = "SETCOOKIE";
    return (pass);
  }

  if (beresp.http.Cache-Control ~ "private") {
    set req.http.Fastly-Cachetype = "PRIVATE";
    return (pass);
  }

  if (beresp.status == 500 || beresp.status == 503) {
    set req.http.Fastly-Cachetype = "ERROR";
    set beresp.ttl = 1s;
    set beresp.grace = 5s;
    return (deliver);
  }  

  if (beresp.http.Expires || beresp.http.Surrogate-Control ~ "max-age" || beresp.http.Cache-Control ~"(s-maxage|max-age)") {
    # keep the ttl here
  } else {
    # apply the default ttl
    set beresp.ttl = 3600s;
  }

  return(deliver);
 }

 sub vcl_hit {
 #FASTLY hit
 
  if (!obj.cacheable) {
    return(pass);
  }
  return(deliver);
  }

  sub vcl_miss {
  #FASTLY miss
  return(fetch);
  }

  sub vcl_deliver {
  #FASTLY deliver
  return(deliver);
  }

  sub vcl_error {
  #FASTLY error
  }

  sub vcl_pass {
  #FASTLY pass
  }

Inserting ESI Logic Based on Content Type:

  sub vcl_fetch {
  #FASTLY fetch

  ##############ESI CODE GOES HERE##########################
  if beresp.http.Content-type ~ "(html|js)" { 
  esi;
  }

Inserting ESI Logic Based on the Destination URL:

 sub vcl_fetch {
 #FASTLY fetch
    
 ##############ESI CODE GOES HERE##########################
 if (req.url == "/page/with/include_tag" || req.url == "/other_page/with/include_tag") { 
 esi; 
 }

Keep in Mind:

  • Fastly currently doesn’t support the use of ESI with GZIP. Both the container and the ESI URL need to be uncompressed.

  • If you can’t avoid compression, you may want to explore using AJAX instead.

  • Currently, Fastly only supports the use of double quotes in your ESI tags.


How do I enable basic ESI in my VCL?