<?xml version='1.0' encoding='UTF-8'?> <!DOCTYPE xep SYSTEM 'xep.dtd' [ <!ENTITY % ents SYSTEM 'xep.ent'> %ents; ]> <?xml-stylesheet type='text/xsl' href='xep.xsl'?> <xep> <header> <title>Jabber-RPC</title> <abstract>This specification defines a method for transporting XML-RPC encoded requests and responses over Jabber/XMPP.</abstract> &LEGALNOTICE; <number>0009</number> <status>Final</status> <type>Standards Track</type> <sig>Standards</sig> <dependencies> <spec>XMPP Core</spec> <spec>XML-RPC</spec> </dependencies> <supersedes/> <supersededby/> <shortname>jabber-rpc</shortname> <schemaloc> <url>http://www.xmpp.org/schemas/jabber-rpc.xsd</url> </schemaloc> <author> <firstname>DJ</firstname> <surname>Adams</surname> <email>dj.adams@pobox.com</email> <jid>dj@gnu.mine.nu</jid> </author> <revision> <version>2.1</version> <date>2006-02-09</date> <initials>psa</initials> <remark>Defined error handling, service discovery, security considerations, and XMPP Registrar considerations.</remark> </revision> <revision> <version>2.0</version> <date>2002-12-09</date> <initials>psa</initials> <remark>Per a vote of the Jabber Council, changed status to Final.</remark> </revision> <revision> <version>1.0</version> <date>2001-09-27</date> <initials>psa</initials> <remark>Changed status to Draft</remark> </revision> <revision> <version>0.1</version> <date>2001-09-14</date> <initials>dja</initials> <remark>Initial version</remark> </revision> </header> <section1 topic='Introduction'> <p>&xmlrpc; is a method of encoding RPC requests and responses in XML. The original specification defines HTTP (see &rfc2068;) as the only valid transport for XML-RPC payloads.</p> <p>Various initiatives exist already to transport XML-RPC payloads over Jabber. These initiatives were independent of each other and used slightly differing methods (e.g. carrying the payload in a <message/> element as opposed to an &IQ; stanza), resulting in potential interoperability problems.</p> <p>A working session during JabberCon 2001 resulted in a <link url="http://www.pipetree.com/jabber/jrpc.html">formalisation</link> of a single method. This document describes that method, which is labelled as Jabber-RPC to differentiate it from XML-RPC itself.</p> </section1> <section1 topic='Jabber-RPC'> <p>The &IQ; stanza is used to transport XML-RPC payloads. XML-RPC requests are transported using an &IQ; stanza of type "set", and XML-RPC responses are transported using an &IQ; stanza of type "result". An &IQ; stanza MUST NOT contain more than one request or response.</p> <p>The &IQ; stanza contains a single &QUERY; sub-element in the jabber:iq:rpc namespace. The direct child of the &QUERY; element will be either a single <methodCall/> element (in the case of a request) or a single <methodResponse/> element (in the case of a response). This child element will contain the XML-RPC payload. Note that the XML declaration that normally appears at the head of an XML-RPC request or response when transported as the payload of an HTTP POST request MUST BE omitted when it is transported via a Jabber &IQ; stanza.</p> <p>The encoding of the Jabber XML stream is UTF-8. It is assumed that the encoding of the XML-RPC payload is also UTF-8.</p> <p>Application-level errors will be indicated within the XML-RPC payload (as is the case with the traditional HTTP-based XML-RPC mechanism). Transport level errors will be indicated in the normal way for &IQ; stanzas -- namely, by an &IQ; stanza of type "error" and the addition of an <error/> tag as a direct child of the &IQ; stanza. There are no specific XML-RPC-related, transport-level errors.</p> </section1> <section1 topic='Examples'> <example caption='A typical request'><![CDATA[ <iq type='set' from='requester@company-b.com/jrpc-client' to='responder@company-a.com/jrpc-server' id='rpc1'> <query xmlns='jabber:iq:rpc'> <methodCall> <methodName>examples.getStateName</methodName> <params> <param> <value><i4>6</i4></value> </param> </params> </methodCall> </query> </iq> ]]></example> <example caption='A typical response'><![CDATA[ <iq type='result' from='responder@company-a.com/jrpc-server' to='requester@company-b.com/jrpc-client' id='rpc1'> <query xmlns='jabber:iq:rpc'> <methodResponse> <params> <param> <value><string>Colorado</string></value> </param> </params> </methodResponse> </query> </iq> ]]></example> <p>If the requesting entity does not have sufficient permissions to perform remote procedure calls, the responding entity MUST return a &forbidden; error:</p> <example caption='Requesting entity is forbidden to perform remote procedure calls'><![CDATA[ <iq type='error' from='responder@company-a.com/jrpc-server' to='requester@company-b.com/jrpc-client' id='rpc1'> <query xmlns='jabber:iq:rpc'> <methodCall> <methodName>examples.getStateName</methodName> <params> <param> <value><i4>6</i4></value> </param> </params> </methodCall> </query> <error code='403' type='auth'> <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/> </error> </iq> ]]></example> </section1> <section1 topic='Service Discovery' anchor='disco'> <p>If an entity supports the Jabber-RPC protocol, it SHOULD advertise that fact in response to &xep0030; information ("diso#info") requests by returning an identity of "automation/rpc" and a feature of "jabber:iq:rpc":</p> <example caption='A disco#info query'><![CDATA[ <iq type='get' from='requester@company-b.com/jrpc-client' to='responder@company-a.com/jrpc-server' id='disco1'> <query xmlns='http://jabber.org/protocol/disco#info'/> </iq> ]]></example> <example caption='A disco#info response'><![CDATA[ <iq type='result' to='requester@company-b.com/jrpc-client' from='responder@company-a.com/jrpc-server' id='disco1'> <query xmlns='http://jabber.org/protocol/disco#info'> <identity category='automation' type='rpc'/> <feature var='jabber:iq:rpc'/> </query> </iq> ]]></example> </section1> <section1 topic='Security Considerations' anchor='security'> <p>An entity that supports Jabber-RPC SHOULD establish a "whitelist" of entities that are allowed to perform remote procedure calls and MUST return a &forbidden; error if entities with insufficient permissions attempt such calls.</p> </section1> <section1 topic='IANA Considerations' anchor='iana'> <p>This document requires no interaction with &IANA;.</p> </section1> <section1 topic="XMPP Registrar Considerations" anchor='registrar'> <section2 topic='Protocol Namespaces' anchor='registrar-ns'> <p>The ®ISTRAR; includes 'jabber:iq:rpc' in its registry of protocol namespaces.</p> </section2> <section2 topic='Service Discovery Identity' anchor='registrar-disco'> <p>The XMPP Registrar includes a Service Discovery type of "rpc" within the "automation" category in its registry of service discovery identities.</p> </section2> </section1> <section1 topic='XML Schema'> <code><![CDATA[ <?xml version='1.0' encoding='UTF-8'?> <xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema' targetNamespace='jabber:iq:rpc' xmlns='jabber:iq:rpc' elementFormDefault='qualified'> <xs:annotation> <xs:documentation> The protocol documented by this schema is defined in XEP-0009: http://www.xmpp.org/extensions/xep-0009.html There is no official XML schema for XML-RPC. The main body of this schema has been borrowed from an unofficial schema representation contained in the book "Processing XML With Java" by Elliotte Rusty Harold, as located at: http://www.ibiblio.org/xml/books/xmljava/chapters/ch02s05.html </xs:documentation> </xs:annotation> <xs:element name='query'> <xs:complexType> <xs:choice minOccurs='0' maxOccurs='1'> <xs:element ref='methodCall'/> <xs:element ref='methodResponse'/> </xs:choice> </xs:complexType> </xs:element> <xs:element name="methodCall"> <xs:complexType> <xs:all> <xs:element name="methodName"> <xs:simpleType> <xs:restriction base="ASCIIString"> <xs:pattern value="([A-Za-z0-9]|/|\.|:|_)*" /> </xs:restriction> </xs:simpleType> </xs:element> <xs:element name="params" minOccurs="0" maxOccurs="1"> <xs:complexType> <xs:sequence> <xs:element name="param" type="ParamType" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> </xs:element> </xs:all> </xs:complexType> </xs:element> <xs:element name="methodResponse"> <xs:complexType> <xs:choice> <xs:element name="params"> <xs:complexType> <xs:sequence> <xs:element name="param" type="ParamType"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="fault"> <!-- What can appear inside a fault is very restricted --> <xs:complexType> <xs:sequence> <xs:element name="value"> <xs:complexType> <xs:sequence> <xs:element name="struct"> <xs:complexType> <xs:sequence> <xs:element name="member" type="MemberType"> </xs:element> <xs:element name="member" type="MemberType"> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:choice> </xs:complexType> </xs:element> <xs:complexType name="ParamType"> <xs:sequence> <xs:element name="value" type="ValueType"/> </xs:sequence> </xs:complexType> <xs:complexType name="ValueType" mixed="true"> <xs:choice> <xs:element name="i4" type="xs:int"/> <xs:element name="int" type="xs:int"/> <xs:element name="string" type="ASCIIString"/> <xs:element name="double" type="xs:decimal"/> <xs:element name="Base64" type="xs:base64Binary"/> <xs:element name="boolean" type="NumericBoolean"/> <xs:element name="dateTime.iso8601" type="xs:dateTime"/> <xs:element name="array" type="ArrayType"/> <xs:element name="struct" type="StructType"/> </xs:choice> </xs:complexType> <xs:complexType name="StructType"> <xs:sequence> <xs:element name="member" type="MemberType" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> <xs:complexType name="MemberType"> <xs:sequence> <xs:element name="name" type="xs:string" /> <xs:element name="value" type="ValueType"/> </xs:sequence> </xs:complexType> <xs:complexType name="ArrayType"> <xs:sequence> <xs:element name="data"> <xs:complexType> <xs:sequence> <xs:element name="value" type="ValueType" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> <xs:simpleType name="ASCIIString"> <xs:restriction base="xs:string"> <xs:pattern value="([ -~]|\n|\r|\t)*" /> </xs:restriction> </xs:simpleType> <xs:simpleType name="NumericBoolean"> <xs:restriction base="xs:boolean"> <xs:pattern value="0|1" /> </xs:restriction> </xs:simpleType> </xs:schema> ]]></code> </section1> </xep>