RSSCloud assumes the calling address is the callback address

RSSCloud is a proposed mechanism for delivering feed update notifications in near real-time. Rather than subscribers polling publishers every few minutes, a cloud server aggregates subscriptions and receives change notifications from publishers via HTTP. The cloud then notifies subscribers, who in turn fetch the updated feed from the publisher.

The subscription protocol requires the subscriber to declare a notification procedure, port, path, protocol (XML-RPC, SOAP, or HTTP POST), and the feed URLs. Conspicuously absent is any way to specify a callback host. As the RSSCloud walkthrough states:

Notifications are sent to the IP address the request came from.

The workaround works when the originating IP can accept inbound connections. That excludes the majority of home users on NAT'd routers, most corporate networks, the iPhone, and—increasingly—cloud-hosted infrastructure, where compute nodes and their IPs come and go. Vodpod, for instance, fronts its cluster with failover, IP routing, and HTTP proxying, so an individual node that subscribes may later be gone, and a distributed deployment would require subscribing from every host to preserve reliability. EC2-scale environments make the issue more acute.

The RSSCloud mailing list settled on the correct remedy early on: a domain parameter letting subscribers specify which FQDN or IP cloud servers should contact. Dave Winer added it to the walkthrough, but server support remains uneven—WordPress, to pick one example, still hasn't implemented it.

Partial workarounds

Until domain gains traction, two routes help. PubSubHubbub defines the full callback URL in its subscription flow, so it avoids the problem by design; a superfeedr-style bridge can translate RSSCloud notifications into PubSubHubbub pushes. Alternatively, you can make the request appear to come from a routable address. Vodpod did exactly that when subscribing to WordPress: bind an outbound connection's source IP to a public address known to route into the cluster, then complete the HTTP request from that socket. The trick re-binds the socket beneath Net::HTTP:

res = Net::HTTP.new(uri.host, uri.port).start do |http|
  # Replace the socket with one that we bind to the interface we want to use.

  # The local IP address we'd like RSSCloud to call back.
  local_addr = Socket.pack_sockaddr_in 0, '208.101.30.10'
  # The RSSCloud server IP address
  remote_addr = Socket.pack_sockaddr_in uri.port, uri.host

  # Create a new socket
  s = Socket.new Socket::AF_INET, Socket::SOCK_STREAM, 0
  # Bind it to the local address
  s.bind local_addr

  # Wrap for Net::HTTP and connect
  socket = Net::BufferedIO.new(s)
  s.connect remote_addr

  # Replace the HTTP client's connection
  http.instance_variable_set('@socket', socket)

  # And make the request
  http.request(req)
end

It is an outright hack—it works only if the chosen outbound and inbound paths terminate somewhere reachable for the callback, and it does nothing about the underlying protocol gap. What it does provide is a stopgap for any deployment whose boundary is elastic or NAT'd until RSSCloud servers adopt the domain parameter.