changeset 5736:ba731ff5b895

mod_storage_s3: Reorder path components (BC: invalidates any existing data) keyvalue: /bucket/hostname/username/store archive: /bucket/hostname/username/store/yyyy-mm-dd/with/key
author Kim Alvefur <zash@zash.se>
date Mon, 27 Nov 2023 09:30:04 +0100
parents 9a1d8c39d0b0
children 72b0fa7e36dc
files mod_storage_s3/mod_storage_s3.lua
diffstat 1 files changed, 23 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/mod_storage_s3/mod_storage_s3.lua	Mon Nov 27 09:28:28 2023 +0100
+++ b/mod_storage_s3/mod_storage_s3.lua	Mon Nov 27 09:30:04 2023 +0100
@@ -155,8 +155,8 @@
 		is_absolute = true;
 		bucket;
 		jid.escape(module.host);
+		jid.escape(key or "@");
 		jid.escape(self.store);
-		jid.escape(key or "@");
 	})
 end
 
@@ -175,7 +175,7 @@
 
 function keyval:users()
 	local bucket_path = url.build_path({ is_absolute = true; bucket; is_directory = true });
-	local prefix = url.build_path({ jid.escape(module.host); jid.escape(self.store); is_directory = true });
+	local prefix = url.build_path({ jid.escape(module.host); is_directory = true });
 	local list_result, err = async.wait_for(new_request(self, "GET", bucket_path, { prefix = prefix }))
 	if err or list_result.code ~= 200 then
 		return nil, err;
@@ -186,9 +186,12 @@
 		module:log("warn", "Paging truncated results not implemented, max %s %s returned", max_keys, self.store);
 	end
 	local keys = array();
+	local store_part = jid.escape(self.store);
 	for content in list_bucket_result:childtags("Contents") do
 		local key = url.parse_path(content:get_child_text("Key"));
-		keys:push(jid.unescape(key[3]));
+		if key[3] == store_part then
+			keys:push(jid.unescape(key[2]));
+		end
 	end
 	return function()
 		return keys:pop();
@@ -208,10 +211,10 @@
 		is_absolute = true;
 		bucket;
 		jid.escape(module.host);
+		jid.escape(username or "@");
 		jid.escape(self.store);
-		jid.escape(username or "@");
+		date or dt.date(when);
 		jid.escape(with and jid.prep(with) or "@");
-		date or dt.date(when);
 		key;
 	})
 end
@@ -235,15 +238,15 @@
 
 function archive:find(username, query)
 	local bucket_path = url.build_path({ is_absolute = true; bucket; is_directory = true });
-	local prefix = { jid.escape(module.host); jid.escape(self.store); is_directory = true };
-	table.insert(prefix, jid.escape(username or "@"));
+	local prefix = { jid.escape(module.host); jid.escape(username or "@"); jid.escape(self.store); is_directory = true };
 	if not query then
 		query = {};
 	end
-	if query["with"] then
-		table.insert(prefix, jid.escape(jid.prep(query["with"]), true):sub(1,24));
-		if query["start"] and query["end"] and dt.date(query["start"]) == dt.date(query["end"]) then
-			table.insert(prefix, dt.date(query["start"]));
+
+	if query["start"] and query["end"] and dt.date(query["start"]) == dt.date(query["end"]) then
+		table.insert(prefix, dt.date(query["start"]));
+		if query["with"] then
+			table.insert(prefix, jid.escape(query["with"]));
 		end
 	end
 
@@ -271,18 +274,19 @@
 	local ids = query["ids"] and set.new(query["ids"]);
 	local found = not query["after"];
 	for content in iterwrap(list_bucket_result:childtags("Contents")) do
-		local key = url.parse_path(content:get_child_text("Key"));
-		if found and query["before"] == key[6] then
+		local when, with, id = table.unpack(url.parse_path(content:get_child_text("Key")), 4);
+		with = jid.unescape(with);
+		if found and query["before"] == id then
 			break
 		end
-		if (not query["with"] or query["with"] == jid.unescape(key[5]))
-		and (not query["start"] or dt.date(query["start"]) >= key[6])
-		and (not query["end"] or dt.date(query["end"]) <= key[6])
-		and (not ids or ids:contains(key[6]))
+		if (not query["with"] or query["with"] == with)
+		and (not query["start"] or dt.date(query["start"]) >= when)
+		and (not query["end"] or dt.date(query["end"]) <= when)
+		and (not ids or ids:contains(id))
 		and found then
-			keys:push({ key = key[6]; date = key[5]; with = jid.unescape(key[4]) });
+			keys:push({ key = id; date = when; with = with });
 		end
-		if not found and key[6] == query["after"] then
+		if not found and id == query["after"] then
 			found = not found
 		end
 	end