-
Notifications
You must be signed in to change notification settings - Fork 1
Home
Varnish vmod that enables you to add custom HTTP headers to the client request and response via whatever native programming language you prefer (PHP, Node, Ruby, Python, etc).
You might be asking yourself, why would I add latency to my super fast cached responses by adding an extra HTTP call? Doesn't that defeat the pupose of a caching proxy? It's a great question. The answer is yes, it does add latency. The amount of latency of course is dependant on how fast your web script is. What the vmod gives you is additional ways to integrate Varnish into your stack that you might not have had before, or were just too complex. Remember that in addition to fast client responses, Varnish also keeps potentially expensive traffic off your backend, so the more ways you can use it the better.
Note that the web script you send requests to does not actually modify the client request or response directly. Instead your script outputs a json formatted list of headers it wants the vmod to add.
For installation and vmod method details see the README.
Also check out the canonical example for inspiration.
Usage involves:
- Writing and hosting the web script you want to send requests to. See WEB SCRIPT for details.
- Add the appropriate vmod functions to your vcl. See VCL for details.
You must host a web script that the vmod can send requests to. This script is something you write. It will be called by the vmod and must return a JSON response containing any headers it wants added, if any.
The vmod will call your web script with an HTTP GET request containing a copy of the same headers the client sent. The exception to this is the HTTP method and url headers. For those you will receive these additional headers:
-
X-Forwarded-Method Contains HTTP method requested by the client (
GET,POST,PUT, etc) -
X-Forwarded-Url Contains the
urlrequested by the client. - X-Forwarded-For Contains client IP.
Your web script must return a Content-Type: application/json response whose body is a json formatted string with the headers it wants the vmod to add. The vmod will set those headers in Varnish's vcl_recv and vcl_deliver methods. Here is an example response:
{
'vcl_recv': {
'X-Geo: us',
'X-Device: tablet'
},
'vcl_deliver': {
'Set-Cookie: geo=us',
'Set-Cookie: device=tablet',
}
}
In this example you are requesting that inside vcl_recv the vmod add two headers to the client request, and inside vcl_deliver add two cookie headers to the client response.
<?php
if (false == isset($_COOKIE['geo'])) {
$geo = geo_lookup($_SERVER['HTTP_X_FORWARDED_FOR']);
}
header('Content-type: application/json');
echo json_encode(array(
'vcl_recv' => array(
"X-Geo: $geo",
),
'vcl_deliver' => array(
"Set-Cookie: geo=$geo"
)
));
This example shows how you can prepare a request to vary a response on geo location. First we do the geo lookup. Next, via the JSON, we request an X-Geo header be added to the client request. Finally we request a
Set-Cookie header be added to the response going to the client. Setting a cookie allows us to bypass the potentially expensive geo lookup at the top of the script.
On the Varnish side after a cache miss (or pass), here is what a client request that goes to the backend might look like after headerproxy.call() in vcl_recv has done its thing. The X-Geo header was automatically inserted by the vmod.
GET /index.html HTTP/1.1
Host: www.example.com
X-Geo: us
And here is an example response from the backend. Note that your backend app (not the vmod web script) needs to add the Vary header. Its up to you how to implement this logic (see the canonical example directory for details).
HTTP/1.1 200 OK
Content-type: text/html
Vary: X-Geo
And here is the response to the client after the headerproxy.process() call in vcl_deliver. The Set-Cookie header was automatically inserted by the vmod.
HTTP/1.1 200 OK
Content-type: text/html
Set-Cookie: geo=us
To call your web script you first add a headerproxy.call() call into vcl_recv. This method takes two parameters.
The first parameter to headerproxy.call() is a Varnish backend (or director). The vmod will use this backend to determine the hostname of the server hosting your web script. It can be a dedicated backend/director just for your web script, or more simply it can be the same backend used by your application backends by passing req.backend_hint as the param.
The second parameter to headerproxy.call() is a string containing the path
to your script. For example "/webscript".
Calling headerproxy.call() does the following:
- Using curl the vmod sends the client request to the url of your web script. Your script will get an identical copy of all client request headers (see
Request from vmod_). - Your web script will return a list of headers that the vmod will add to the request (see
Response back to vmod_). - The vmod will insert the headers specified in a
vcl_recvjson key into the clientrequest. TIP: Headers you add here can be referenced by aVaryresponse header, which is where the real power comes in.
Finally you add a headerproxy.process() in vcl_deliver (see process_). The vmod will insert the headers requested in a vcl_deliver json key into the client response. TIP: Headers set here wont be cached. Its the ideal place to insert Set-Cookie headers.