# HG changeset patch # User Kim Alvefur # Date 1649457678 -7200 # Node ID bdac7c717c915ad4a419c990337f829526008927 # Parent b9f8dd9a7fdb139935970e4f4718c057270858bc mod_rest: Support parameters in callback URL E.g. rest_callback_url = "http://myapi.example:5000/api/{kind}/{type}" which results in e.g. requests to /api/message/chat Allows using path routing in web frameworks for dispatch instead of having to pick apart the payload to further dispatch it. diff -r b9f8dd9a7fdb -r bdac7c717c91 mod_rest/README.markdown --- a/mod_rest/README.markdown Sat Apr 09 00:37:55 2022 +0200 +++ b/mod_rest/README.markdown Sat Apr 09 00:41:18 2022 +0200 @@ -130,6 +130,10 @@ rest_callback_url = "http://my-api.example:9999/stanzas" ``` +The callback URL supports a few variables from the stanza being sent, +namely `{kind}` (e.g. message, presence, iq or meta) and ones +corresponding to stanza attributes: `{type}`, `{to}` and `{from}`. + The preferred format can be indicated via the Accept header in response to an OPTIONS probe that mod_rest does on startup, or by configuring: diff -r b9f8dd9a7fdb -r bdac7c717c91 mod_rest/mod_rest.lua --- a/mod_rest/mod_rest.lua Sat Apr 09 00:37:55 2022 +0200 +++ b/mod_rest/mod_rest.lua Sat Apr 09 00:41:18 2022 +0200 @@ -1,6 +1,6 @@ -- RESTful API -- --- Copyright (c) 2019-2020 Kim Alvefur +-- Copyright (c) 2019-2022 Kim Alvefur -- -- This file is MIT/X11 licensed. @@ -416,13 +416,22 @@ -- Forward stanzas from XMPP to HTTP and return any reply local rest_url = module:get_option_string("rest_callback_url", nil); if rest_url then + local function get_url() return rest_url; end + if rest_url:find("%b{}") then + local httputil = require "util.http"; + local render_url = require"util.interpolation".new("%b{}", httputil.urlencode); + function get_url(stanza) + local at = stanza.attr; + return render_url(rest_url, { kind = stanza.name, type = at.type, to = at.to, from = at.from }); + end + end local send_type = module:get_option_string("rest_callback_content_type", "application/xmpp+xml"); if send_type == "json" then send_type = "application/json"; end module:set_status("info", "Not yet connected"); - http.request(rest_url, { + http.request(get_url(st.stanza("meta", { type = "info", to = module.host, from = module.host })), { method = "OPTIONS", }, function (body, code, response) if code == 0 then @@ -455,7 +464,7 @@ stanza = st.clone(stanza, true); module:log("debug", "Sending[rest]: %s", stanza:top_tag()); - http.request(rest_url, { + http.request(get_url(stanza), { body = request_body, headers = { ["Content-Type"] = send_type,