unset X-Varnish header to the backend server but keep it in the response to client

Dridi Boukelmoune dridi at varni.sh
Fri Nov 8 16:25:23 UTC 2019


Hi,

Thank you for taking the time to reach out to this list.

On Fri, Nov 8, 2019 at 8:39 AM EC DIGIT FPFIS <digit.fpfis at gmail.com> wrote:
>
> Dear all,
>
> Currently, I migrate a configuration from Varnish 3 to Varnish 6 but I have an issue concerning unset a header to a backend but keep it in the resp.
>
> Indeed, I cannot use it in vcl_backend_response because it's unset before (vcl_pass/vcl_backend_fetch)...
>
> In the documentation (https://book.varnish-software.com/4.0/chapters/VCL_Subroutines.html), I can see that "if you do not wish to send the X-Varnish header to the backend server, you can remove it in vcl_miss or vcl_pass. For that case, you can use unset bereq.http.x-varnish;." but I cannot use bereq in vcl_miss/vcl_pass.

This is a bug in the varnish book, it lives here:

https://github.com/varnish/varnish-book

> Do you have any idea how to keep this header in vcl_backend_response but without send it to backend?
>
> In Varnish 3, I used it in vcl_miss/vcl_pass and the unset bereq was set in vcl_fetch.

Nowadays you would do that in vcl_backend_fetch, but the tricky part
is that you no longer have access to the client context. So instead
you need to "pollute" your bereq to find that information or use a
different tool like vmod_var or something similar.

> Vcl code:
>
> vcl 4.1;
> import std;
>
> backend dev {
>   .host = "127.0.0.1";
>   .port = "8080";
> }
>
> sub vcl_recv {
>   set req.http.App="App1";
>   set req.backend_hint = dev;
>   return (hash);
> }
>
> sub vcl_miss {
>   unset req.http.App;
> }
>
> sub vcl_pass {
>   unset req.http.App;
> }

Don't do anything in vcl_miss or vcl_pass.

> sub vcl_backend_fetch {
>   unset bereq.http.App;
> }

Here you may do something like this:

sub vcl_backend_fetch {
  if (bereq.http.App) {
    var.set("app", bereq.http.App);
    unset bereq.http.App;
  }
}

> sub vcl_backend_response {
>   if (bereq.http.App) {
>     set beresp.http.Debug = "test";
>     set beresp.ttl = 10s;
>     set beresp.grace = 10s;
>     return (deliver); // not applied
>   }
> }

And here, something like that:

sub vcl_backend_response {
  if (var.get("app")) {
    set beresp.ttl = 10s;
    set beresp.grace = 10s;
    return (deliver);
  }
}

> sub vcl_deliver {
>   set res.http.App;
> }
>
> Goal:
>
> Currently: App header in unset for backend & client (unable to use it in vcl_backend_response)
> Goal: App header can be used for conditions in vcl_backend_response but not sent to the backend

See https://github.com/varnish/varnish-modules/blob/master/docs/vmod_var.rst

Dridi


More information about the varnish-misc mailing list