annotate mod_pubsub_hub/mod_pubsub_hub.lua @ 5616:59d5fc50f602

mod_http_oauth2: Implement refresh token rotation Makes refresh tokens one-time-use, handing out a new refresh token with each access token. Thus if a refresh token is stolen and used by an attacker, the next time the legitimate client tries to use the previous refresh token, it will not work and the attack will be noticed. If the attacker does not use the refresh token, it becomes invalid after the legitimate client uses it. This behavior is recommended by draft-ietf-oauth-security-topics
author Kim Alvefur <zash@zash.se>
date Sun, 23 Jul 2023 02:56:08 +0200
parents 4cec8b7aed6d
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
764
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
1 -- Copyright (C) 2011 - 2012 Kim Alvefur
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
2 --
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
3 -- This file is MIT/X11 licensed.
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
4
1325
b21236b6b8d8 Backed out changeset 853a382c9bd6
Kim Alvefur <zash@zash.se>
parents: 1324
diff changeset
5 local http = require "net.http";
b21236b6b8d8 Backed out changeset 853a382c9bd6
Kim Alvefur <zash@zash.se>
parents: 1324
diff changeset
6 local formdecode = http.formdecode;
b21236b6b8d8 Backed out changeset 853a382c9bd6
Kim Alvefur <zash@zash.se>
parents: 1324
diff changeset
7 local formencode = http.formencode;
1458
e9d164e694e7 mod_pubsub_hub: Update to PubSubHubbub version 0.4
Kim Alvefur <zash@zash.se>
parents: 1325
diff changeset
8 local http_request = http.request;
764
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
9 local uuid = require "util.uuid".generate;
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
10 local hmac_sha1 = require "util.hmac".sha1;
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
11 local json_encode = require "util.json".encode;
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
12 local time = os.time;
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
13 local m_min, m_max = math.min, math.max;
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
14 local tostring = tostring;
1458
e9d164e694e7 mod_pubsub_hub: Update to PubSubHubbub version 0.4
Kim Alvefur <zash@zash.se>
parents: 1325
diff changeset
15
764
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
16 local xmlns_pubsub = "http://jabber.org/protocol/pubsub";
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
17 local xmlns_pubsub_event = xmlns_pubsub .. "#event";
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
18 local subs_by_topic = module:shared"subscriptions";
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
19
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
20 local max_lease, min_lease, default_lease = 86400, 600, 3600;
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
21
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
22 module:depends"pubsub";
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
23
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
24 local valid_modes = { ["subscribe"] = true, ["unsubscribe"] = true, }
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
25
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
26 local function do_subscribe(subscription)
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
27 -- FIXME handle other states
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
28 if subscription.state == "subscribed" then
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
29 local ok, err = hosts[module.host].modules.pubsub.service:add_subscription(subscription.topic, true, module.host);
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
30 module:log(ok and "debug" or "error", "add_subscription() => %s, %s", tostring(ok), tostring(err));
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
31 end
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
32 end
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
33
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
34 local function handle_request(event)
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
35 local request, response = event.request, event.response;
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
36 local method, body = request.method, request.body;
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
37
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
38 local query = request.url.query or {};
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
39 if query and type(query) == "string" then
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
40 query = formdecode(query);
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
41 end
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
42 if body and request.headers.content_type == "application/x-www-form-urlencoded" then
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
43 body = formdecode(body);
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
44 end
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
45
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
46 if method == "POST" then
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
47 -- Subscription request
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
48 if body["hub.callback"] and body["hub.mode"] and valid_modes[body["hub.mode"]]
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
49 and body["hub.topic"] and body["hub.verify"] then
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
50
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
51 -- http://pubsubhubbub.googlecode.com/svn/trunk/pubsubhubbub-core-0.3.html#anchor5
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
52 local callback = body["hub.callback"];
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
53 local mode = body["hub.mode"];
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
54 local topic = body["hub.topic"];
767
e5667f1da6bf mod_pubsub_hub: Enforce minimal lease time
Kim Alvefur <zash@zash.se>
parents: 766
diff changeset
55 local lease_seconds = m_max(min_lease, m_min(tonumber(body["hub.lease_seconds"]) or default_lease, max_lease));
764
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
56 local secret = body["hub.secret"];
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
57 local verify_token = body["hub.verify_token"];
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
58
1458
e9d164e694e7 mod_pubsub_hub: Update to PubSubHubbub version 0.4
Kim Alvefur <zash@zash.se>
parents: 1325
diff changeset
59 module:log("debug", "topic is "..(type(topic)=="string" and "%q" or "%s"), tostring(topic));
764
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
60
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
61 if not subs_by_topic[topic] then
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
62 subs_by_topic[topic] = {};
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
63 end
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
64 local subscription = subs_by_topic[topic][callback];
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
65
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
66 local verify_modes = {};
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
67 for i=1,#body do
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
68 if body[i].name == "hub.verify" then
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
69 verify_modes[body[i].value] = true;
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
70 end
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
71 end
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
72
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
73 subscription = subscription or {
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
74 id = uuid(),
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
75 callback = callback,
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
76 topic = topic,
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
77 state = "unsubscribed",
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
78 secret = secret,
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
79 want_state = mode,
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
80 };
1458
e9d164e694e7 mod_pubsub_hub: Update to PubSubHubbub version 0.4
Kim Alvefur <zash@zash.se>
parents: 1325
diff changeset
81 subscription.lease_seconds = lease_seconds;
e9d164e694e7 mod_pubsub_hub: Update to PubSubHubbub version 0.4
Kim Alvefur <zash@zash.se>
parents: 1325
diff changeset
82 subscription.expires = time() + lease_seconds;
764
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
83 subs_by_topic[topic][callback] = subscription;
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
84 local challenge = uuid();
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
85
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
86 local callback_url = callback .. (callback:match("%?") and "&" or "?") .. formencode{
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
87 ["hub.mode"] = mode,
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
88 ["hub.topic"] = topic,
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
89 ["hub.challenge"] = challenge,
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
90 ["hub.lease_seconds"] = tostring(lease_seconds),
1458
e9d164e694e7 mod_pubsub_hub: Update to PubSubHubbub version 0.4
Kim Alvefur <zash@zash.se>
parents: 1325
diff changeset
91 ["hub.verify_token"] = verify_token, -- COMPAT draft version 0.3
764
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
92 }
1458
e9d164e694e7 mod_pubsub_hub: Update to PubSubHubbub version 0.4
Kim Alvefur <zash@zash.se>
parents: 1325
diff changeset
93 module:log("debug", "Sending async verification request to %s for %s", tostring(callback_url), tostring(subscription));
e9d164e694e7 mod_pubsub_hub: Update to PubSubHubbub version 0.4
Kim Alvefur <zash@zash.se>
parents: 1325
diff changeset
94 http_request(callback_url, nil, function(body, code)
e9d164e694e7 mod_pubsub_hub: Update to PubSubHubbub version 0.4
Kim Alvefur <zash@zash.se>
parents: 1325
diff changeset
95 if body == challenge and code > 199 and code < 300 then
e9d164e694e7 mod_pubsub_hub: Update to PubSubHubbub version 0.4
Kim Alvefur <zash@zash.se>
parents: 1325
diff changeset
96 if not subscription.want_state then
e9d164e694e7 mod_pubsub_hub: Update to PubSubHubbub version 0.4
Kim Alvefur <zash@zash.se>
parents: 1325
diff changeset
97 module:log("warn", "Verification of already verified request, probably");
e9d164e694e7 mod_pubsub_hub: Update to PubSubHubbub version 0.4
Kim Alvefur <zash@zash.se>
parents: 1325
diff changeset
98 return;
764
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
99 end
1458
e9d164e694e7 mod_pubsub_hub: Update to PubSubHubbub version 0.4
Kim Alvefur <zash@zash.se>
parents: 1325
diff changeset
100 subscription.state = subscription.want_state .. "d";
e9d164e694e7 mod_pubsub_hub: Update to PubSubHubbub version 0.4
Kim Alvefur <zash@zash.se>
parents: 1325
diff changeset
101 subscription.want_state = nil;
e9d164e694e7 mod_pubsub_hub: Update to PubSubHubbub version 0.4
Kim Alvefur <zash@zash.se>
parents: 1325
diff changeset
102 module:log("debug", "calling do_subscribe()");
e9d164e694e7 mod_pubsub_hub: Update to PubSubHubbub version 0.4
Kim Alvefur <zash@zash.se>
parents: 1325
diff changeset
103 do_subscribe(subscription);
e9d164e694e7 mod_pubsub_hub: Update to PubSubHubbub version 0.4
Kim Alvefur <zash@zash.se>
parents: 1325
diff changeset
104 subs_by_topic[topic][callback] = subscription;
e9d164e694e7 mod_pubsub_hub: Update to PubSubHubbub version 0.4
Kim Alvefur <zash@zash.se>
parents: 1325
diff changeset
105 else
e9d164e694e7 mod_pubsub_hub: Update to PubSubHubbub version 0.4
Kim Alvefur <zash@zash.se>
parents: 1325
diff changeset
106 module:log("warn", "status %d and body was %q", tostring(code), tostring(body));
e9d164e694e7 mod_pubsub_hub: Update to PubSubHubbub version 0.4
Kim Alvefur <zash@zash.se>
parents: 1325
diff changeset
107 subs_by_topic[topic][callback] = subscription;
e9d164e694e7 mod_pubsub_hub: Update to PubSubHubbub version 0.4
Kim Alvefur <zash@zash.se>
parents: 1325
diff changeset
108 end
e9d164e694e7 mod_pubsub_hub: Update to PubSubHubbub version 0.4
Kim Alvefur <zash@zash.se>
parents: 1325
diff changeset
109 end)
e9d164e694e7 mod_pubsub_hub: Update to PubSubHubbub version 0.4
Kim Alvefur <zash@zash.se>
parents: 1325
diff changeset
110 return 202;
764
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
111 else
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
112 response.status = 400;
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
113 response.headers.content_type = "text/html";
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
114 return "<h1>Bad Request</h1>\n<a href='http://pubsubhubbub.googlecode.com/svn/trunk/pubsubhubbub-core-0.3.html#anchor5'>Missing required parameter(s)</a>\n"
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
115 end
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
116 end
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
117 end
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
118
1458
e9d164e694e7 mod_pubsub_hub: Update to PubSubHubbub version 0.4
Kim Alvefur <zash@zash.se>
parents: 1325
diff changeset
119 local function periodic(now)
764
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
120 local next_check = now + max_lease;
766
1184fe8ebb21 mod_pubsub_hub: Try to choose time until the next periodic check in a sane way
Kim Alvefur <zash@zash.se>
parents: 764
diff changeset
121 local purge = false;
764
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
122 for topic, callbacks in pairs(subs_by_topic) do
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
123 for callback, subscription in pairs(callbacks) do
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
124 if subscription.mode == "subscribed" then
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
125 if subscription.expires < now then
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
126 -- Subscription has expired, drop it.
766
1184fe8ebb21 mod_pubsub_hub: Try to choose time until the next periodic check in a sane way
Kim Alvefur <zash@zash.se>
parents: 764
diff changeset
127 purge = true;
764
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
128 else
766
1184fe8ebb21 mod_pubsub_hub: Try to choose time until the next periodic check in a sane way
Kim Alvefur <zash@zash.se>
parents: 764
diff changeset
129 next_check = m_min(next_check, subscription.expires);
764
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
130 end
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
131 end
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
132 end
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
133 if purge then
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
134 local new_callbacks = {};
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
135 for callback, subscription in pairs(callbacks) do
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
136 if (subscription.state == "subscribed" and subscription.expires < now)
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
137 and subscription.want_state ~= "remove" then
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
138 new_callbacks[callback] = subscription;
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
139 end
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
140 end
766
1184fe8ebb21 mod_pubsub_hub: Try to choose time until the next periodic check in a sane way
Kim Alvefur <zash@zash.se>
parents: 764
diff changeset
141 subs_by_topic[topic] = new_callbacks;
1184fe8ebb21 mod_pubsub_hub: Try to choose time until the next periodic check in a sane way
Kim Alvefur <zash@zash.se>
parents: 764
diff changeset
142 purge = false;
764
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
143 end
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
144 end
785
e781e63a49f4 mod_pubsub_hub: Fix calculating next periodic check of subscriptions.
Kim Alvefur <zash@zash.se>
parents: 767
diff changeset
145 return m_max((now - next_check) - min_lease, min_lease);
764
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
146 end
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
147
801
133ee88d19ae mod_pubsub_hub: Add compat wrapping of Atom content for interop with PuSH
Kim Alvefur <zash@zash.se>
parents: 785
diff changeset
148 local xmlns_atom = "http://www.w3.org/2005/Atom";
133ee88d19ae mod_pubsub_hub: Add compat wrapping of Atom content for interop with PuSH
Kim Alvefur <zash@zash.se>
parents: 785
diff changeset
149 local st = require "util.stanza";
133ee88d19ae mod_pubsub_hub: Add compat wrapping of Atom content for interop with PuSH
Kim Alvefur <zash@zash.se>
parents: 785
diff changeset
150
764
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
151 local function on_notify(subscription, content)
801
133ee88d19ae mod_pubsub_hub: Add compat wrapping of Atom content for interop with PuSH
Kim Alvefur <zash@zash.se>
parents: 785
diff changeset
152 if content.attr and content.attr.xmlns == xmlns_atom then
133ee88d19ae mod_pubsub_hub: Add compat wrapping of Atom content for interop with PuSH
Kim Alvefur <zash@zash.se>
parents: 785
diff changeset
153 -- COMPAT This is required by the PubSubHubbub spec.
133ee88d19ae mod_pubsub_hub: Add compat wrapping of Atom content for interop with PuSH
Kim Alvefur <zash@zash.se>
parents: 785
diff changeset
154 content = st.stanza("feed", {xmlns=xmlns_atom}):add_child(content);
133ee88d19ae mod_pubsub_hub: Add compat wrapping of Atom content for interop with PuSH
Kim Alvefur <zash@zash.se>
parents: 785
diff changeset
155 end
764
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
156 local body = tostring(content);
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
157 local headers = {
3021
4cec8b7aed6d mod_pubsub_hub: Use the correct MIME type for Atom feeds
Kim Alvefur <zash@zash.se>
parents: 1458
diff changeset
158 ["Content-Type"] = "application/atom+xml",
764
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
159 };
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
160 if subscription.secret then
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
161 headers["X-Hub-Signature"] = "sha1="..hmac_sha1(subscription.secret, body, true);
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
162 end
1458
e9d164e694e7 mod_pubsub_hub: Update to PubSubHubbub version 0.4
Kim Alvefur <zash@zash.se>
parents: 1325
diff changeset
163 http_request(subscription.callback, { method = "POST", body = body, headers = headers }, function(body, code)
764
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
164 if code >= 200 and code <= 299 then
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
165 module:log("debug", "Delivered");
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
166 else
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
167 module:log("warn", "Got status code %d on delivery to %s", tonumber(code) or -1, tostring(subscription.callback));
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
168 -- TODO Retry
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
169 -- ... but the spec says that you should not retry, wtf?
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
170 end
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
171 end);
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
172 end
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
173
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
174 module:hook("message/host", function(event)
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
175 local stanza = event.stanza;
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
176 if stanza.attr.from ~= module.host then return end;
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
177
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
178 for pubsub_event in stanza:childtags("event", xmlns_pubsub_event) do
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
179 local items = pubsub_event:get_child("items");
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
180 local node = items.attr.node;
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
181 if items and node and subs_by_topic[node] then
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
182 for item in items:childtags("item") do
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
183 local content = item.tags[1];
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
184 for callback, subscription in pairs(subs_by_topic[node]) do
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
185 on_notify(subscription, content)
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
186 end
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
187 end
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
188 end
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
189 end
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
190 return true;
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
191 end, 10);
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
192
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
193 module:depends"http";
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
194 module:provides("http", {
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
195 default_path = "/hub";
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
196 route = {
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
197 POST = handle_request;
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
198 GET = function()
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
199 return json_encode(subs_by_topic);
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
200 end;
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
201 ["GET /topic/*"] = function(event, path)
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
202 return json_encode(subs_by_topic[path])
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
203 end;
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
204 };
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
205 });
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
206
d11d91ee81ed mod_pubsub_hub: New module that implements the Hub part of PubSubHubbub
Kim Alvefur <zash@zash.se>
parents:
diff changeset
207 module:add_timer(1, periodic);