File

util/xml.lua @ 11405:ce8291e89d67

mod_http_file_share: Remove correct entries when not all expired files were deleted If any of the expired files could not be deleted then we should not forget about that, we should complain loudly and try again. The code got this backwards and would have removed only the entries referring to still existing files. Test procedure: 1. Upload a file 2. chown root:root http_file_share/ 3. In uploads.list, decrease 'when' enough to ensure expiry 4. Reload mod_http_file_share 5. Should see an error in the logs about failure to delete the file 6. Should see that the metadata in uploads.list is still there 7. chown http_file_share/ back to the previous owner 8. Reload mod_http_file_share 9. Should see logs about successful removal of expired file 10. Should see that the metadata in uploads.list is gone 11. Should see that the file was deleted
author Kim Alvefur <zash@zash.se>
date Thu, 25 Feb 2021 23:58:08 +0100
parent 11127:1d9cd1abc660
child 12121:2162e86029b6
line wrap: on
line source


local st = require "util.stanza";
local lxp = require "lxp";
local t_insert = table.insert;
local t_remove = table.remove;

local _ENV = nil;
-- luacheck: std none

local parse_xml = (function()
	local ns_prefixes = {
		["http://www.w3.org/XML/1998/namespace"] = "xml";
	};
	local ns_separator = "\1";
	local ns_pattern = "^([^"..ns_separator.."]*)"..ns_separator.."?(.*)$";
	return function(xml)
		--luacheck: ignore 212/self
		local handler = {};
		local stanza = st.stanza("root");
		local namespaces = {};
		local prefixes = {};
		function handler:StartNamespaceDecl(prefix, url)
			if prefix ~= nil then
				t_insert(namespaces, url);
				t_insert(prefixes, prefix);
			end
		end
		function handler:EndNamespaceDecl(prefix)
			if prefix ~= nil then
				-- we depend on each StartNamespaceDecl having a paired EndNamespaceDecl
				t_remove(namespaces);
				t_remove(prefixes);
			end
		end
		function handler:StartElement(tagname, attr)
			local curr_ns,name = tagname:match(ns_pattern);
			if name == "" then
				curr_ns, name = "", curr_ns;
			end
			if curr_ns ~= "" then
				attr.xmlns = curr_ns;
			end
			for i=1,#attr do
				local k = attr[i];
				attr[i] = nil;
				local ns, nm = k:match(ns_pattern);
				if nm ~= "" then
					ns = ns_prefixes[ns];
					if ns then
						attr[ns..":"..nm] = attr[k];
						attr[k] = nil;
					end
				end
			end
			local n = {}
			for i=1,#namespaces do
				n[prefixes[i]] = namespaces[i];
			end
			stanza:tag(name, attr, n);
		end
		function handler:CharacterData(data)
			stanza:text(data);
		end
		function handler:EndElement()
			stanza:up();
		end
		local parser = lxp.new(handler, "\1");
		local ok, err, line, col = parser:parse(xml);
		if ok then ok, err, line, col = parser:parse(); end
		--parser:close();
		if ok then
			return stanza.tags[1];
		else
			return ok, ("%s (line %d, col %d))"):format(err, line, col);
		end
	end;
end)();

return {
	parse = parse_xml;
};