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 |