Last active
March 25, 2019 15:00
-
-
Save section-io-gists/0434f76f707717092bc11dd267ab7752 to your computer and use it in GitHub Desktop.
HTML Streaming solution to cache the HEAD of HTML
This file contains hidden or 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
#Example of HTML Streaming. This gist involves both Varnish and nginx LUA reverse proxies | |
#Varnish: | |
sub vcl_recv { | |
# Do not stream on non-get requests | |
if (req.method != "GET" && req.method != "HEAD" && req.method != "PURGE") { | |
return (pass); | |
} | |
# By defaul disable holepunch unless below cases fall through (do not modify this line) | |
set req.http.X-Holepunch = "false"; | |
# Do not cache section_esi calls | |
if (req.url ~ "section_esi") { | |
set req.http.X-Holepunch = "true"; | |
return (pass); | |
} | |
# Set the set-cookie header for holepunch ajax calls | |
if (req.url ~ "/section/holepunch/setcookie/") { | |
set req.http.X-Parsed-QS = regsuball(req.url, "^(.*)\?(.*)", "\2"); | |
call decodeQueryString; | |
return (synth(750, req.http.X-Parsed-QS)); | |
} | |
# Do not cache URL's that contain a querystring (Can be modified per site design) | |
if (req.url ~ "\?") { | |
return (pass); | |
} | |
# SWITCH for Holepunching | |
set req.http.X-Holepunch = "true"; | |
return(hash); | |
} | |
sub vcl_backend_response { | |
# Hole punch | |
if (bereq.http.X-Holepunch == "true" && beresp.http.Content-Type ~ "text/html") { | |
set beresp.do_esi = true; #Do ESI processing | |
#Never cache /section_esi as this is the body of the page and it could be personalised | |
if (bereq.url ~ "/section_esi") { | |
set beresp.uncacheable = true; | |
set beresp.ttl = 120s; | |
return (deliver); | |
} else { | |
unset beresp.http.Set-Cookie; | |
set beresp.ttl = 900s; | |
return(deliver); | |
} | |
} | |
} | |
sub vcl_synth { | |
if (resp.status == 750) { | |
set resp.http.set-cookie = resp.reason; | |
set resp.status = 204; | |
return (deliver); | |
} | |
} | |
sub decodeQueryString { | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%20", " "); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%21", "!"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%22", {"""}); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%23", "#"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%24", "$"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%25", "%"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%26", "&"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%27", "'"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%28", "("); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%29", ")"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%2A", "*"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%2B", "+"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%2C", ","); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%2D", "-"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%2E", "."); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%2F", "/"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%30", "0"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%31", "1"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%32", "2"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%33", "3"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%34", "4"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%35", "5"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%36", "6"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%37", "7"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%38", "8"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%39", "9"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%3A", ":"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%3B", ";"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%3C", "<"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%3D", "="); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%3E", ">"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%3F", "?"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%40", "@"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%41", "A"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%42", "B"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%43", "C"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%44", "D"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%45", "E"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%46", "F"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%47", "G"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%48", "H"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%49", "I"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%4A", "J"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%4B", "K"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%4C", "L"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%4D", "M"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%4E", "N"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%4F", "O"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%50", "P"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%51", "Q"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%52", "R"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%53", "S"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%54", "T"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%55", "U"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%56", "V"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%57", "W"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%58", "X"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%59", "Y"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%5A", "Z"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%5B", "["); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%5C", {"\"}); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%5D", "]"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%5E", "^"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%5F", "_"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%60", "`"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%61", "a"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%62", "b"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%63", "c"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%64", "d"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%65", "e"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%66", "f"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%67", "g"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%68", "h"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%69", "i"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%6A", "j"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%6B", "k"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%6C", "l"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%6D", "m"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%6E", "n"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%6F", "o"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%70", "p"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%71", "q"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%72", "r"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%73", "s"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%74", "t"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%75", "u"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%76", "v"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%77", "w"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%78", "x"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%79", "y"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%7A", "z"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%7B", "{"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%7C", "|"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%7D", "}"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%7E", "~"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%A2", "¢"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%A3", "£"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%A5", "¥"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%A6", "|"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%A7", "§"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%AB", "«"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%AC", "¬"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%AD", "¯"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%B0", "º"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%B1", "±"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%B2", "ª"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%B4", ","); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%B5", "µ"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%BB", "»"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%BC", "¼"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%BD", "½"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%BF", "¿"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%C0", "À"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%C1", "Á"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%C2", "Â"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%C3", "Ã"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%C4", "Ä"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%C5", "Å"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%C6", "Æ"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%C7", "Ç"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%C8", "È"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%C9", "É"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%CA", "Ê"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%CB", "Ë"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%CC", "Ì"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%CD", "Í"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%CE", "Î"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%CF", "Ï"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%D0", "Ð"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%D1", "Ñ"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%D2", "Ò"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%D3", "Ó"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%D4", "Ô"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%D5", "Õ"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%D6", "Ö"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%D8", "Ø"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%D9", "Ù"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%DA", "Ú"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%DB", "Û"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%DC", "Ü"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%DD", "Ý"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%DE", "Þ"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%DF", "ß"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%E0", "à"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%E1", "á"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%E2", "â"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%E3", "ã"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%E4", "ä"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%E5", "å"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%E6", "æ"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%E7", "ç"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%E8", "è"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%E9", "é"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%EA", "ê"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%EB", "ë"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%EC", "ì"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%ED", "í"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%EE", "î"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%EF", "ï"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%F0", "ð"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%F1", "ñ"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%F2", "ò"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%F3", "ó"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%F4", "ô"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%F5", "õ"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%F6", "ö"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%F7", "÷"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%F8", "ø"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%F9", "ù"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%FA", "ú"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%FB", "û"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%FC", "ü"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%FD", "ý"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%FE", "þ"); | |
set req.http.X-Parsed-QS = regsuball(req.http.X-Parsed-QS, "%FF", "ÿ"); | |
} | |
#LUA component - body_filter_by.lua | |
if not ngx.ctx.eof then | |
if ngx.header.content_type ~= nil and (string.find(ngx.header.content_type,"text/html") or string.find(ngx.header.content_type,"text/css") or string.find(ngx.header.content_type,"javascript")) then | |
if string.find(ngx.header.content_type,"text/html") or string.find(ngx.header.content_type,"text/css") or string.find(ngx.header.content_type,"javascript") then | |
--ngx.log(ngx.WARN,ngx.header.content_encoding .. " appending upstream enc: " .. ngx.var.upstream_http_content_encoding) | |
ngx.log(ngx.WARN,ngx.header.content_encoding) | |
ngx.log(ngx.WARN,ngx.var.upstream_http_content_encoding) | |
if ngx.var.upstream_http_content_encoding == "gzip" then | |
ngx.log(ngx.WARN,"Inside gzip block") | |
local body = ngx.arg[1] -- use local variable to avoid excess use of ngx.arg | |
local is_first_chunk = false | |
if ngx.ctx.inflater == nil then | |
is_first_chunk = true | |
local zl = require("zlib") | |
ngx.ctx.inflater = zl.inflate() | |
-- windowBits 15+16 means default window size of 15 + send a gzip header | |
-- use compression level 5 as guess (override with gzip_comp_level option) | |
ngx.ctx.deflater = zl.deflate(5, 15+16) | |
end | |
local inflate_success, inflated_body, eof = pcall(function() return ngx.ctx.inflater(body) end) | |
if inflate_success then | |
body = inflated_body | |
ngx.ctx.eof = eof | |
else | |
-- inflated_body is the error message if pcall failed | |
local chunkLength = 0 | |
if body ~= nil then chunkLength = string.len(body) end | |
local errorDetail = "Inflater failed. Status code: " .. ngx.status .. ". Chunk length: " .. chunkLength .. ". " .. inflated_body | |
-- gzip header begins 0x1F 0x8B, or decimal 31 139 | |
if not is_first_chunk or ( chunkLength > 2 and string.sub(body, 1, 2) == "\31\139" ) then | |
-- the body looks gzipped but is corrupt | |
ngx.log(ngx.ERR, errorDetail) | |
error("Lua cannot safely continue.") | |
end | |
-- otherwise the Content-Encoding header was most-likely incorrect | |
ngx.log(ngx.WARN, "Assuming incorrect Content-Encoding after: " .. errorDetail) | |
ngx.ctx.inflater = function(input) return input, ngx.arg[2] end -- replace inflater with a no-op function | |
-- we need to gzip on the way out even if the origin didn't because the header says its gzipped and varnish errors otherwise | |
-- ngx.ctx.deflater = function(input, flags) return input, string.len(input), string.len(input), ngx.arg[2] end -- no-op | |
end | |
ngx.arg[1] = body | |
end | |
--ESI hole punch body | |
--Replace <BODY> with ESI request | |
if not string.match(ngx.var.request_uri, "section_esi") | |
and ngx.var.request_method == "GET" and not string.match(ngx.var.request_uri, "?") | |
and string.find(ngx.header.content_type,"text/html") | |
and ngx.req.get_headers()["X_Holepunch"] == "true" | |
then | |
if ngx.ctx.body_detected ~= nil and ngx.ctx.body_detected == true then | |
if string.find(ngx.arg[1], [[</body>]]) then | |
ngx.arg[1] = ngx.re.gsub(ngx.arg[1], [[.*</body>(.*)]], [[$1]], "si") | |
else | |
ngx.arg[1] = ngx.re.gsub(ngx.arg[1], [[(.*)]], [[]], "si") | |
end | |
end | |
if string.find(ngx.arg[1], [[<body]]) then | |
ngx.arg[1] = ngx.re.gsub(ngx.arg[1], [[<body.*]], [[<!-- ESI Start --><esi:include src="]].. [[/section_esi]] .. ngx.var.request_uri .. [["/><!-- ESI Finish -->]], "si") | |
ngx.ctx.body_detected = true | |
end | |
end | |
--Modify the responses under the /section_esi uri to only contain the HTML <BODY>..</BODY> | |
if string.match(ngx.var.request_uri, "section_esi") then | |
if ngx.ctx.body_detected ~= nil and ngx.ctx.body_detected == true then | |
ngx.arg[1] = ngx.re.gsub(ngx.arg[1], [[(.*</body>).*]], [[$1]], "si") | |
else | |
if string.find(ngx.arg[1], [[<body]]) then | |
ngx.arg[1] = ngx.re.gsub(ngx.arg[1], [[(.*)(<body.*)]], [[$2]], "si") | |
ngx.ctx.body_detected = true | |
--Inject any set-cookies found in the HTTP response for body ESI call into HTML | |
local documentJSCookie = '' | |
local ajaxSnippets = '' | |
local resp_headers = ngx.resp.get_headers()["Set-Cookie"] | |
if type(resp_headers) == "table" then | |
for k, v in pairs(resp_headers) do | |
if v == nil then | |
v = '' | |
elseif type(v) == 'table' then | |
v = table.concat(v) | |
end | |
documentJSCookie = documentJSCookie .. [[document.cookie = ']] .. v .. [[';]] | |
local ajaxQueryString = v | |
local ajaxUrl = ngx.escape_uri(ajaxQueryString) | |
ajaxSnippets = ajaxSnippets .. [[var section_ajax_url = new Image();section_ajax_url.src="//www.example.com/section/holepunch/setcookie/?]] .. ajaxUrl .. [[";]] | |
end | |
elseif type(resp_headers) == "string" then | |
documentJSCookie = documentJSCookie .. [[document.cookie = ']] .. resp_headers .. [[';]] | |
local ajaxQueryString = resp_headers | |
local ajaxUrl = ngx.escape_uri(ajaxQueryString) | |
ajaxSnippets = ajaxSnippets .. [[var section_ajax_url = new Image();section_ajax_url.src="//www.example.com/section/holepunch/setcookie/?]] .. ajaxUrl .. [[";]] | |
end | |
ngx.arg[1] = ngx.re.gsub(ngx.arg[1], [[(<body[^>]*>)]], [[$1]] .. [[<script type='text/javascript'>]] .. documentJSCookie .. ajaxSnippets .. [[</script>]], "si") | |
else | |
ngx.arg[1] = ngx.re.gsub(ngx.arg[1], [[(.*)]], [[]], "si") | |
end | |
end | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Note: Need to add the
vcl_synth
code snippet for status750