VCL Shield Detection


#1

Hi all,

Short version: I’m looking for a built in variable, or recommended VCL conditional snippet that will return true only on the Origin Shield servers.

Long version: I’m attempting to send requests for “^/p/special/…” to our special backend, minus the “/p/special” prefix… and I’d like to shield that backend.
I have set-up the conditional “special” backend basically following the example here: https://docs.fastly.com/guides/conditions/using-conditions
I have also added VCL to alter the backend request:

sub vcl_miss {   
  if (req.url ~ "^/p/special/") {
     set bereq.url = regsub(bereq.url, "^/p/speicial/", "/");
  }
}

This works fine, until I enable shielding - because the vcl_miss snippet gets executed twice. I need a way to isolate it so it will only run on the shield and not the edge.


#2

Hi

Yes, you can use req.http.fastly-ff to test if the node is in a shield POP. If it’s set the request has passed through another POP already.

See https://docs.fastly.com/guides/performance-tuning/shielding for details.


#3

Thanks, I’ll give that a go!

I previously tried using fastly_info.is_cluster_edge as described here - https://docs.fastly.com/guides/performance-tuning/request-collapsing#determining-if-a-cache-is-an-edge-or-a-shield - but it didn’t work as expected.

I’ll have a crack with req.http.fastly-ff instead… although, having slept on the problem, I know realise that I’ll need some more extensive logic to ensure this continues to work if the shield PoP is down for whatever reason.


#4

fastly_info.is_cluster_edge has to do with clustering, within a datacenter. Shielding involves multiple datacenters. So “edge” is correct, but is on a different scale/level.

As for the best solution for this, since you’re not specifically caring whether you’re on the shield, but actually care whether the current machine is going to talk to the origin, instead of another Fastly POP, the following strategy might be better:

In vcl_miss, check whether req.backend == F_your_origin and only if that’s the case, remove the part from the URL you want gone. (Also, in your code above there seems to be a typo in special.) This works because we set req.backend to the shield director if the request needs to go there next.

So, something like:

sub vcl_miss {   
  if (req.backend == F_special_origin && req.url ~ "^/p/special/") {
     set bereq.url = regsub(bereq.url, "^/p/special/", "/");
  }
}

#5

Ugh, duh! Of course! Thanks for that.

Actually, thinking about it, the req.url check is actually superfluous, since that is already checked in vcl_recv to switch backends. So now I just have:

    sub vcl_miss {   
      if (req.backend == F_special_origin) {
         set bereq.url = regsub(bereq.url, "^/p/special/", "/");
      }
    }

Working like a charm, on edge and shield POPs.

Thanks again!