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
41 // by Edd Dumbill (C) 1999,2000
42 // <edd@usefulinc.com>
44 // License is granted to use or modify this software ("XML-RPC for PHP")
45 // for commercial or non-commercial use provided the copyright of the author
46 // is preserved in any distributed or derivative work.
48 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
49 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
50 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
51 // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
52 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
53 // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
54 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
55 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
56 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
57 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
59 // XML RPC Server class
60 // requires: transport.php, xmlrpc_emu.inc
62 // change path as necessary. or set before including this file.
63 if (!$xmlrpc_util_path) {
64 $xmlrpc_util_path = "./utils/";
67 include_once("$xmlrpc_util_path/utils.php");
68 include_once("$xmlrpc_util_path/xmlrpc_emu.inc");
70 /*************************************************************
71 * The Introspection callback is called when an introspection *
72 * request is received by the xmlrpc server. It is a private *
73 * function and should never be called directly. *
75 * It translates useful_inc style introspection data for all *
76 * of the registered methods into xmlrpc-epi style xml, which *
77 * is then returned to the server, parsed, and possibly spit *
79 *************************************************************/
80 function _introspection_cb($userdata)
82 foreach ($userdata as $name => $method) {
83 if ($incr++ > 0) break;
87 if (isset($method[docstring])) {
88 $purpose = "<purpose>$method[docstring]</purpose>";
91 if (is_array($method[signature])) {
92 $sigs_buf = "<signatures>";
93 foreach ($method[signature] as $sig) {
96 foreach ($sig as $param) {
97 $xml = "<value type='$param'/>\n";
107 "<signature><params>$params</params><returns>$returns</returns></signature>\n";
109 $sigs_buf .= "</signatures>";
113 "<methodDescription name='$name'>\n$purpose\n$sigs_buf\n</methodDescription>\n";
116 $xml = "<?xml version='1.0'?>\n\n<introspection version='1.0'>\n<methodList>$method_desc</methodList></introspection>\n";
120 /********************************************************************
121 * xmlrpc_server class. Wrappers around the xmlrpc-epi server APIs. *
122 ********************************************************************/
128 // constructor. creates server and optionally services request.
129 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()
162 global $_xmlrpc_debuginfo;
163 if ($_xmlrpc_debuginfo != "")
164 return "<!-- DEBUG INFO:\n\n" .
165 $_xmlrpc_debuginfo . "\n-->\n";
170 // public. service the xmlrpc request
173 global $HTTP_RAW_POST_DATA;
174 $data = $HTTP_RAW_POST_DATA;
176 trigger_error("empty \$HTTP_RAW_POST_DATA", E_USER_WARNING);
179 $payload = xmlrpc_server_call_method($this->xmlrpc_server, $data, $this->dmap,
180 array('output_type' => "xml", 'version' => "xmlrpc"));
181 Header("Content-type: text/xml\nContent-length: " . strlen($payload));
185 // private. no equivalent in C library (yet)
186 function verifySignature($in, $sig)
188 return "verifySignature not supported";
191 // public. this used to be called by service().
192 // it's no longer necessary, but we keep it around in case
193 // people are calling it directly from applications.
194 function parseRequest($data = "")
196 global $_xh, $HTTP_RAW_POST_DATA;
198 global $xmlrpcerr, $xmlrpcstr, $xmlrpcerrxml, $xmlrpc_defencoding;
201 $data = $HTTP_RAW_POST_DATA;
205 $php_val = xmlrpc_server_call_method($this->xmlrpc_server, $data, $this->dmap,
206 array('output_type' => "php", 'version' => "xmlrpc"));
208 /* check for fault */
209 if (is_array($php_val) && isset($php_val['faultCode'])) {
210 $fc = $php_val['faultCode'];
211 $fs = $php_val['faultString'];
213 $rpc_val = php_to_val($php_val);
215 $response = new xmlrpcresp($rpc_val, $fc, $fs);
220 // public. test routine.
223 global $HTTP_RAW_POST_DATA;
225 // a debugging routine: just echos back the input
226 // packet as a string value
229 $r->xv = new xmlrpcval("'Aha said I: '" . $HTTP_RAW_POST_DATA, "string");
230 print $r->serialize();
235 /**********************************************************************
236 * This is the callback function that is called by C engine for *all* *
237 * php methods. This then calls the user callback funcs which require *
238 * xmlrpcmsg for input and return xmlrpcresp. *
240 * This function converts between native php types which are *
241 * sent/expected by C engine, and the objects which are used *
242 * by user funcs. kind of ugly/slow, but necessary. *
243 **********************************************************************/
244 function xmlrpc_user_func_wrapper_cb($methodname, $params, $method_map)
247 $user_func = $method_map[$methodname]['function'];
250 // create msg from methodname and params.
251 $msg = new xmlrpcmsg($methodname);
252 foreach ($params as $param) {
253 $msg->addParam(php_to_val($param));
257 $rpc_resp = $user_func($msg);
259 // translate user func response into php values.
260 if (is_object($rpc_resp)) {
261 if ($rpc_resp->faultCode()) {
262 return xu_fault_code($rpc_resp->faultCode(), $rpc_resp->faultString());
264 return val_to_php($rpc_resp->value());
266 return xu_fault_code($xmlrpcerr["invalid_return"], $xmlrpcstr["invalid_return"]);
269 return xu_fault_code($xmlrpcerr["unknown_method"], $xmlrpcstr["unknown_method"]);
272 $_xmlrpc_debuginfo = '';
273 function xmlrpc_debugmsg($m)
275 global $_xmlrpc_debuginfo;
276 $_xmlrpc_debuginfo = $_xmlrpc_debuginfo . $m . "\n";