Monday, April 04, 2011 at 1:06 AM.

rssCloudSuite.pleaseNotify

on pleaseNotify (notifyProcedure, port, path, protocol, urllist, callerIpAddress, flDiffDomain=false) {
	<<Changes
		<<10/2/09; 3:06:07 PM by DW
			<<Optional param, flDiffDomain.
		<<9/11/09; 6:07:23 AM by DW
			<<Don't accept notification requests for resources that don't exist.
		<<7/25/09; 10:18:00 AM by DW
			<<Instead of hard-coding the feed expiration at 25 hours, use the new pref. 
		<<7/21/09; 12:52:12 PM by DW
			<<Add optional param, callerIpAddress. This allows the REST interface to set the client as a param.
		<<7/19/09; 11:17:11 AM by DW
			<<Test the notify procedure on the first item in the list. If it fails, call it an error. If you can't handle a notification now, we don't believe you'll be able to handle it in the future. This helps keep garbage out of our network.
		<<7/15/09; 7:25:44 AM by DW
			<<Allow "http-post" as a method.
		<<7/14/09; 7:09:17 AM by DW
			<<The interface described here: 
				<<http://cyber.law.harvard.edu/rss/soapMeetsRss.html#rsscloudInterface
	local (adrdata = rssCloudSuite.init (), feedurl, apiurl, flfirst = true, errormsg = "");
	rssCloudSuite.checkEnabled (); //scripterror if not enabled
	bundle { //set apiurl
		<<xmlrpc://rpc.lifeliner.org:5337/RPC2
		case protocol {
			"xml-rpc" {
				apiurl = "xmlrpc://"};
			"soap" {
				apiurl = "soap://"};
			"http-post" {
				apiurl = "http://"}}
		else {
			scriptError ("Can't accept the notification request because the protocol, \"" + protocol + "\", is unsupported.")};
		if callerIpAddress == "75.101.165.156" {
			callerIpAddress = "rpc.rsscloud.org"};
		apiurl = apiurl + callerIpAddress + ":" + port;
		if not (path beginswith "/") {
			path = "/" + path};
		apiurl = apiurl + path};
	local (adrsubscriber = @adrdata^.subscribers.[apiurl]);
	if not defined (adrsubscriber^) {
		new (tabletype, adrsubscriber)};
	adrsubscriber^.notifyProcedure = notifyProcedure;
	for feedurl in urllist {
		local (adrsubscriptions = @adrdata^.subscriptions.[feedurl], startticks = clock.ticks (), flresourceexists);
		bundle { //check if resource exists, 9/11/09 by DW
			local (urllist);
			try {
				urllist = string.urlsplit (feedurl)}
			else {
				urllist = string.urlsplit (feedurl + "/")};
			try {
				local (s = tcp.httpClient (server:urllist [2], path:urllist [3], ctFollowRedirects:3, flMessages:true));
				local (code = number (tcp.httpGetStatusCode (s)));
				flresourceexists = (code >= 200) and (code <= 299)} //http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
			else {
				flresourceexists = false};
			if not flresourceexists {
				errormsg = "The subscription was cancelled because there was an error reading the resource at URL " + feedurl + "."}};
		if flresourceexists {
			if not defined (adrsubscriptions^) { //one table for each feed that's being subscribed to
				new (tabletype, adrsubscriptions)};
			local (adrsubscription = @adrsubscriptions^.[apiurl]);
			if not defined (adrsubscription^) {
				new (tabletype, adrsubscription)};
			if flfirst { //7/19/09 by DW
				on test () { //10/2/09 by DW
					if flDiffDomain {
						return (rssCloudSuite.notifyOneChallenge (adrsubscription))}
					else {
						return (rssCloudSuite.notifyOne (adrsubscription, false))}};
				if not test () { //failed
					errormsg = "The subscription was cancelled because the call failed when we tested the handler."};
				flfirst = false}; //only need to do it once
			adrsubscription^.whenExpires = clock.now () + adrdata^.prefs.ctSecsFeedExpire;
			rssCloudSuite.initSubscription (adrsubscription)};
		bundle { //log the event
			local (urllist = string.urlsplit (apiurl));
			local (servername = string.nthfield (urllist [2], ":", 1)); //pop the port off the name of the server
			local (protocolname = urllist [1] - "://");
			local (s = "Subscriber <a href=\"" + apiurl + "\">" + servername + "</a> requests notification when the <a href=\"" + feedurl + "\"> feed</a> changes via <i>" + protocolname + "</i> protocol.");
			if errormsg != "" {
				s = s + "<br /><br />Error: " + errormsg};
			log2.add (rssCloudInfo.name, "Subscribe", s, startticks)};
		if errormsg != "" { //report the error back to the other app
			try {delete (adrsubscription)};
			scriptError (errormsg)}}};
bundle { //test code
	pleaseNotify ("rsscloud.hello", 5337, "/RPC2", "xml-rpc", {"http://static.lifeliner.org/davexxx/rss.xml"}, "127.0.0.1")}



This listing is for code that runs in the OPML Editor environment. I created these listings because I wanted the search engines to index it, so that when I want to look up something in my codebase I don't have to use the much slower search functionality in my object database. Dave Winer.