Skip to content

Instantly share code, notes, and snippets.

@nosun
Forked from titpetric/purge-multi.lua
Last active January 4, 2023 19:00
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save nosun/0cfb58d3164f829e2f027fd37b338ede to your computer and use it in GitHub Desktop.
Save nosun/0cfb58d3164f829e2f027fd37b338ede to your computer and use it in GitHub Desktop.
Delete NGINX cached items with a PURGE with wildcard support
-- 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 nosun2008@126.com
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
@nosun
Copy link
Author

nosun commented May 16, 2018

Usage:

at the location of cache block, add lines below:

if ($request_method = PURGE) {
set $lua_purge_path "/data/nginx_${host}_cache";
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.

@m1911
Copy link

m1911 commented Sep 9, 2018

@nosun 你这是把单个和删除全部加到了一起吗?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment