Software / code / prosody-modules
Comparison
mod_rest/mod_rest.lua @ 4503:80912726405d
mod_rest: Allow passing e.g. disco 'node' as a ?query variable
This enables e.g.
GET /disco/pubsub.example.org?node=princely_musings
Note the hack to skip this for ping.
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Sun, 07 Mar 2021 22:01:50 +0100 |
| parent | 4502:48afaec5d1de |
| child | 4506:508cb880b163 |
comparison
equal
deleted
inserted
replaced
| 4502:48afaec5d1de | 4503:80912726405d |
|---|---|
| 63 local function amend_from_path(data, path) | 63 local function amend_from_path(data, path) |
| 64 local st_kind, st_type, st_to = path:match("^([mpi]%w+)/(%w+)/(.*)$"); | 64 local st_kind, st_type, st_to = path:match("^([mpi]%w+)/(%w+)/(.*)$"); |
| 65 if not st_kind then return; end | 65 if not st_kind then return; end |
| 66 if st_kind == "iq" and st_type ~= "get" and st_type ~= "set" then | 66 if st_kind == "iq" and st_type ~= "get" and st_type ~= "set" then |
| 67 -- GET /iq/disco/jid | 67 -- GET /iq/disco/jid |
| 68 data.kind = "iq"; | 68 data = { |
| 69 data.type = "get"; | 69 kind = "iq"; |
| 70 data[st_type] = true; | 70 type = "get"; |
| 71 [st_type] = st_type == "ping" or data or {}; | |
| 72 }; | |
| 71 else | 73 else |
| 72 data.kind = st_kind; | 74 data.kind = st_kind; |
| 73 data.type = st_type; | 75 data.type = st_type; |
| 74 end | 76 end |
| 75 if st_to and st_to ~= "" then | 77 if st_to and st_to ~= "" then |
| 85 elseif mimetype == "application/json" then | 87 elseif mimetype == "application/json" then |
| 86 local parsed, err = json.decode(data); | 88 local parsed, err = json.decode(data); |
| 87 if not parsed then | 89 if not parsed then |
| 88 return parsed, err; | 90 return parsed, err; |
| 89 end | 91 end |
| 90 if path and not amend_from_path(parsed, path) then return nil, "invalid-path"; end | 92 if path then |
| 93 parsed = amend_from_path(parsed, path); | |
| 94 if not parsed then return nil, "invalid-path"; end | |
| 95 end | |
| 91 return jsonmap.json2st(parsed); | 96 return jsonmap.json2st(parsed); |
| 92 elseif mimetype == "application/cbor" and have_cbor then | 97 elseif mimetype == "application/cbor" and have_cbor then |
| 93 local parsed, err = cbor.decode(data); | 98 local parsed, err = cbor.decode(data); |
| 94 if not parsed then | 99 if not parsed then |
| 95 return parsed, err; | 100 return parsed, err; |
| 96 end | 101 end |
| 97 return jsonmap.json2st(parsed); | 102 return jsonmap.json2st(parsed); |
| 98 elseif mimetype == "application/x-www-form-urlencoded"then | 103 elseif mimetype == "application/x-www-form-urlencoded"then |
| 99 local parsed = http.formdecode(data); | 104 local parsed = http.formdecode(data); |
| 100 if type(parsed) == "string" then | 105 if type(parsed) == "string" then |
| 106 -- This should reject GET /iq/query/to?messagebody | |
| 107 if path then | |
| 108 return nil, "invalid-query"; | |
| 109 end | |
| 101 return parse("text/plain", parsed); | 110 return parse("text/plain", parsed); |
| 102 end | 111 end |
| 103 for i = #parsed, 1, -1 do | 112 for i = #parsed, 1, -1 do |
| 104 parsed[i] = nil; | 113 parsed[i] = nil; |
| 105 end | 114 end |
| 106 if path and not amend_from_path(parsed, path) then return nil, "invalid-path"; end | 115 if path then |
| 116 parsed = amend_from_path(parsed, path); | |
| 117 if not parsed then return nil, "invalid-path"; end | |
| 118 end | |
| 107 return jsonmap.json2st(parsed); | 119 return jsonmap.json2st(parsed); |
| 108 elseif mimetype == "text/plain" then | 120 elseif mimetype == "text/plain" then |
| 109 if not path then | 121 if not path then |
| 110 return st.message({ type = "chat" }, data); | 122 return st.message({ type = "chat" }, data); |
| 111 end | 123 end |
| 112 local parsed = {}; | 124 local parsed = {}; |
| 113 if not amend_from_path(parsed, path) then return nil, "invalid-path"; end | 125 if path then |
| 126 parsed = amend_from_path(parsed, path); | |
| 127 if not parsed then return nil, "invalid-path"; end | |
| 128 end | |
| 114 if parsed.kind == "message" then | 129 if parsed.kind == "message" then |
| 115 parsed.body = data; | 130 parsed.body = data; |
| 116 elseif parsed.kind == "presence" then | 131 elseif parsed.kind == "presence" then |
| 117 parsed.show = data; | 132 parsed.show = data; |
| 118 else | 133 else |
| 201 | 216 |
| 202 -- GET → iq-get | 217 -- GET → iq-get |
| 203 local function parse_request(request, path) | 218 local function parse_request(request, path) |
| 204 if path and request.method == "GET" then | 219 if path and request.method == "GET" then |
| 205 -- e.g. /verison/{to} | 220 -- e.g. /verison/{to} |
| 221 if request.url.query then | |
| 222 return parse("application/x-www-form-urlencoded", request.url.query, "iq/"..path); | |
| 223 end | |
| 206 return parse(nil, nil, "iq/"..path); | 224 return parse(nil, nil, "iq/"..path); |
| 207 else | 225 else |
| 208 return parse(request.headers.content_type, request.body, path); | 226 return parse(request.headers.content_type, request.body, path); |
| 209 end | 227 end |
| 210 end | 228 end |