view plugins/mod_http_altconnect.lua @ 13765:7c57fb2ffbb0 13.0

mod_websocket: Merge session close handling changes from mod_c2s (bug fixes) This should bring some fixes and general robustness that mod_websocket had missed out on. The duplicated code here is not at all ideal. To prevent this happening again, we should figure out how to have the common logic in a single place, while still being able to do the websocket-specific parts that we need. The main known bug that this fixes is that it's possible for a session to get into a non-destroyable state. For example, if we try to session:close() a hibernating session, then session.conn is nil and the function will simply return without doing anything. In the mod_c2s code we already handle this, and just destroy the session. But if a hibernating websocket session is never resumed or becomes non-resumable, it will become immortal! By merging the fix from mod_c2s, the session should now be correctly destroyed.
author Matthew Wild <mwild1@gmail.com>
date Tue, 11 Mar 2025 18:44:40 +0000
parents 569fae28a2f3
children
line wrap: on
line source

-- mod_http_altconnect
-- XEP-0156: Discovering Alternative XMPP Connection Methods

module:depends"http";

local mm = require "prosody.core.modulemanager";
local json = require"prosody.util.json";
local st = require"prosody.util.stanza";
local array = require"prosody.util.array";

local advertise_bosh = module:get_option_boolean("advertise_bosh", true);
local advertise_websocket = module:get_option_boolean("advertise_websocket", true);

local function get_supported()
	local uris = array();
	if advertise_bosh and (mm.is_loaded(module.host, "bosh") or mm.is_loaded("*", "bosh")) then
		uris:push({ rel = "urn:xmpp:alt-connections:xbosh", href = module:http_url("bosh", "/http-bind") });
	end
	if advertise_websocket and (mm.is_loaded(module.host, "websocket") or  mm.is_loaded("*", "websocket")) then
		uris:push({ rel = "urn:xmpp:alt-connections:websocket", href = module:http_url("websocket", "xmpp-websocket"):gsub("^http", "ws") });
	end
	return uris;
end


local function GET_xml(event)
	local response = event.response;
	local xrd = st.stanza("XRD", { xmlns='http://docs.oasis-open.org/ns/xri/xrd-1.0' });
	local uris = get_supported();
	for _, method in ipairs(uris) do
		xrd:tag("Link", method):up();
	end
	response.headers.content_type = "application/xrd+xml"
	response.headers.access_control_allow_origin = "*";
	return '<?xml version="1.0" encoding="UTF-8"?>' .. tostring(xrd);
end

local function GET_json(event)
	local response = event.response;
	local jrd = { links = get_supported() };
	response.headers.content_type = "application/json"
	response.headers.access_control_allow_origin = "*";
	return json.encode(jrd);
end;

module:provides("http", {
	default_path = "/.well-known";
	route = {
		["GET /host-meta"] = GET_xml;
		["GET /host-meta.json"] = GET_json;
	};
});