Last active
December 27, 2015 14:29
-
-
Save xdamman/7340863 to your computer and use it in GitHub Desktop.
Make Varnish 3.x handle jsonp requests so that we can cache them (even when jQuery generates random callback function names when using $.getJSON). Inspired by https://gist.github.com/simonw/640331 and adapted for Varnish 3.x.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#<jsonp> | |
# We go BACK to varnish to get it to generate an ESI template that | |
# generates a JSON-P response. | |
backend jsonp_template_backend { | |
.host = "127.0.0.1"; | |
.port = "80"; # use the port that varnish is listening on | |
} | |
# <jsonp> | |
# 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=") { | |
set req.http.X-Callback = regsub( | |
req.url, ".*[\?&]callback=([\.A-Za-z0-9_]+).*", "\1" | |
); | |
set req.http.X-ESI-Url = regsub(req.url, "&?callback=[\.A-Za-z0-9_]+", ""); | |
# 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, "\?&", "?"); | |
# Remove %22 (") | |
set req.http.X-ESI-Url = regsub(req.http.X-ESI-Url, "%22", ""); | |
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) { | |
remove beresp.http.X-ESI; | |
set beresp.do_esi = true; | |
} | |
} | |
sub vcl_fetch { | |
# X-JSONP-Server means we need to clean up the response a bit | |
if (beresp.http.X-JSONP-Server) { | |
remove beresp.http.X-JSONP-Server; | |
remove beresp.http.Via; # Gets added again later on, but a bit less messy | |
remove beresp.http.Retry-After; | |
set beresp.http.Server = "JSONP-Server"; | |
} | |
} | |
# 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; charset=utf8"; | |
set obj.http.X-ESI = "1"; | |
set obj.http.X-JSONP-Server = "1"; | |
set obj.status = 200; | |
set obj.response = "OK"; | |
synthetic {"<esi:include />"} + req.http.X-Callback + {"(<esi:include src="} + req.http.X-ESI-Url + {" />)"}; | |
return(deliver); | |
} | |
} | |
# </jsonp> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment