This chapter describes the functions in the libxmlrpc_server_cgi++ function library, which is part of XML-RPC For C/C++ (Xmlrpc-c). Also see General Library Information - C
The libxmlrpc_server_cgi++ library provides C++ classes for use in a program that is an XML-RPC server based on CGI (Common Gateway Interface) scripts run by a web server.
When using libxmlrpc_server_cgi++, you must also use the libxmlrpc++ library. It contains additional facilities that an XML-RPC server needs but are general to XML-RPC and not specific to XML-RPC servers. Besides, the libxmlrpc_server_cgi++ classes depend on it.
Similarly, you will need the libxmlrpc_server++ library. It contains functions for XML-RPC servers that are not specific to CGI-based servers. And libxmlrpc_server_cgi++ classes depend on it.
libxmlrpc_server_cgi++ was new in Xmlrpc-c 1.16 (December 2008). The C version, libxmlrpc_server_cgi is much older.
The <xmlrpc-c/xmlrpc_server_cgi.hpp> header file declares the interface to libxmlrpc_server_cgi++.
You'll have to figure out where on your system this file lives and how to make your compiler look there for it, or use xmlrpc-c-config.
Because various other Xmlrpc-c libraries are prerequisites (and xmlrpc_server_cgi.hpp includes them), you'll also need their header files. It's easiest just to have the entire Xmlrpc-c package available.
The classic Unix name for the file containing the libxmlrpc_server_cgi++ library is libxmlrpc_server_cgi++.a or libxmlrpc_server_cgi++.so. The classic linker option to cause the library to be linked into your program is -l xmlrpc_server_cgi++. These are hints; you'll have to modify this according to conventions of your particular platform. You'll also have to figure out where the library resides and how to make your linker look there for it. Or use xmlrpc-c-config.
The following libraries are prerequisites of libxmlrpc_server_cgi, so you'll need to link them in too:
Here is an example of a C++ CGI program that uses libxmlrpc_server_cgi++ to effect an XML-RPC server.
#include <cassert>
#include <iostream>
#include <xmlrpc-c/base.hpp>
#include <xmlrpc-c/registry.hpp>
#include <xmlrpc-c/server_cgi.hpp>
using namespace std;
class sampleAddMethod : public xmlrpc_c::method {
public:
sampleAddMethod() {
// signature and help strings are documentation -- the client
// can query this information with a system.methodSignature and
// system.methodHelp RPC.
this->_signature = "i:ii"; // method's arguments, result are integers
this->_help = "This method adds two integers together";
}
void
execute(xmlrpc_c::paramList const& paramList,
xmlrpc_c::value * const retvalP) {
int const addend(paramList.getInt(0));
int const adder(paramList.getInt(1));
paramList.verifyEnd(2);
*retvalP = xmlrpc_c::value_int(addend + adder);
}
};
int
main(int const,
const char ** const) {
try {
xmlrpc_c::registry myRegistry;
xmlrpc_c::methodPtr const sampleAddMethodP(new sampleAddMethod);
myRegistry.addMethod("sample.add", sampleAddMethodP);
xmlrpc_c::serverCgi myServer(
xmlrpc_c::serverCgi::constrOpt()
.registryP(&myRegistry));
myServer.processCall();
} catch (exception const& e) {
cerr << "Something failed. " << e.what() << endl;
}
return 0;
}
This program, with procedures to build it, is in the Xmlrpc-c source tree as examples/cpp/xmlrpc_sample_add_server_cgi.cpp.
The manual for libxmlrpc_server_cgi++'s C cousin has some useful information on what CGI is about and how this library fits into it. The C++ library fits in the same way, just for a different language.
An object of class xmlrpc_c::serverCgi is the XML-RPC engine inside an XML-RPC server. The object does the XML-RPC part of executing one XML-RPC call, connecting to the HTTP server that does the rest of the work via CGI.
You use the object like this: your HTTP server, upon receiving an XML-RPC call, calls your CGI program. Your CGI program creates a serverCgi object, executes its processCall method, the destroys the object and exits. processCall gets information about the XML-RPC call via the CGI interface and delivers information for the XML-RPC response via the CGI interface.
You supply the XML-RPC methods for the server to execute as an Xmlrpc-c method registry. Though there's only one particular method that needs to execute (because there's only one XML-RPC call) you normally build a registry with all of the server's methods so your code doesn't have to decide which method is required.
See above.
Overview:
serverCgi::serverCgi(constrOpt const& opt);
Example:
xmlrpc_c::registry myRegistry;
...
xmlrpc_c::serverCgi cgiServer(xmlrpc_c::serverCgi::constrOpt()
.registryP(&myRegistry));
This constructor uses the constrOpt paradigm to make specifying options easy and flexible, though technically there is just one C++ parameter.
The option methods are:
You must specify either registryPtr or registry, and not both.
You must specify either registryPtr or registry, and not both.
This method does the XML-RPC part of executing an XML-RPC call. The entire point of your CGI program is to call this method once. It communicates with the web server via the CGI interface to get the XML-RPC call information and supply the XML-RPC response information.
The heart of what processCall does is call one of the method functions that you registered in the method registry tied to the serverCgi object.
processCall does its best to respond to any problems it has by generating an appropriate XML-RPC or HTTP error response. But if problems are so basic that it can't do that, it throws an error.
Example:
cgiServerP->processCall();
Prototype:
void processCall();
If you set the XMLRPC_TRACE_XML environment variable to 1, the CGI program prints to Standard Error the XML that it processes and returns. This is not much more informative than trace facilities that are probably available in your web server. But at least it will help you confirm that the CGI program is running and you are using the method registry correctly.