简体   繁体   中英

Can I set a cookie value by calling a PHP script from Varnish config

Here's the problem: I have a website, cached by varnish, on which I want to do some A/B testing. In order to do this, varnish needs to show some people one version of the site (across all pages), and other people the alternative (across all pages), while the URL remains the same.

I was thinking of doing this by having varnish read a cookie containing a hash value, and show the user a different cached version based on that. I know Varnish can do that because I already do something similar for dealing with currencies.

Now the question is: I need to set this cookie value on the first page a visitor loads. I need to do it as efficiently as possible of course, and I don't want a page reload (otherwise I could have some javascript check if the cookie value is set, if not do an ajax call + page refresh or something).

How could I achieve this? Is it possible to have varnish check the cookie value, and if nothing is set yet (which should only happen on the first page a visitor visits) call a PHP API (which will determine which version to show to which type of people etc)? Varnish can then use this value, and proceed as if the cookie value was already there. The PHP API can write the returned value into a cookie for the next page load.

Alternatively: Is there a better way to get the behaviour I want?

Edit: Basically I'm looking for a way to set the cookie with a value generated by a PHP script (or command line command) without having to let the request hit the backend.

I think there are other/better ways to do A\\B testing without consequences for your caching. Have a look at tools like Visual Website Optimizer or Optimizely, which do everything via javascript.

Still want to build it by yourself? Use javascript or ESI blocks to get the variations. The specific AJAX/ESI response could be non-cachable and you can allow sending the cookies to this requests.

If you really want Varnish to do it instead of your backend. You could build this into a vmod on inline C. And, if you really want to run a command line script you can call popen() from within your C code (either inline or compiled into your vmod.

Here's a basic example:

sub vcl_recv
{
    C{
       const struct gethdr_s hdr = { HDR_REQ, "\07Cookie:" };

       char str[128] = "";

       // Use popen() to run your command and save the result in str[]
       FILE *fp = popen("some_command_to_run", "r");
       if (fp)
       {
           fgets(str, sizeof(str) - 1, fp);
           fclose(fp);
       }

       // Add str as the value to the header
       VRT_SetHdr(ctx, &hdr, str, vrt_magic_string_end);
    }C

    ...
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM