changeset 4613:6478442d217f

mod_auto156: Queries for XEP-0156 TXT records and prints in JSON format
author Kim Alvefur <zash@zash.se>
date Sat, 03 Jul 2021 20:18:21 +0200
parents fe24bda72838
children 5d494dba9c02
files mod_auto156/mod_auto156.lua
diffstat 1 files changed, 52 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mod_auto156/mod_auto156.lua	Sat Jul 03 20:18:21 2021 +0200
@@ -0,0 +1,52 @@
+-- Synthesize XEP-0156 JSON from DNS
+local array = require "util.array";
+local encodings = require "util.encodings";
+local json = require "util.json";
+local promise = require "util.promise";
+
+local dns = require"net.adns".resolver();
+
+local function check_dns(domain)
+	return dns:lookup_promise("_xmppconnect." .. domain, "TXT");
+end
+
+local function check_domain(domain)
+	return promise.resolve(domain):next(encodings.stringprep.nameprep):next(encodings.idna.to_ascii):next(
+		function(domain_A)
+			if not domain_A then
+				return promise.reject(400);
+			else
+				return domain_A;
+			end
+		end):next(check_dns):next(function(txt)
+		local uris = array();
+		for _, cm in ipairs(txt) do
+			local kind, uri = tostring(cm.txt):match("^_xmpp%-client%-(%w+)=([hpstw]+s?://.*)");
+			if kind then
+				uris:push({rel = "urn:xmpp:alt-connections:" .. kind, href = uri});
+			end
+		end
+		if #uris == 0 then
+			return promise.reject(404);
+		end
+		return uris;
+	end);
+end
+
+module:depends("http");
+module:provides("http", {
+	route = {
+		["GET /*"] = function(_, domain)
+			return check_domain(domain):next(function(uris)
+				return {headers = {content_type = "application/json"}, body = json.encode({links = uris})};
+			end);
+		end,
+	},
+});
+
+function module.command(args)
+	local async = require "util.async";
+	for _, domain in ipairs(args) do
+		print(assert(async.wait_for(check_domain(domain):next(json.encode))));
+	end
+end