4 xmlrpcs_emu.inc -- xmlrpcs.inc wrapper.
6 08/30/01 - last modified by Dan Libby <dan@libby.com>
8 This code provides API compatibility with Edd Dumbill's php xmlrpc
9 library (http://phpxmlrpc.sourceforge.net/) but uses the xmlrpc-epi
10 engine for the actual xml processing. It is intended to provide a
11 smooth transition path for those who would like to be able to use either
14 To use in your existing application, simply change:
16 include("xmlrpcs.inc");
20 include("xmlrpcs_emu.inc");
23 - This file requires that xmlrpc-epi C extension be installed.
24 See http://xmlrpc-epi.sourceforge.net/
26 - xmlrpc_decode, xmlrpc_encode are present in both the xmlrpc-epi
27 C extension and the usefulinc implementation, and conflict.
28 They have been enhanced and renamed to val_to_php, php_to_val.
30 - the xmlrpc-epi engine uses different fault codes and strings than
31 the xmlrpc.inc. Application fault codes will remain unchanged
32 between implementations, but system codes will likely be
34 See http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php
36 - Certain methods are not implemented and will typically return
42 // by Edd Dumbill (C) 1999,2000
43 // <edd@usefulinc.com>
44 // $Id: xmlrpcs_emu.inc,v 1.2 2004-12-10 02:36:43 rurban Exp $
46 // License is granted to use or modify this software ("XML-RPC for PHP")
47 // for commercial or non-commercial use provided the copyright of the author
48 // is preserved in any distributed or derivative work.
50 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
51 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
52 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
53 // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
54 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
55 // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
56 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
57 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
58 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
59 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 // XML RPC Server class
62 // requires: transport.php, xmlrpc_emu.inc
64 // change path as necessary. or set before including this file.
65 if(!$xmlrpc_util_path) {
66 $xmlrpc_util_path = "./utils/";
69 include_once("$xmlrpc_util_path/utils.php");
70 include_once("$xmlrpc_util_path/xmlrpc_emu.inc");
72 /*************************************************************
73 * The Introspection callback is called when an introspection *
74 * request is received by the xmlrpc server. It is a private *
75 * function and should never be called directly. *
77 * It translates useful_inc style introspection data for all *
78 * of the registered methods into xmlrpc-epi style xml, which *
79 * is then returned to the server, parsed, and possibly spit *
81 *************************************************************/
82 function _introspection_cb($userdata) {
83 foreach($userdata as $name => $method) {
84 if($incr++ > 0) break;
88 if(isset($method[docstring])) {
89 $purpose = "<purpose>$method[docstring]</purpose>";
92 if(is_array($method[signature])) {
93 $sigs_buf = "<signatures>";
94 foreach($method[signature] as $sig) {
97 foreach($sig as $param) {
98 $xml = "<value type='$param'/>\n";
109 "<signature><params>$params</params><returns>$returns</returns></signature>\n";
111 $sigs_buf .= "</signatures>";
115 "<methodDescription name='$name'>\n$purpose\n$sigs_buf\n</methodDescription>\n";
118 $xml = "<?xml version='1.0'?>\n\n<introspection version='1.0'>\n<methodList>$method_desc</methodList></introspection>\n";
122 /********************************************************************
123 * xmlrpc_server class. Wrappers around the xmlrpc-epi server APIs. *
124 ********************************************************************/
125 class xmlrpc_server {
129 // constructor. creates server and optionally services request.
130 function xmlrpc_server($dispMap, $serviceNow=1) {
131 global $HTTP_RAW_POST_DATA;
132 // dispMap is a despatch array of methods
133 // mapped to function names and signatures
135 // doesn't appear in the map then an unknown
136 // method error is generated
137 $this->dmap = $dispMap;
140 // php has no destructor support currently, so we can't call xmlrpc_server_destroy()
141 // at the end like we should. Fortunately, the C code takes care of this at the
142 // end of the request. Feels unclean though.
143 $this->xmlrpc_server = xmlrpc_server_create();
146 foreach($this->dmap as $name => $method) {
147 xmlrpc_server_register_method($this->xmlrpc_server, $name, "xmlrpc_user_func_wrapper_cb");
150 // register a callback in case of introspection queries.
151 xmlrpc_server_register_introspection_callback($this->xmlrpc_server, "_introspection_cb");
153 // possibly go to work handling request
159 // private. not really useful anymore since this is all handled by the xmlrpc-epi stuff.
160 function serializeDebug() {
161 global $_xmlrpc_debuginfo;
162 if ($_xmlrpc_debuginfo!="")
163 return "<!-- DEBUG INFO:\n\n" .
164 $_xmlrpc_debuginfo . "\n-->\n";
169 // public. service the xmlrpc request
171 global $HTTP_RAW_POST_DATA;
172 $data = $HTTP_RAW_POST_DATA;
175 $payload = xmlrpc_server_call_method($this->xmlrpc_server, $data, $this->dmap,
176 array('output_type' => "xml", 'version' => "xmlrpc"));
177 Header("Content-type: text/xml\nContent-length: " . strlen($payload));
181 // private. no equivalent in C library (yet)
182 function verifySignature($in, $sig) {
183 return "verifySignature not supported";
186 // public. this used to be called by service().
187 // it's no longer necessary, but we keep it around in case
188 // people are calling it directly from applications.
189 function parseRequest($data="") {
190 global $_xh,$HTTP_RAW_POST_DATA;
192 global $xmlrpcerr, $xmlrpcstr, $xmlrpcerrxml, $xmlrpc_defencoding;
195 $data = $HTTP_RAW_POST_DATA;
199 $php_val = xmlrpc_server_call_method($this->xmlrpc_server, $data, $this->dmap,
200 array('output_type' => "php", 'version' => "xmlrpc"));
202 /* check for fault */
203 if (is_array($php_val) && isset($php_val['faultCode'])) {
204 $fc = $php_val['faultCode'];
205 $fs = $php_val['faultString'];
207 $rpc_val = php_to_val($php_val);
209 $response = new xmlrpcresp($rpc_val, $fc, $fs);
214 // public. test routine.
215 function echoInput() {
216 global $HTTP_RAW_POST_DATA;
218 // a debugging routine: just echos back the input
219 // packet as a string value
222 $r->xv = new xmlrpcval( "'Aha said I: '" . $HTTP_RAW_POST_DATA, "string");
223 print $r->serialize();
228 /**********************************************************************
229 * This is the callback function that is called by C engine for *all* *
230 * php methods. This then calls the user callback funcs which require *
231 * xmlrpcmsg for input and return xmlrpcresp. *
233 * This function converts between native php types which are *
234 * sent/expected by C engine, and the objects which are used *
235 * by user funcs. kind of ugly/slow, but necessary. *
236 **********************************************************************/
237 function xmlrpc_user_func_wrapper_cb($methodname, $params, $method_map) {
239 $user_func = $method_map[$methodname]['function'];
242 // create msg from methodname and params.
243 $msg = new xmlrpcmsg($methodname);
244 foreach($params as $param) {
245 $msg->addParam(php_to_val($param));
249 $rpc_resp = $user_func($msg);
251 // translate user func response into php values.
252 if (is_object($rpc_resp)) {
253 if ($rpc_resp->faultCode()) {
254 return xu_fault_code($rpc_resp->faultCode(), $rpc_resp->faultString());
256 return val_to_php($rpc_resp->value());
258 return xu_fault_code( $xmlrpcerr["invalid_return"], $xmlrpcstr["invalid_return"]);
261 return xu_fault_code( $xmlrpcerr["unknown_method"], $xmlrpcstr["unknown_method"]);
264 $_xmlrpc_debuginfo='';
265 function xmlrpc_debugmsg($m)
267 global $_xmlrpc_debuginfo;
268 $_xmlrpc_debuginfo=$_xmlrpc_debuginfo . $m . "\n";