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 functions 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 library routines 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 library routines depend on it.
There is a C++ equivalent of this library: libxmlrpc_server_cgi++.
Before Xmlrpc-c 1.03 (June 2005), the library was called libxmlrpc_cgi. The name was changed for consistency with other components.
The <xmlrpc-c/xmlrpc_server_cgi.h> 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 the libxmlrpc and libxmlrpc_server libraries are prerequisites, you'll also need their header files (xmlrpc.h and xmlrpc_server.h).
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:
For a complete example of an XML-RPC server program that uses libxmlrpc_server_cgi, see CGI Server Example.
CGI (Common Gateway Interface) is a standard for use in web servers. It is a protocol for the web server to use in calling a user-supplied program to perform the meat of an HTTP request. Whereas a web server executes a classic HTTP GET request by sending the contents of a file named in the GET request, the web server can be configured instead to run an arbitrary CGI program. The program gets the data that came with the GET request and generates the data to be sent back in response. CGI also works with requests other than GET, including POST.
Since XML-RPC is implemented over HTTP (and a web server is an HTTP server), all you need for an XML-RPC server is a web server configured to invoke a CGI program that knows how to execute an XML-RPC call. libxmlrpc_server's method registry provides all the logic you need to execute an XML-RPC call, so all you have to do is hook that up to the CGI interface. libxmlrpc_server_cgi gives the facilities to make that connection.
It is common to call a CGI program a "CGI script." The term "script" doesn't really convey what it is, though. A script is a description of a simple procedure, normally one that a human would typically perform. The first scripts were written on paper and followed by human operators. Later, they were automated. The languages for writing automatic scripts became more and more capable and the scripts more and more complex until programs written in the scripting language bore far more resemblence to what has always been called a "program" than to what was originally called a "script." The distinction most people use today is that if a program is written in a language whose roots are in scripting, it's a script and otherwise, it's a program.
CGI programs are usually written in a language whose roots are in scripting, so they have come to be known as scripts. But regardless of what language you use to write a CGI program, "program" is a more meaningful name for it than "script."
How you set up a CGI program is a characteristic of your web server, and differs from one web server program to another.
However, if you can make your web server serve simple HTML web pages, it's usually an easy step from there to make it a CGI-based XML-RPC server. Just create a file whose name ends in ".cgi" instead of ".html". That file should contain a program (an executable) you created using libxmlrpc_cgi.
Note that when you create an XML-RPC server this way, its URL may not be of the classic "/RPC2" form. And that means simple programs may not be able to use it, at least not without coaxing. The URL would have the same form as you would use to browse .html files in the same place. For example, if you put the CGI program in a personal web directory, the URL might be http://www.acme.com/~johndoe/sample_add.cgi.
It's common for a web server to be configured with CGI disabled, for security reasons.
For Apache, you the CGI program must go in a directory that has the "ExecCGI" option, which gives the user permission to run CGI programs in the directory. Specify that in the Apache configuration file.
You must configure the web server to recognize your URL as a CGI program to run, as opposed to a plain document to fetch or one of various other things. Usually, you set that up by directory (e.g. "cgi-bin") or filename extension (e.g. ".cgi"). For Apache, you can use either a ScriptAlias or AddHandler statement in the configuration file for this.
There are lots of ways you can build an XML-RPC server based on the CGI interface to a web server.
The most basic (but not easiest) is not to use any Xmlrpc-c facilities at all. Write your own CGI program which takes an XML document from the web server, interprets it as an XML-RPC call, and returns to the web server an XML response.
The next step up in convenience would be to have your CGI program use Xmlrpc-c's XML encoding and decoding tools to free you from having to know the XML-RPC protocol, and other libxmlrpc facilities to process the data easily. (But if you're writing CGI programs, you probably have other facilities available to do that).
The next step up would be to use an Xmlrpc-c method registry. Instead of writing your own CGI interface code, have your CGI program call xmlrpc_server_cgi_process_call(). To tell this function what methods to execute, you build a method registry and identify it in xmlrpc_server_cgi_process_call()'s arguments. Now you don't have to know the CGI interface.
There is another style in which you don't build a method registry separately, but rather use libxmlrpc_server_cgi facilities to add individual methods to a server instance. I don't recommend this style. It used to be (before Xmlrpc-c 1.03 - June 2005) the only one, so continues to exist for backward compatibility, but I find it to be more complex than the newer xmlrpc_server_cgi() style.
This section describes how to write a CGI program that uses the Xmlrpc-c method registry to implement XML-RPC server functions.
void xmlrpc_server_cgi_process_call(xmlrpc_registry * const registryP);
This function processes an HTTP request which is supposedly an XML-RPC call. It processes it as defined by the method registry identified by registryP.
The function gets all the information about the HTTP request and returns its results using the global variables (e.g. Unix environment variables) of the CGI interface.
#include <xmlrpc-c/base.h> #include <xmlrpc-c/server.h> #include <xmlrpc-c/server_cgi.h> xmlrpc_registry * registryP; xmlrpc_env env; xmlrpc_env_init(&env); registryP = xmlrpc_registry_new(&env); xmlrpc_registry_add_method( &env, registryP, NULL, "sample.add", &sample_add, NULL); xmlrpc_server_cgi_process_call(registryP);
For a complete example, see the program xmlrpc_sample_add_server_cgi.c in the examples directory of the Xmlrpc-c source tree.
Before Xmlrpc-c Version 1.03 (June 2005), the old style is the only one available.
The old facility is the same as the new one, except that the method registry is in a global variable that you don't normally see and you build it using special functions that operate on that global variable.
This old facility is deprecated because it complicates programming and understanding by using global variables and duplicating function of libxmlrpc_server.
void xmlrpc_cgi_init(int flags);
This sets up the internal method registry.
flags must be zero.
This cleans up the method registry created by xmlrpc_cgi_init(). Call it after you're done with it (i.e. after you've called xmlrpc_cgi_process_call()
void xmlrpc_cgi_add_method(char * method_name, xmlrpc_method method, void * user_data);
This adds a method to the internal method registry. It is analogous to xmlrpc_add_method().
void xmlrpc_cgi_add_method_w_doc(char *method_name, xmlrpc_method method, void *user_data, char *signature, char *help);
This adds a method to the internal method registry. It is analogous to xmlrpc_add_method_w_doc().
This is the same thing as xmlrpc_server_cgi_process_call() except that it uses the internal method registry.
xmlrpc_registry * xmlrpc_cgi_registry(void);
This gets you a pointer to the internal method registry. (Which means it isn't really internal, and there's even less reason to like this old facility).
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.