Software /
code /
prosody-modules
Comparison
mod_rest/mod_rest.lua @ 4920:bdac7c717c91
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.
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Sat, 09 Apr 2022 00:41:18 +0200 |
parent | 4918:347e34c3c7e2 |
child | 4921:816b23e09c20 |
comparison
equal
deleted
inserted
replaced
4919:b9f8dd9a7fdb | 4920:bdac7c717c91 |
---|---|
1 -- RESTful API | 1 -- RESTful API |
2 -- | 2 -- |
3 -- Copyright (c) 2019-2020 Kim Alvefur | 3 -- Copyright (c) 2019-2022 Kim Alvefur |
4 -- | 4 -- |
5 -- This file is MIT/X11 licensed. | 5 -- This file is MIT/X11 licensed. |
6 | 6 |
7 local encodings = require "util.encodings"; | 7 local encodings = require "util.encodings"; |
8 local base64 = encodings.base64; | 8 local base64 = encodings.base64; |
414 }); | 414 }); |
415 | 415 |
416 -- Forward stanzas from XMPP to HTTP and return any reply | 416 -- Forward stanzas from XMPP to HTTP and return any reply |
417 local rest_url = module:get_option_string("rest_callback_url", nil); | 417 local rest_url = module:get_option_string("rest_callback_url", nil); |
418 if rest_url then | 418 if rest_url then |
419 local function get_url() return rest_url; end | |
420 if rest_url:find("%b{}") then | |
421 local httputil = require "util.http"; | |
422 local render_url = require"util.interpolation".new("%b{}", httputil.urlencode); | |
423 function get_url(stanza) | |
424 local at = stanza.attr; | |
425 return render_url(rest_url, { kind = stanza.name, type = at.type, to = at.to, from = at.from }); | |
426 end | |
427 end | |
419 local send_type = module:get_option_string("rest_callback_content_type", "application/xmpp+xml"); | 428 local send_type = module:get_option_string("rest_callback_content_type", "application/xmpp+xml"); |
420 if send_type == "json" then | 429 if send_type == "json" then |
421 send_type = "application/json"; | 430 send_type = "application/json"; |
422 end | 431 end |
423 | 432 |
424 module:set_status("info", "Not yet connected"); | 433 module:set_status("info", "Not yet connected"); |
425 http.request(rest_url, { | 434 http.request(get_url(st.stanza("meta", { type = "info", to = module.host, from = module.host })), { |
426 method = "OPTIONS", | 435 method = "OPTIONS", |
427 }, function (body, code, response) | 436 }, function (body, code, response) |
428 if code == 0 then | 437 if code == 0 then |
429 return module:log_status("error", "Could not connect to callback URL %q: %s", rest_url, body); | 438 return module:log_status("error", "Could not connect to callback URL %q: %s", rest_url, body); |
430 else | 439 else |
453 | 462 |
454 -- Keep only the top level element and let the rest be GC'd | 463 -- Keep only the top level element and let the rest be GC'd |
455 stanza = st.clone(stanza, true); | 464 stanza = st.clone(stanza, true); |
456 | 465 |
457 module:log("debug", "Sending[rest]: %s", stanza:top_tag()); | 466 module:log("debug", "Sending[rest]: %s", stanza:top_tag()); |
458 http.request(rest_url, { | 467 http.request(get_url(stanza), { |
459 body = request_body, | 468 body = request_body, |
460 headers = { | 469 headers = { |
461 ["Content-Type"] = send_type, | 470 ["Content-Type"] = send_type, |
462 ["Content-Language"] = stanza.attr["xml:lang"], | 471 ["Content-Language"] = stanza.attr["xml:lang"], |
463 Accept = table.concat(supported_inputs, ", "); | 472 Accept = table.concat(supported_inputs, ", "); |