Can I set set req.backend.host dynamically

Comments

4 comments

  • Justin

    Hi mpapper

    Yes, you can change the Host header depending on the request. However, when you have one Fastly service serving different origins or domains you need to bear in mind:

    1) Any change to the service will affect requests for all of the origins or domains. This may be fine for one.example.com and two.example.com, but may not be what you want for dev, staging and www.example.com

    2) If you are serving different content for the same URL you'd need to set the Vary header to let the cache to store different versions based on a specific header. In the case you've mentioned you will be OK as the default cache key is composed of the Host header + the path/query string, but if you were to change that algorithm to take another header into consideration you'd need to use Vary.

    Alternatively an easier way to set up the backends than using the UI may be to use the API instead:

    https://docs.fastly.com/api/config#backend

    https://docs.fastly.com/api/config#condition

    That might be something to consider.

  • devforce

    Thanks Jason for the response. I want to be sure though: I'm not changing the host header I'm changing the backend's data structure - the host field in particular. This way I would have just one backend in my custom VCL and switch the backend.host value for each and every request (that is not cached) based on my rules for deciding on the proxying to the backend. In my case I have 10 different backends (per each of qa, staging and production) to deal with and thought it would be easier to have just 1 backend in my VCL code and chnage its .host value dependent on the request.

    I take your point about one.example.com and two.example.com versus using the same VCL for qa, staging and production domains. I think I need a way to test my VCL in qa/staging before putting into production and would want to keep each of these in separate "services".

  • Andrew Betts

    To be clear here, there are two hostnames to consider. The one attached to the definition of an origin is there to allow us to resolve an IP address to which we send origin fetches. The second hostname is the value of the Host: header that we send to that server in the fetch.

    The first of those, the hostname for IP lookup, is not something you can change dynamically, but you can configure more than one of them. The Host header that is sent to the backend IS dynamically configurable - it's just a string variable.

    So, this means that while it is NOT possible to reach out to an arbitrary backend server based on a full URL specified in the request, like this:

    set req.backend = req.http.X-Backend-Host; // This doesn't work

    You CAN do any of the following:

    1. If all potential backend hostnames would resolve to the same set of IPs, eg if your backends are all on Heroku (in the same Heroku region) or behind some other router that deals with lots of hostnames, then you can safely define one backend using any one of your backend host names, and then change the req.http.host header to tell Heroku's router which of your backend apps you want to send the request to.

    2. If you have programmatic control over the DNS for your backends, you can change the IP addresses we connect to by changing the address to which your backend hostnames resolve. This will have a latency dictated by your DNS records' TTLs, and we may impose a minimum TTL too. Some customers do use this to swap out backends without changing their VCL, but it's more common to do it with multiple backends defined in VCL.

    3. We offer 'dynamic servers': https://docs.fastly.com/guides/dynamic-servers/creating-and-using-server-entries-with-dynamic-servers. These allow you to change the definition of a backend, including the hostname used for address resolution, without activating a new version of your configuration. BUT this won't affect any in-flight requests.

  • sefulevuv

    Hi, I've got the same problem as mpapper, I need to change req.backend.host dynamically from VCL without an API call.

    I tried with 127.0.0.1 as the only backend and generating a synth in vcl_deliver followed by a restart, hoping that fastly will take that synth as input, but It doesn't work as expected. Fastly retain only the req var between restarts.

    May someone reply to mpapper question? :roll_eyes:

Please sign in to leave a comment.