mod_pubsub_feeds/mod_pubsub_feeds.lua
changeset 718 a37e4149ccd1
parent 717 e79147fb39f9
child 762 0a06cf46c263
equal deleted inserted replaced
717:e79147fb39f9 718:a37e4149ccd1
     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