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.