Skip to content

Instantly share code, notes, and snippets.

@howardr
Created April 29, 2011 16:07
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save howardr/f1d91b64acdb3f1d7769 to your computer and use it in GitHub Desktop.
Example varnish config w/ jsonp hack
backend default {
.host = "localhost";
.port = "81";
}
backend jsonp_template_backend {
.host = "localhost";
.port = "80";
}
# How the jsonp_template_backend dispatches to the ESI generating code:
sub vcl_recv {
if (req.url == "/JSONP-ESI-TEMPLATE") {
error 760;
}
}
sub vcl_recv {
# If URL includes callback=, rewrite to an ESI template
if (req.url ~ "(?:callback|jsonp)=" && req.url ~ "\.(json|js)") {
set req.http.X-Callback = regsub(
req.url, ".*[\?&](?:callback|jsonp)=([^&]+).*", "\1"
);
set req.http.X-ESI-Url = regsub(req.url, "&?(?:callback|jsonp)=[^&]+", "");
# Remove a trailing ?
set req.http.X-ESI-Url = regsub(req.http.X-ESI-Url, "\?$", "");
# Fix any accidental ?&
set req.http.X-ESI-Url = regsub(req.http.X-ESI-Url, "\?&", "?");
set req.url = "/JSONP-ESI-TEMPLATE";
set req.backend = jsonp_template_backend;
return (pass); # NEVER cache template, since it varies on X-Callback/ESI-Url
}
}
sub vcl_fetch {
# X-ESI: 1 from backend triggers ESI processing
if (beresp.http.X-ESI) {
unset beresp.http.X-ESI;
esi;
}
}
sub vcl_fetch {
# X-JSONP-Server means we need to clean up the response a bit
if (beresp.http.X-JSONP-Server == "1") {
set beresp.http.X-JSONP-Server = "2";
unset beresp.http.Via; # Gets added again later on, but a bit less messy
unset beresp.http.Retry-After;
unset beresp.http.X-Varnish;
}
}
sub vcl_deliver {
if(resp.http.X-JSONP-Server == "2") {
unset resp.http.X-JSONP-Server;
set resp.http.Cache-Control = "no-store, max-age=5, private";
}
}
# We're using a custom error here because it's the only way I could find to get # varnish to compose a custom response.
sub vcl_error {
if (obj.status == 760) {
set obj.http.Content-Type = "application/javascript";
set obj.http.X-ESI = "1";
set obj.http.X-JSONP-Server = "1";
set obj.status = 200;
set obj.response = "OK";
synthetic
"<esi:include />" # Blank directive, needed to avoid this error:
# ESI_xmlerror: No ESI processing, first char not '<'
req.http.X-Callback
"(<esi:include src=%22" req.http.X-ESI-Url "%22 />)";
return(deliver);
}
}
# Base config for normal traffic
sub vcl_recv {
// varnish won't cache requests with cookies
if (req.http.host ~ "^api\.tweetriver\.com$" || req.url ~ "\.(json|rss|atom|xml|js|css)") {
remove req.http.Cookie;
set req.http.X-API-Request = "1";
}
// allow requests to send old stale data for up to 30s if
// server is taking too long
set req.grace = 30m;
}
sub vcl_fetch {
set beresp.grace = 30m;
if(beresp.cacheable) {
set beresp.http.X-TR-Cached = "yes";
set beresp.http.X-TR-TTL = beresp.ttl;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment