This commit is contained in:
2019-02-06 00:49:12 +03:00
commit 8dbb1bb605
4796 changed files with 506072 additions and 0 deletions

View File

@@ -0,0 +1,72 @@
<appendix id="ljp.csp.faq">
<title>Frequently Asked Questions</title>
<qandaset>
<qandaentry id="ljp.csp.faq.urlitemid">
<question><simpara>How do I calculate the protocol itemid to get the <quote>URL</quote> itemid?</simpara></question>
<answer><simpara>For protocol methods that return an <varname>itemid</varname>, there is also another variable returned called <varname>anum</varname>.
To calculate the public URL itemid, use the following formula: <inlineequation>(itemid * 256) + anum</inlineequation>.
</simpara></answer>
</qandaentry>
<qandaentry id="ljp.csp.faq.datalimits">
<question><simpara>What are the limitations on post and user information data?</simpara></question>
<answer><para>To help calculate portions of your client, here are the upper limits of client affected data:
<itemizedlist>
<listitem><simpara>Posts: 65,535 bytes</simpara></listitem>
<listitem><simpara>Entry Properties (Currents): 255 bytes or 100 characters</simpara></listitem>
<listitem><simpara>Entry Subjects: 255 bytes or 100 characters</simpara></listitem>
<listitem><simpara>User Picture Keywords: 40 characters</simpara></listitem>
<listitem><simpara>Usernames: 15 characters</simpara></listitem>
<listitem><simpara>Name: 50 characters</simpara></listitem>
<listitem><simpara>Webpage URL: 255 bytes</simpara></listitem>
<listitem><simpara>Webpage Name: 255 bytes</simpara></listitem>
</itemizedlist>
</para></answer>
</qandaentry>
<qandaentry id="ljp.csp.faq.downloadpage">
<question><simpara>I just wrote a client for LiveJournal. How do I go about getting it on the Download page?</simpara></question>
<answer>
<simpara>The Downloads page currently requires manual updates, which happen infrequently.
Due to the large userbase which uses clients offered up via the Downloads page, we
prefer to only add well-established clients to the page at this point.
</simpara>
<simpara>
All too often, someone will code a client and then abandon it after a certain amount of time.
If you feel that you are willing and able to commit to maintaining and providing support for
a client, then by all means produce one and announce it on
<ulink url="http://www.livejournal.com/community/lj_clients/info">lj_clients</ulink>. It is
recommended that you create a community for the users of your client, so you can announce new
versions and provide a forum for troubleshooting and user support. Once your client has
matured, it will likely be included on the Downloads page. If your program has reached a
point where you feel it should be included in the page and it hasn't been yet, feel free to
drop a post to <ulink url="http://www.livejournal.com/community/lj_clients/info">lj_clients</ulink>
asking why.
</simpara>
<itemizedlist>
<title>Client Listing Guidelines for the <ulink url="http://www.livejournal.com/download/">Download a Client</ulink> page</title>
<listitem><simpara>As a minimum, clients MUST support the basic features of LiveJournal,
such as logging in, posting new entries, editing old entries, history views, etc.</simpara></listitem>
<listitem><simpara>Client MUST be mature and well-established before being listed. Having minor bugs is ok, but
we don't want to link to clients that have the potential to mess up an account.</simpara></listitem>
<listitem><simpara>Client MUST be free to use. You're welcome to create and maintain a
client that isn't free/open, we just don't want to provide free advertising for such a client.</simpara></listitem>
<listitem><simpara>Client MUST be originally written for LiveJournal. We support the Blogger and Atom APIs, and
we encourage interoperational clients, but we don't want to get in the habit of listing clients for
competitor services.</simpara></listitem>
</itemizedlist>
</answer>
</qandaentry>
<qandaentry id="ljp.csp.faq.userinfopage">
<question><simpara>Why doesn't my client show up on my user info page?</simpara></question>
<answer><simpara>Recently client logging was disabled because its current implementation was consuming
far too many database resources. It will likely reappear in the future, once a more efficient design
is coded and tested.
</simpara></answer>
</qandaentry>
</qandaset>
</appendix>
<!--
Local Variables:
mode:sgml
sgml-parent-document: ("index.xml" "part" "appendix")
End:
-->

View File

@@ -0,0 +1,122 @@
<chapter id="ljp.csp.auth">
<title>Authentication in the Client Server Protocol</title>
<section id="ljp.csp.auth.clear">
<title>Clear</title>
<warning><simpara>Although this method is still supported, it is DEPRECATED and should not be used. Client authors
SHOULD use another authentication method if it is available to them.</simpara></warning>
<para>The default authentication method is known as <quote>clear</quote>, which refers to the fact that <literal>password</literal>s
are being sent as plain-text (<quote>in the clear</quote>). Though clients have the ability to encrypt passwords
in a one way hash function (MD5) and send them to the server (as <literal>hpassword</literal>), they are still
vulnerable to replay attacks if the hashed password becomes known.</para>
<para><quote>Clear</quote> authentication occurs when a <literal>username</literal> and either <literal>password</literal>
or <literal>hpassword</literal> is passed to any client server protocol method.</para>
</section>
<section id="ljp.csp.auth.cookies">
<title>HTTP Cookies</title>
<para>If you specify <parameter>auth_method</parameter> with the value of <quote>cookie</quote>, you can use
session cookies generated by the server in your client. To prevent against the usage of modified forms to perform
actions without the consent of the user, we require the <abbrev>HTTP</abbrev> header <literal>X-LJ-Auth</literal>
be set to <quote>cookie</quote> as well.</para>
<example>
<title>Using Wget 1.9 with <literal>auth_method=cookie</literal> in flat protocol</title>
<screen><prompt>$</prompt> <command>wget</command> <option>--post-data "mode=login&amp;user=test&amp;auth_method=cookie"</option> <option>--header "X-LJ-Auth: cookie"</option> <option>--header "Cookie: ljsession=<replaceable>cookieval</replaceable></option> &siteroot;/interface/flat</screen>
</example>
</section>
<section id="ljp.csp.auth.challresp">
<title>Challenge / Response</title>
<para>Another way to authenticate your client is to build a hex digest consisting of the user's password and
a challenge as issued by the server. This is currently known as <parameter>auth_method</parameter> <quote>challenge</quote>.</para>
<para>Essentially, you generate a challenge by issuing a blank request to the <methodname>getchallenge</methodname> method. If your
method call is successful you're given:</para>
<variablelist>
<varlistentry>
<term><type>string</type> <returnvalue>auth_scheme</returnvalue></term>
<listitem><simpara>You can ignore this for now. By default this is the highest version of our
authentication schemes, if in the future if we implement other auth schemes or change the default.
In that case we'd add a new capabilities exchange: your client could say, "I know c0 and c1", and
our server would then say, "Use c1, it's the best."</simpara></listitem>
</varlistentry>
<varlistentry>
<term><type>string</type> <returnvalue>challenge</returnvalue></term>
<listitem><simpara><returnvalue>challenge</returnvalue> is an opaque cookie, as generated by
<xref linkend="ljp.api.lj.get_challenge" />. Challenges may only be used once.</simpara></listitem>
</varlistentry>
<varlistentry>
<term><type>int</type> <returnvalue>expire_time</returnvalue></term>
<listitem><simpara><returnvalue>expire_time</returnvalue> is the expiration time for the challenge
as measured in seconds since the Unix epoch.</simpara></listitem>
</varlistentry>
<varlistentry>
<term><type>int</type> <returnvalue>server_time</returnvalue></term>
<listitem><simpara><returnvalue>servertime</returnvalue> is the time of when the challenge was generated,
as measured in seconds since the Unix epoch. The formula (<returnvalue>server_time</returnvalue> -
<returnvalue>expire_time</returnvalue>) is the life span of the challenge, in seconds.</simpara></listitem>
</varlistentry>
</variablelist>
<para>For your response, you then build a MD5 hex digest of the formula (<returnvalue>challenge</returnvalue>
+ MD5_hex(<literal>password</literal>)). To authenticate your client now, you simply send back the following 3
parameters, along with your username:</para>
<variablelist>
<varlistentry>
<term><type>string</type> <parameter>auth_method</parameter></term>
<listitem><simpara>Set to <quote>challenge</quote></simpara></listitem>
</varlistentry>
<varlistentry>
<term><type>string</type> <parameter>auth_challenge</parameter></term>
<listitem><simpara>The challenge issued by the server</simpara></listitem>
</varlistentry>
<varlistentry>
<term><type>string</type> <parameter>auth_response</parameter></term>
<listitem><simpara>MD5_hex(<returnvalue>challenge</returnvalue> + MD5_hex(<literal>password</literal>))</simpara></listitem>
</varlistentry>
</variablelist>
<example>
<title>Sample Perl script using <methodname>getchallenge</methodname></title>
<programlisting><![CDATA[
use strict;
use Fcntl;
use XMLRPC::Lite;
use Data::Dumper;
use Digest::MD5 qw(md5_hex);
my $xmlrpc = new XMLRPC::Lite;
$xmlrpc->proxy("http://www.lj.com/interface/xmlrpc");
my $get_chal = xmlrpc_call("LJ.XMLRPC.getchallenge");
my $chal = $get_chal->{'challenge'};
my $user = "test";
my $pass = "pass";
print "chal: $chal\n";
my $response = md5_hex($chal . md5_hex($pass));
my $login = xmlrpc_call('LJ.XMLRPC.login', {
'username' => $user,
'auth_method' => 'challenge',
'auth_challenge' => $chal,
'auth_response' => $response,
});
print Dumper($login);
sub xmlrpc_call {
my ($method, $req) = @_;
my $res = $xmlrpc->call($method, $req);
if ($res->fault) {
print STDERR "Error:\n".
" String: " . $res->faultstring . "\n" .
" Code: " . $res->faultcode . "\n";
exit 1;
}
return $res->result;
}]]>
</programlisting>
</example>
</section>
</chapter>
<!--
Local Variables:
mode:sgml
sgml-parent-document: ("index.xml" "book" "part")
End:
-->

View File

@@ -0,0 +1,36 @@
<chapter id="ljp.csp.blogger">
<title>Supporting the Blogger API</title>
<para>
Like LiveJournal, the weblog service <ulink url="http://www.blogger.com/">Blogger</ulink> provides a programmatic interface that's been built with <ulink url="http://www.xmlrpc">XML-RPC</ulink>. To allow our users to make use of popular Blogger-compatible tools (Radio, Blogbuddy, w.bloggar, TextRouter), we've added internal support for their API. However, <ulink url="http://www.blogger.com/developers/api/1_docs/">the Blogger API</ulink> is currently labeled as <quote>experimental and alpha</quote>, and will not be developed further.<footnote><simpara>Blogger: <quote>We are working along with others in the blogging industry to produce a new, more robust API. You can view the current state of <ulink url="http://www.intertwingly.net/wiki/pie/RoadMap">the Echo Project here</ulink>.</quote></simpara></footnote>
</para>
<para>
The Blogger interface address for a LiveJournal installation is <ulink url="/interface/blogger/" />.
</para>
<itemizedlist>
<title>Supported Methods</title>
<para>LiveJournal supports the following Blogger API methods (methods are linked to relevant documentation):</para>
<listitem><simpara><ulink url="http://www.blogger.com/developers/api/1_docs/xmlrpc_newPost.html">blogger.newPost</ulink></simpara></listitem>
<listitem><simpara><ulink url="http://www.blogger.com/developers/api/1_docs/xmlrpc_editPost.html">blogger.editPost</ulink></simpara></listitem>
<listitem><simpara><ulink url="http://groups.yahoo.com/group/bloggerDev/message/147">blogger.deletePost</ulink></simpara></listitem>
<listitem><simpara><ulink url="http://www.blogger.com/developers/api/1_docs/xmlrpc_getUsersBlogs.html">blogger.getUsersBlogs</ulink></simpara></listitem>
<listitem><simpara><ulink url="http://groups.yahoo.com/group/bloggerDev/message/225">blogger.getRecentPosts</ulink></simpara></listitem>
<listitem><simpara><ulink url="http://groups.yahoo.com/group/bloggerDev/message/296">blogger.getPost</ulink></simpara></listitem>
<listitem><simpara><ulink url="http://www.blogger.com/developers/api/1_docs/xmlrpc_getUserInfo.html">blogger.getUserInfo</ulink></simpara></listitem>
</itemizedlist>
<itemizedlist>
<title>Notes</title>
<listitem><simpara>LiveJournal makes no use of the <parameter>appkey</parameter> parameter.</simpara></listitem>
<listitem><simpara>The Blogger API does not support the use of post titles (subjects). To set a title for your post
include the title wrapped in &lt;title&gt; tags in your post body.</simpara></listitem>
<listitem><simpara>LiveJournal specific meta data (current mood and music) are supported by including a line consisting of <parameter>lj-<replaceable>metadatakey</replaceable>: metadata</parameter> in the post body (e.g. <parameter>lj-mood: happy</parameter>).</simpara></listitem>
<listitem><simpara>The <parameter>publish</parameter> parameter is always set true.</simpara></listitem>
<listitem><simpara>blogger.getUserInfo will return the account's name for both <parameter>firstname</parameter> and <parameter>lastname</parameter>.</simpara></listitem>
<listitem><simpara>Due to the differences between Blogger's and LiveJournal's template systems, the <methodname>blogger.getTemplate</methodname> and <methodname>blogger.setTemplate</methodname> methods are not supported.</simpara></listitem>
</itemizedlist>
</chapter>
<!--
Local Variables:
mode:sgml
sgml-parent-document: ("index.xml" "book" "part")
End:
-->

View File

@@ -0,0 +1,151 @@
<chapter id="ljp.csp.guide">
<chapterinfo>
<title>Client / Server Protocol - Quick Reference</title>
</chapterinfo>
<title>Client / Server Protocol - Quick Reference</title>
<section id="ljp.csp.guide.intro">
<title>Introduction to the Protocol</title>
<note>
<para>
Before reading this document, it is assumed you know at least some
basics about network programming, at least the whole idea of opening
sockets and reading/writing to them. If not, this might be kinda
confusing.
</para>
</note>
<para>Basically, sending a LiveJournal request is like this:</para>
<procedure>
<title>Handshake</title>
<step>
<para>Open a socket to www.livejournal.com on port 80</para>
</step>
<step>
<para>Send an HTTP POST request, containing the request variables (mode, user, password, etc...)</para>
</step>
<step>
<para>Read the socket to get the response. The response is really easy to parse.</para>
</step>
<step>
<para>Close the socket. Do any approriate action based on the server&apos;s response.</para>
</step>
</procedure>
<para>For example, your client would output a request:
<programlisting>
<![CDATA[
POST /interface/flat HTTP/1.0
Host: www.livejournal.com
Content-type: application/x-www-form-urlencoded
Content-length: 34
mode=login&user=test&password=test
]]>
</programlisting>
</para>
<note>
<para>
All values must be quoted or the values can interfere with the encoding form.
For example, if someone's password was <quote>blah&amp;=2+&amp;something=yeah</quote>,
it could quite possibly ruin the encoding format.
Here are some guidelines on how to encode values:
<itemizedlist>
<listitem><para>Leave all values from a-z, A-Z, and 0-9 alone. These are fine.</para></listitem>
<listitem><para>Convert spaces to a + (plus) sign.</para></listitem>
<listitem><para>Convert everything else to %<replaceable>hh</replaceable> where <replaceable>hh</replaceable> is the hex representation of the character's <abbrev>ASCII</abbrev> value.</para></listitem>
</itemizedlist>
</para>
<para>
For example, the phrase <quote>I'm going to the mall</quote> could encoded as <quote>I%27m+going+to+the+mall</quote>.
There should be <abbrev>CGI</abbrev> libraries for all major languages which do this encoding for you.
If not, it isn't that hard to do it yourself.
</para>
</note>
<para>
After you construct the big long ugly string of variables/values, find the length of
it and send it in the Content-length field, as in the example above.
Then send a blank line, then the big long ugly string.
</para>
<note><title>Line Endings</title>
<para>
Please note that the end of lines should be a carriage return
(<abbrev>ASCII</abbrev> <literal>13</literal>, <literal>0x0D</literal>) and then a
newline (<abbrev>ASCII</abbrev> <literal>10</literal>, <literal>0x0A</literal>).
In Perl, C/C++ or Java this is <quote>\r\n</quote>.
In Basic, this is <literal>Chr(13)</literal> &amp; <literal>Chr(10)</literal>.
Sending just the newline may work too, but it's generally better to send both.
</para>
</note>
<para>A typical response would be:
<programlisting>
<![CDATA[
HTTP/1.1 200 OK
Date: Sat, 23 Oct 1999 21:32:35 GMT
Server: Apache/1.3.4 (Unix)
Connection: close
Content-Type: text/plain
name
Mr. Test Account
success
OK
message
Hello Test Account!
]]>
</programlisting>
</para>
<para>
The top stuff is headers from the <abbrev>HTTP</abbrev> request.
There may be a lot of other stuff in there too.
First thing to do is make sure the first lines ends with <quote><literal>200 OK</literal></quote>.
If the first line does not end with <quote><literal>200 OK</literal></quote>,
tell the user that an error occurred on the server and that it&apos;s not their fault.
If you see <quote><literal>200 OK</literal></quote> at the end, proceed with parsing the output.
The format is as follows:
<programlisting>
variable
value
someothervariable
someothervalue
</programlisting>
The ordering of the variable/value pairs does not matter.
As you read them in, read them into a hash structure
(associative array, dictionary, collection&hellip;whatever it's called in your language.
Just a data structure that links one string variable key to another string variable value.).
</para>
<para>
After your hash is loaded, proceed with the logic of reporting errors if needed, as governed by the variables and logic above.
</para>
</section>
<section id="ljp.csp.guide.proxies">
<title>Working with Proxies</title>
<para>
As a final feature, once you get that stuff working, is to implement
support for HTTP proxies. This is <emphasis>very</emphasis> easy. Give the
user a checkbox if they want to use a proxy or not, and if so,
ask the proxy host and proxy port. Now, if they selected to use a proxy, do
not connect to www.livejournal.com and port 80, but instead connect to their
proxy host on whatever proxy port they specified. The rest is basically the
same, except for one difference. Instead of doing:
<programlisting>
<![CDATA[
POST /interface/flat HTTP/1.0 ]]>
</programlisting>
You would do:
<programlisting>
<![CDATA[
POST http://www.livejournal.com/interface/flat HTTP/1.0 ]]>
</programlisting>
</para>
<para>
That line tells the proxy what host it needs to connect to in order to
make the real request. The rest of the HTTP you should leave just as you did
before.
</para>
</section>
<note><title>Client Developer Community</title>
<para>
If you ever have any questions about building clients for LiveJournal, then
you'd probably interested in the <ulink url="http://www.livejournal.com/users/lj_clients/info">lj_clients community</ulink>
on LiveJournal.com
</para>
</note>
</chapter>

View File

@@ -0,0 +1,28 @@
<reference id="ljp.csp.flat.protocol">
<referenceinfo>
<title>Flat Client/Server Protocol Reference</title>
</referenceinfo>
<title>Flat Client/Server Protocol Reference</title>
<partintro>
<para>
This is a reference to the <quote>flat</quote> interface to LiveJournal,
where <quote>flat</quote> is simpy a term describing the raw
<abbrev>HTTP</abbrev> request sent to a LiveJournal server.
</para>
<para>
This interface passes uses simple key/value pairs for every request and response.
The benefit is that it's easy to parse the response given by the server, if you
are left to your own devices, and have to do it yourself.
As an alternative, there exists an <link linkend="ljp.csp.xml-rpc.protocol"><abbrev>XML-RPC</abbrev> Interface</link>
<footnote id="note.xml-rpc">
<para>
<abbrev>XML-RPC</abbrev> is something most programming languages have a library for.
Check <ulink url="http://www.xmlrpc.com/directory/1568/implementations" /> to see if there is an
implementation for your language of choice.
</para>
</footnote>,
which returns the data in a predetermined (nested) format that is easier to work with directly.
</para>
</partintro>
&ljp.csp.flat.protocol;
</reference>

View File

@@ -0,0 +1,33 @@
<part id="ljp.csp.protocol" status="prelim">
<title>Client/Server Protocol</title>
<partintro>
<para>
Currently there are a few types of interfaces available to the LiveJournal
protocol: the older "flat" interface, the custom XML-RPC interface, and a modified version of the Blogger API.
The XMLRPC interface is probably easiest to use, because there are quite a few XML-RPC
resources available to developers in just about any programming language. If
you're in a situation that requires you to write your own interface wrapper,
then the flat interface is probably best to use.
</para>
<tip>
<para>
Internally, all interfaces are just wrappers around the same functions. Don't
worry too much about which one you use, as they accomplish the same thing.
</para>
</tip>
</partintro>
&ljp.csp.guide;
&ljp.csp.auth;
&ljp.csp.flat.index;
&ljp.csp.xml-rpc.index;
&ljp.csp.blogger;
&ljp.csp.versions;
&ljp.csp.proplist;
&ljp.csp.appx.faq;
</part>
<!--
Local Variables:
mode:sgml
sgml-parent-document: ("../index.xml" "book" "part")
End:
-->

View File

@@ -0,0 +1,7 @@
<chapter id="ljp.csp.proplist">
<title>Journal Item Meta-data</title>
<para>
This is a list of the meta-data that can be assigned to journal items.
</para>
&ljp.csp.proplist.ref;
</chapter>

View File

@@ -0,0 +1,46 @@
<chapter id="ljp.csp.versions">
<title>Protocol Versions</title>
<para>
The LiveJournal protocol (so far) has been more or less static; while new
modes have been added, the basic operation has not changed much. However,
recent introduction of Unicode support in LiveJournal necessitated changes
in the way text is encoded in protocol requests and responses. In order to
allow new clients to take advantage of Unicode support and at the same time
avoid breaking existing clients, a versioning scheme has been put into the
protocol. The client sends the number of the highest protocol version it
supports in every request, inside a <varname>ver</varname> attribute; version
<literal>0</literal> is implicit if the client does not send the
<varname>ver</varname> attribute. Currently there are two versions of the
protocol, and the Unicode-enabled server code supports both of them.
</para>
<itemizedlist>
<listitem><formalpara><title>Version <literal>0</literal></title>
<para>
If a client does not send a <varname>ver</varname> key on a request,
it assumed to support protocol Version <literal>0</literal>. In protocol
Version <literal>0</literal>, textual information transmitted from or to
the server is always assumed to be a stream of 8-bit bytes, not necessarily
<abbrev>ASCII</abbrev>, but without any guarantee that the
non-<abbrev>ASCII</abbrev> bytes are presented in any particular encoding.
</para></formalpara></listitem>
<listitem><formalpara><title>Version <literal>1</literal></title>
<para>
Version <literal>1</literal> differs from Version <literal>0</literal> only
by imposing additional requirements on the text transmitted through requests
and responses; there aren't any changes in protocol modes. The additional
requirements are that in a Version <literal>1</literal> request, the client
<emphasis>must</emphasis> transmit all textual information as a stream of
Unicode data encoded in <abbrev>UTF-8</abbrev>; the server <emphasis>must</emphasis>
respond to Version <literal>1</literal> requests with Version <literal>1</literal>
responses; in such Version <literal>1</literal> responses, the server
<emphasis>must</emphasis> also transmit all textual information encoded in
<abbrev>UTF-8</abbrev>; and the client <emphasis>must</emphasis> expect that
and handle such responses correctly. In other words, all information transmitted
via protocol when Version <literal>1</literal> is used is always encoded in
<abbrev>UTF-8</abbrev>. <abbrev>UTF-8</abbrev> is a representation of Unicode
in a bytestream format compatible with <abbrev>ASCII</abbrev>.
<footnote id="unicode"><para>See the <ulink url="http://www.unicode.org/">Unicode Consortium website</ulink>
for more information on Unicode and <abbrev>UTF-8</abbrev>.</para></footnote>
</para></formalpara></listitem>
</itemizedlist>
</chapter>

View File

@@ -0,0 +1,23 @@
<reference id="ljp.csp.xml-rpc.protocol">
<referenceinfo>
<title>XML-RPC Client/Server Protocol Reference</title>
</referenceinfo>
<title>XML-RPC Client/Server Protocol Reference</title>
<partintro>
<para>
This the <ulink url="http://www.xmlrpc.com/">XML-RPC</ulink><footnote id="csp.xml-rpc.spec-info"><para>For the XML-RPC spec, see: <ulink url="http://www.xmlrpc.com/spec" /></para></footnote> version of the Client/Server protocol.
XML-RPC allows programs to make procedure calls over the internet, regardless of differing operating systems and environments.
It's also handy for returning preconstructed libraries of information (instead of having to have your program parse the regular server feedback).
</para>
<para>
In order to use the XML-RPC interface, make sure your client is referencing the <filename>/interface/xmlrpc</filename> section of the LiveJournal site it is communicating with.
</para>
<note>
<title>Method Names</title>
<para>
The full title of each method is actually <literal>LJ.XMLRPC.<replaceable>foo</replaceable></literal>, where <replaceable>foo</replaceable> is the short name given below:
</para>
</note>
</partintro>
&ljp.csp.xml-rpc.protocol;
</reference>