Jabber::RPC::HTTPgate - An HTTP gateway for Jabber-RPC / XML-RPC
use Jabber::RPC::HTTPgate; my $gw = new Jabber::RPC::HTTPgate( server => 'myserver.org:5701', identauth => 'jrpchttp.localhost:secret', httpcomp => 'http', ); $gw->start;
Jabber::RPC::HTTPgate is an experimental gateway that provides a conduit service between 'traditional' (HTTP-transported) XML-RPC encoded requests/responses and Jabber-RPC (XML-RPC encoded requests/responses transported over Jabber).
The idea is that you can start a gateway, that connects as a component to the backbone of a Jabber server, and it proxies Jabber-RPC to HTTP-based XML-RPC endpoints, and vice versa. That means that your Jabber-RPC client can not only make XML-RPC encoded calls to a Jabber-RPC endpoint but also to a 'traditional' HTTP-based XML-RPC endpoint. And it also means that your 'traditional' HTTP-based XML-RPC client can make XML-RPC encoded calls to a Jabber-RPC endpoint.
When you create and start up a gateway, it listens for Jabber-RPC calls, just like a normal Jabber-RPC responder. On receipt of such a call, the gateway creates an HTTP request and sends this request on to the HTTP-based XML-RPC endpoint. The response received back from this HTTP call is relayed back to the original Jabber-RPC requester.
While a Jabber-RPC endpoint address is a Jabber ID (JID), an traditional XML-RPC endpoint address is a URL. So all the Jabber-RPC client needs to do is specify the URL in the resource part of the gateway's endpoint JID.
As well as listening for Jabber-RPC calls, a gateway will also service incoming HTTP requests that can be made to the HTTP component that this gateway uses. The HTTP component (called simply 'http') can be downloaded from the normal Jabber software repository.
On receipt of an HTTP request (passed to it by the HTTP component), the gateway creates a Jabber-RPC request containing the XML-RPC encoded payload, and sends it on to the Jabber-RPC responder endpoint. This endpoint is identified (via a JID) by the path part of the URL used in the call by the traditional client.
Here's what it all looks like:
+---+ 2-----------+ 3-----------+ Jabber backbone -----> l | http |<-- HTTP -->| HTTP | l l===| component | | responder | 5-----------+ l l +-> |<- HTTP -+ | | | JabberRPC | l l | +-----------+ | +-----------+ | responder |===l l | | |(component)|<---+ l +---+ | 4-----------+ +-----------+ l| l | <route/> | | HTTP | l|<iq/> 3-v---------+ +->| requester | 6-----------+ l+----->| HTTPgate | | | | JabberRPC | l| l===| component | +-----------+ | responder | l| +--->| | | (client) | l| |l +-----------+ +-----------+ l| |l ^ l| |l | <iq/> l| |l v l| |l 7-----------+ l| |l | JSM |<---+ |l | component |===l |l | |<-----+l +-----------+ <iq/> l ^ l l | <iq/> : : v +---+ 8-----------+ | JabberRPC | | requester | | (client) | +-----------+
The diagram shows all the possible components in the Jabber-RPC and traditional HTTP-based XML-RPC world. Each box is numbered. Here are the descriptions:
This is an instance of this module (HTTPgate.pm) and serves as a gateway between HTTP-based and Jabber-based XML-RPC requests and responses. On the one side it uses an http component (see #2) to make and respond to HTTP calls, and on the other side it accepts and generates <iq/> packets containing XML-RPC encoded payloads.
The HTTPgate component uses this http component to make and receive HTTP calls. HTTP calls and responses are routed between the HTTPgate component and this component via <route/>s. You need an http component like this for HTTPgate to work; download the code from http://download.jabber.org.
This represents a web server on which an XML-RPC responder is present.
This represents a traditional HTTP-based XML-RPC requester.
This is a Jabber-RPC responder that has been attached to the Jabber backbone as a component. It responds to XML-RPC encoded requests carried in <iq/> packets.
This is a Jabber-RPC responder that is connected to Jabber via the JSM (Jabber Session Manager) as a client. It also responds to XML-RPC encoded requests carried in <iq/> packets.
This doesn't have anything to do with Jabber-RPC per se, it's just that Jabber clients connect via the JSM.
This is a Jabber-RPC requester, in the form of a Jabber client, connected via the JSM.
The Jabber-RPC requester (#8) connects to Jabber via the JSM and creates an XML-RPC encoded request and stores it as the query payload of an IQ packet. The namespace qualifying the query payload is jabber:iq:rpc. Normally, if the request were to to go a Jabber-RPC responder, the JID of that responder (e.g. jrpc.localhost/jrpc-server) would be specified in the 'to' attribute of the IQ packet. But in this case, we want to send the request to an HTTP responder (#3), so we go through the gateway - the HTTPgate component (#3).
The address of the HTTP responder is a URL, e.g.:
So we need to specify this URL somewhere - and we specify it in the resource part of the HTTPgate component's JID. So if the HTTPgate component's basic JID is jrpchttp.localhost, then we specify
as the target JID.
The HTTP requester (#4) formulates an XML-RPC encoded request and sends it to the http component (#2). What's the basic URL of the http component? Well, you specify a port in the component instance definition in the jabber.xml configuration file, like this:
<service id="http"> <load><http>./http/http.so</http></load> <http xmlns="jabber:config:http"> <listen port="5281"> <map to="jrpchttp.localhost"/> </listen> <timeout>60</timeout> <dnsrv>http-dns</dnsrv> </http> </service>
See the README in the http component tarball for more info.
So the basic URL of the http component is e.g.:
While we need to specify a URL when we call a HTTP-based XML-RPC responder from Jabber, this time we need to specify a JID when calling a Jabber-based XML-RPC responder from HTTP. What we do is extend the URL by specifying JID as the path, like this:
In this example, the Jabber-RPC responder is connected to Jabber as a client, not a component - you can tell this from the JID by the existence of an @ sign (user@hostname - users (their sessions) are managed by the JSM).
You need three components to get this working in both directions; the HTTPgate component itself, the http component, and a helper DNS resolver component for when the http component wants to make outgoing HTTP requests. Setting up the latter two components are described in the http component's README. (The helper DNS resolver is identified in the example above by the <dnsrv/> tag).
In the HTTPgate's instantiation call, e.g.:
my $gw = new Jabber::RPC::HTTPgate( server => 'localhost:5701', identauth => 'jrpchttp.localhost:secret', httpcomp => 'http', );
there are three arguments required.
This argument specifies the host and port to which the HTTPgate component will connect. You will need a corresponding component instance definition in your jabber.xml configuration file that looks like this:
<service id='jrpchttp.localhost'> <accept> <ip>127.0.0.1</ip> <secret>secret</secret> <port>5701</port> </accept> </service>
This is the identity and secret for the component, separated by a colon. The identity refers to the value of the 'id' attribute in the component instance definition, and the secret refers to the value of the <secret/> tag.
This is used to specify the name of the http component, and refers to the value of the 'id' attribute in the http component's instance definition in jabber.xml - see earlier for an example of this.