1 module:depends("http"); |
1 module:depends("http"); |
2 |
2 |
3 local st = require "util.stanza"; |
3 local st = require "util.stanza"; |
4 local json = require "util.json"; |
4 local json = require "util.json"; |
|
5 local xml = require "util.xml"; |
5 local uuid_generate = require "util.uuid".generate; |
6 local uuid_generate = require "util.uuid".generate; |
6 local timestamp_generate = require "util.datetime".datetime; |
7 local timestamp_generate = require "util.datetime".datetime; |
7 |
8 |
8 local pubsub_service = module:depends("pubsub").service; |
9 local pubsub_service = module:depends("pubsub").service; |
9 |
10 |
|
11 local error_mapping = { |
|
12 ["forbidden"] = 403; |
|
13 ["item-not-found"] = 404; |
|
14 ["internal-server-error"] = 500; |
|
15 ["conflict"] = 409; |
|
16 }; |
|
17 |
|
18 local function publish_payload(node, item_id, payload) |
|
19 local post_item = st.stanza("item", { xmlns = "http://jabber.org/protocol/pubsub", id = item_id, }) |
|
20 :add_child(payload); |
|
21 local ok, err = pubsub_service:publish(node, true, item_id, post_item); |
|
22 module:log("debug", ":publish(%q, true, %q, %s) -> %q", node, item_id, payload:top_tag(), err or ""); |
|
23 if not ok then |
|
24 return error_mapping[err] or 500; |
|
25 end |
|
26 return 202; |
|
27 end |
|
28 |
|
29 local function handle_xml(node, payload) |
|
30 local xmlpayload, err = xml.parse(payload); |
|
31 if not xmlpayload then |
|
32 module:log("debug", "XML parse error: %s\n%q", err, payload); |
|
33 return { status_code = 400, body = tostring(err) }; |
|
34 end |
|
35 return publish_payload(node, "current", xmlpayload); |
|
36 end |
|
37 |
10 function handle_POST(event, path) |
38 function handle_POST(event, path) |
11 local data = event.request.body; |
39 local request = event.request; |
12 local item_id = "default"; |
40 module:log("debug", "Handling POST: \n%s\n", tostring(request.body)); |
13 |
41 |
14 local post_item = st.stanza("item", { id = item_id, xmlns = "http://jabber.org/protocol/pubsub" }) |
42 local content_type = request.headers.content_type or "application/octet-stream"; |
15 :tag("entry", { xmlns = "http://www.w3.org/2005/Atom" }) |
43 |
16 :tag("id"):text(uuid_generate()):up() |
44 if content_type == "application/xml" or content_type:sub(-4) == "+xml" then |
17 :tag("title"):text(data):up() |
45 return handle_xml(path, request.body); |
18 :tag("author") |
46 end |
19 :tag("name"):text(event.request.conn:ip()):up() |
47 |
20 :up() |
48 module:log("debug", "Unsupported content-type: %q", content_type); |
21 :tag("published"):text(timestamp_generate()):up(); |
49 return 415; |
22 |
|
23 local ok, err = pubsub_service:publish(path, true, item_id, post_item); |
|
24 module:log("debug", "Handled POST: \n%s\n", tostring(event.request.body)); |
|
25 return ok and "Posted" or ("Error: "..err); |
|
26 end |
50 end |
27 |
51 |
28 module:provides("http", { |
52 module:provides("http", { |
29 route = { |
53 route = { |
30 ["POST /*"] = handle_POST; |
54 ["POST /*"] = handle_POST; |