3 -- Depends: http://code.matthewwild.co.uk/lua-feeds |
3 -- Depends: http://code.matthewwild.co.uk/lua-feeds |
4 -- |
4 -- |
5 -- Config: |
5 -- Config: |
6 -- Component "pubsub.example.com" "pubsub" |
6 -- Component "pubsub.example.com" "pubsub" |
7 -- modules_enabled = { |
7 -- modules_enabled = { |
8 -- "pubsub_feed"; |
8 -- "pubsub_feeds"; |
9 -- } |
9 -- } |
10 -- feeds = { -- node -> url |
10 -- feeds = { -- node -> url |
11 -- prosody_blog = "http://blog.prosody.im/feed/atom.xml"; |
11 -- prosody_blog = "http://blog.prosody.im/feed/atom.xml"; |
12 -- } |
12 -- } |
13 -- feed_pull_interval = 20 -- minutes |
13 -- feed_pull_interval = 20 -- minutes |
158 |
158 |
159 local function format_url(node) |
159 local function format_url(node) |
160 return module:http_url(nil, "/callback") .. "?node=" .. urlencode(node); |
160 return module:http_url(nil, "/callback") .. "?node=" .. urlencode(node); |
161 end |
161 end |
162 |
162 |
163 function subscribe(feed) |
163 function subscribe(feed, want) |
|
164 want = want or "subscribe"; |
164 feed.token = uuid(); |
165 feed.token = uuid(); |
165 feed.secret = uuid(); |
166 feed.secret = feed.secret or uuid(); |
166 local body = formencode{ |
167 local body = formencode{ |
167 ["hub.callback"] = format_url(feed.node); |
168 ["hub.callback"] = format_url(feed.node); |
168 ["hub.mode"] = "subscribe"; --TODO unsubscribe |
169 ["hub.mode"] = want; |
169 ["hub.topic"] = feed.url; |
170 ["hub.topic"] = feed.url; |
170 ["hub.verify"] = "async"; |
171 ["hub.verify"] = "async"; |
171 ["hub.verify_token"] = feed.token; |
172 ["hub.verify_token"] = feed.token; |
172 ["hub.secret"] = feed.secret; |
173 ["hub.secret"] = feed.secret; |
173 --["hub.lease_seconds"] = ""; |
174 --["hub.lease_seconds"] = ""; |
174 }; |
175 }; |
175 |
176 |
176 --module:log("debug", "subscription request, body: %s", body); |
177 --module:log("debug", "subscription request, body: %s", body); |
177 |
178 |
178 --FIXME The subscription states and related stuff |
179 --FIXME The subscription states and related stuff |
179 feed.subscription = "subscribe"; |
180 feed.subscription = want; |
180 http.request(feed.hub, { body = body }, function(data, code, req) |
181 http.request(feed.hub, { body = body }, function(data, code, req) |
181 module:log("debug", "subscription to %s submitted, status %s", feed.node, tostring(code)); |
182 module:log("debug", "subscription to %s submitted, status %s", feed.node, tostring(code)); |
182 if code >= 400 then |
183 if code >= 400 then |
183 module:log("error", "There was something wrong with our subscription request, body: %s", tostring(data)); |
184 module:log("error", "There was something wrong with our subscription request, body: %s", tostring(data)); |
184 feed.subscription = "failed"; |
185 feed.subscription = "failed"; |
198 --module:log("debug", "GET data: %s", dump(query)); |
199 --module:log("debug", "GET data: %s", dump(query)); |
199 end |
200 end |
200 --module:log("debug", "Headers: %s", dump(request.headers)); |
201 --module:log("debug", "Headers: %s", dump(request.headers)); |
201 |
202 |
202 local feed = feed_list[query.node]; |
203 local feed = feed_list[query.node]; |
|
204 if not feed then |
|
205 return 404; |
|
206 end |
|
207 |
203 if method == "GET" then |
208 if method == "GET" then |
204 if query.node and feed then |
209 if query.node then |
205 if query["hub.topic"] ~= feed.url then |
210 if query["hub.topic"] ~= feed.url then |
206 module:log("debug", "Invalid topic: %s", tostring(query["hub.topic"])) |
211 module:log("debug", "Invalid topic: %s", tostring(query["hub.topic"])) |
207 return 404 |
212 return 404 |
208 end |
213 end |
209 if query["hub.mode"] ~= feed.subscription then |
214 if query["hub.mode"] ~= feed.subscription then |
214 -- it would probably invalidate the subscription |
219 -- it would probably invalidate the subscription |
215 -- when/if the hub asks if it should be renewed |
220 -- when/if the hub asks if it should be renewed |
216 end |
221 end |
217 if query["hub.verify_token"] ~= feed.token then |
222 if query["hub.verify_token"] ~= feed.token then |
218 module:log("debug", "Invalid verify_token: %s", tostring(query["hub.verify_token"])) |
223 module:log("debug", "Invalid verify_token: %s", tostring(query["hub.verify_token"])) |
219 return 401 |
224 return 401; |
220 end |
225 end |
221 module:log("debug", "Confirming %s request to %s", feed.subscription, feed.url) |
226 module:log("debug", "Confirming %s request to %s", feed.subscription, feed.url) |
222 return query["hub.challenge"]; |
227 return query["hub.challenge"]; |
223 end |
228 end |
224 return 400; |
229 return 400; |
225 elseif method == "POST" then |
230 elseif method == "POST" then |
226 local body = request.body; |
231 if #body > 0 then |
227 if #body > 0 and feed then |
|
228 module:log("debug", "got %d bytes PuSHed for %s", #body, query.node); |
232 module:log("debug", "got %d bytes PuSHed for %s", #body, query.node); |
229 local signature = request.headers.x_hub_signature; |
233 local signature = request.headers.x_hub_signature; |
230 if feed.secret then |
234 if feed.secret then |
231 local localsig = "sha1=" .. hmac_sha1(feed.secret, body, true); |
235 local localsig = "sha1=" .. hmac_sha1(feed.secret, body, true); |
232 if localsig ~= signature then |
236 if localsig ~= signature then |