-
-
Save nosun/0cfb58d3164f829e2f027fd37b338ede to your computer and use it in GitHub Desktop.
Delete NGINX cached items with a PURGE with wildcard support
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
-- Tit Petric, Monotek d.o.o., Tue 03 Jan 2017 06:54:56 PM CET | |
-- | |
-- Delete nginx cached assets with a PURGE request against an endpoint | |
-- supports extended regular expression PURGE requests (/upload/.*) | |
-- combine single,all,match three mode | |
-- updated by nosun [email protected] | |
local md5 = require 'md5' | |
function file_exists(name) | |
local f = io.open(name, "r") | |
if f~=nil then io.close(f) return true else return false end | |
end | |
function explode(d, p) | |
local t, ll | |
t={} | |
ll=0 | |
if(#p == 1) then return {p} end | |
while true do | |
l=string.find(p, d, ll, true) -- find the next d in the string | |
if l~=nil then -- if "not not" found then.. | |
table.insert(t, string.sub(p, ll, l-1)) -- Save it in our array. | |
ll=l+1 -- save just after where we found it for searching next time. | |
else | |
table.insert(t, string.sub(p, ll)) -- Save what's left in our array. | |
break -- Break at end, as it should be, according to the lua manual. | |
end | |
end | |
return t | |
end | |
function purge(filename) | |
if (file_exists(filename)) then | |
os.remove(filename) | |
end | |
end | |
function trim(s) | |
return (string.gsub(s, "^%s*(.-)%s*$", "%1")) | |
end | |
function exec(cmd) | |
local handle = io.popen(cmd) | |
local result = handle:read("*all") | |
handle:close() | |
return trim(result) | |
end | |
function list_files(cache_path, purge_upstream, purge_pattern) | |
local result = exec("/usr/bin/find " .. cache_path .. " -type f | /usr/bin/xargs --no-run-if-empty -n1000 /bin/grep -El -m 1 '^KEY: " .. purge_upstream .. purge_pattern .. "' 2>&1") | |
if result == "" then | |
return {} | |
end | |
return explode("\n", result) | |
end | |
function cache_filename(cache_path, cache_levels, cache_key) | |
local md5sum = md5.sumhexa(cache_key) | |
local levels = explode(":", cache_levels) | |
local filename = "" | |
local index = string.len(md5sum) | |
for k, v in pairs(levels) do | |
local length = tonumber(v) | |
-- add trailing [length] chars to index | |
index = index - length; | |
filename = filename .. md5sum:sub(index+1, index+length) .. "/"; | |
end | |
if cache_path:sub(-1) ~= "/" then | |
cache_path = cache_path .. "/"; | |
end | |
filename = cache_path .. filename .. md5sum | |
return filename | |
end | |
function file_exists(name) | |
local f=io.open(name,"r") | |
if f~=nil then io.close(f) return true else return false end | |
end | |
function purge_single() | |
local cache_key = ngx.var.lua_purge_upstream .. ngx.var.request_uri | |
local filename = cache_filename(ngx.var.lua_purge_path, ngx.var.lua_purge_levels, cache_key) | |
if file_exists(filename) then | |
purge(filename) | |
return 1 | |
else | |
return 0 | |
end | |
end | |
function purge_multi() | |
local files = list_files(ngx.var.lua_purge_path, ngx.var.lua_purge_upstream, ngx.var.request_uri) | |
for k, v in pairs(files) do | |
purge(v) | |
end | |
return table.getn(files) | |
end | |
function purge_all() | |
local number = exec("/usr/bin/find " .. ngx.var.lua_purge_path .. " -type f | /usr/bin/wc -l") | |
os.execute('rm -rd "'..ngx.var.lua_purge_path..'/"') | |
return number | |
end | |
function get_function(uri) | |
local func | |
if(uri == '/purge_all.html') then | |
func = 'purge_all' | |
elseif(string.find(uri,'*')) then | |
func = 'purge_multi' | |
else | |
func = 'purge_single' | |
end | |
return func | |
end | |
if ngx ~= nil then | |
-- list all cached items matching upstream+request_uri (extended regex) | |
local func = get_function(ngx.var.request_uri) | |
local count = _G[func]() | |
ngx.header["Content-type"] = "text/plain; charset=utf-8" | |
ngx.header["X-Purged-Count"] = count | |
ngx.say('OK') | |
ngx.exit(ngx.OK) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Usage:
at the location of cache block, add lines below:
if ($request_method = PURGE) {$lua_purge_path "/data/nginx_$ {host}_cache";
set
set $lua_purge_levels "1:2";
set $lua_purge_upstream $host;
content_by_lua_file /etc/nginx/lua/cache_purge.lua;
}
$host there is the variable relation to your cache path.