Make WordPress Core

source: trunk/wp-includes/class-xmlrpcs.php @ 1608

Last change on this file since 1608 was 601, checked in by saxmatt, 22 years ago

The great renaming.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.5 KB
Line 
1<?php
2// by Edd Dumbill (C) 1999-2001
3// <[email protected]>
4// $Id: class-xmlrpcs.php 601 2003-12-11 00:22:36Z saxmatt $
5
6
7# additional fixes for case of missing xml extension file by Michel Valdrighi <[email protected]>
8
9
10// Copyright (c) 1999,2000,2001 Edd Dumbill.
11// All rights reserved.
12//
13// Redistribution and use in source and binary forms, with or without
14// modification, are permitted provided that the following conditions
15// are met:
16//
17//    * Redistributions of source code must retain the above copyright
18//      notice, this list of conditions and the following disclaimer.
19//
20//    * Redistributions in binary form must reproduce the above
21//      copyright notice, this list of conditions and the following
22//      disclaimer in the documentation and/or other materials provided
23//      with the distribution.
24//
25//    * Neither the name of the "XML-RPC for PHP" nor the names of its
26//      contributors may be used to endorse or promote products derived
27//      from this software without specific prior written permission.
28//
29// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
32// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
33// REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
34// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
35// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
36// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
37// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
38// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
39// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
40// OF THE POSSIBILITY OF SUCH DAMAGE.
41
42// XML RPC Server class
43// requires: class-xmlrpc.php
44
45// listMethods: either a string, or nothing
46$_xmlrpcs_listMethods_sig=array(array($xmlrpcArray, $xmlrpcString), 
47                                                                                                                                array($xmlrpcArray));
48$_xmlrpcs_listMethods_doc='This method lists all the methods that the XML-RPC server knows how to dispatch';
49function _xmlrpcs_listMethods($server, $m) {
50        global $xmlrpcerr, $xmlrpcstr, $_xmlrpcs_dmap;
51        $v=new xmlrpcval();
52        $dmap=$server->dmap;
53        $outAr=array();
54        for(reset($dmap); list($key, $val)=each($dmap); ) {
55                $outAr[]=new xmlrpcval($key, "string");
56        }
57        $dmap=$_xmlrpcs_dmap;
58        for(reset($dmap); list($key, $val)=each($dmap); ) {
59                $outAr[]=new xmlrpcval($key, "string");
60        }
61        $v->addArray($outAr);
62        return new xmlrpcresp($v);
63}
64
65$_xmlrpcs_methodSignature_sig=array(array($xmlrpcArray, $xmlrpcString));
66$_xmlrpcs_methodSignature_doc='Returns an array of known signatures (an array of arrays) for the method name passed. If no signatures are known, returns a none-array (test for type != array to detect missing signature)';
67function _xmlrpcs_methodSignature($server, $m) {
68        global $xmlrpcerr, $xmlrpcstr, $_xmlrpcs_dmap;
69
70        $methName=$m->getParam(0);
71        $methName=$methName->scalarval();
72        if (ereg("^system\.", $methName)) {
73                $dmap=$_xmlrpcs_dmap; $sysCall=1;
74        } else {
75                $dmap=$server->dmap; $sysCall=0;
76        }
77        //      print "<!-- ${methName} -->\n";
78        if (isset($dmap[$methName])) {
79                if ($dmap[$methName]["signature"]) {
80                        $sigs=array();
81                        $thesigs=$dmap[$methName]["signature"];
82                        for($i=0; $i<sizeof($thesigs); $i++) {
83                                $cursig=array();
84                                $inSig=$thesigs[$i];
85                                for($j=0; $j<sizeof($inSig); $j++) {
86                                        $cursig[]=new xmlrpcval($inSig[$j], "string");
87                                }
88                                $sigs[]=new xmlrpcval($cursig, "array");
89                        }
90                        $r=new xmlrpcresp(new xmlrpcval($sigs, "array"));
91                } else {
92                        $r=new xmlrpcresp(new xmlrpcval("undef", "string"));
93                }
94        } else {
95                        $r=new xmlrpcresp(0,
96                                                  $xmlrpcerr["introspect_unknown"],
97                                                  $xmlrpcstr["introspect_unknown"]);
98        }
99        return $r;
100}
101
102$_xmlrpcs_methodHelp_sig=array(array($xmlrpcString, $xmlrpcString));
103$_xmlrpcs_methodHelp_doc='Returns help text if defined for the method passed, otherwise returns an empty string';
104function _xmlrpcs_methodHelp($server, $m) {
105        global $xmlrpcerr, $xmlrpcstr, $_xmlrpcs_dmap;
106
107        $methName=$m->getParam(0);
108        $methName=$methName->scalarval();
109        if (ereg("^system\.", $methName)) {
110                $dmap=$_xmlrpcs_dmap; $sysCall=1;
111        } else {
112                $dmap=$server->dmap; $sysCall=0;
113        }
114        //      print "<!-- ${methName} -->\n";
115        if (isset($dmap[$methName])) {
116                if ($dmap[$methName]["docstring"]) {
117                        $r=new xmlrpcresp(new xmlrpcval($dmap[$methName]["docstring"]),
118                                                                                                "string");
119                } else {
120                        $r=new xmlrpcresp(new xmlrpcval("", "string"));
121                }
122        } else {
123                        $r=new xmlrpcresp(0,
124                                                  $xmlrpcerr["introspect_unknown"],
125                                                  $xmlrpcstr["introspect_unknown"]);
126        }
127        return $r;
128}
129
130$_xmlrpcs_dmap=array(
131                                                                                 "system.listMethods" =>
132                                                                                 array("function" => "_xmlrpcs_listMethods",
133                                                                                                         "signature" => $_xmlrpcs_listMethods_sig,
134                                                                                                         "docstring" => $_xmlrpcs_listMethods_doc),
135                                                                                 "system.methodHelp" =>
136                                                                                 array("function" => "_xmlrpcs_methodHelp",
137                                                                                                         "signature" => $_xmlrpcs_methodHelp_sig,
138                                                                                                         "docstring" => $_xmlrpcs_methodHelp_doc),
139                                                                                 "system.methodSignature" =>
140                                                                                 array("function" => "_xmlrpcs_methodSignature",
141                                                                                                         "signature" => $_xmlrpcs_methodSignature_sig,
142                                                                                                         "docstring" => $_xmlrpcs_methodSignature_doc)
143                                                                                 );
144
145$_xmlrpc_debuginfo="";
146function xmlrpc_debugmsg($m) {
147        global $_xmlrpc_debuginfo;
148        $_xmlrpc_debuginfo=$_xmlrpc_debuginfo . $m . "\n";
149}
150
151class xmlrpc_server {
152  var $dmap=array();
153
154  function xmlrpc_server($dispMap, $serviceNow=1) {
155                global $HTTP_RAW_POST_DATA;
156                // dispMap is a despatch array of methods
157                // mapped to function names and signatures
158                // if a method
159                // doesn't appear in the map then an unknown
160                // method error is generated
161                $this->dmap=$dispMap;
162                if ($serviceNow) {
163                        $this->service();
164                }
165  }
166
167        function serializeDebug() {
168                global $_xmlrpc_debuginfo;
169                if ($_xmlrpc_debuginfo!="") 
170                        return "<!-- DEBUG INFO:\n\n" .
171                                $_xmlrpc_debuginfo . "\n-->\n";
172                else
173                        return "";
174        }
175
176        function service() {
177                $r=$this->parseRequest();
178                $payload="<?xml version=\"1.0\"?>\n" . 
179                        $this->serializeDebug() .
180                        $r->serialize();
181                Header("Content-type: text/xml\r\nContent-length: " . 
182                                         strlen(trim($payload)));
183                print trim($payload);
184        }
185
186        function verifySignature($in, $sig) {
187                for($i=0; $i<sizeof($sig); $i++) {
188                        // check each possible signature in turn
189                        $cursig=$sig[$i];
190                        if (sizeof($cursig)==$in->getNumParams()+1) {
191                                $itsOK=1;
192                                for($n=0; $n<$in->getNumParams(); $n++) {
193                                        $p=$in->getParam($n);
194                                        // print "<!-- $p -->\n";
195                                        if ($p->kindOf() == "scalar") {
196                                                $pt=$p->scalartyp();
197                                        } else {
198                                                $pt=$p->kindOf();
199                                        }
200                                        // $n+1 as first type of sig is return type
201                                        if ($pt != $cursig[$n+1]) {
202                                                $itsOK=0;
203                                                $pno=$n+1; $wanted=$cursig[$n+1]; $got=$pt;
204                                                break;
205                                        }
206                                }
207                        if ($itsOK) 
208                                return array(1);
209                        }
210                }
211                return array(0, "Wanted ${wanted}, got ${got} at param ${pno})");
212        }
213
214  function parseRequest($data="") {
215        global $_xh,$HTTP_RAW_POST_DATA;
216        global $xmlrpcerr, $xmlrpcstr, $xmlrpcerrxml, $xmlrpc_defencoding,
217                $_xmlrpcs_dmap;
218
219       
220
221        if ($data=="") {
222          $data=$HTTP_RAW_POST_DATA;
223        }
224        $parser = xml_parser_create($xmlrpc_defencoding);
225
226        $_xh[$parser]=array();
227        $_xh[$parser]['st']="";
228        $_xh[$parser]['cm']=0; 
229        $_xh[$parser]['isf']=0; 
230        $_xh[$parser]['params']=array();
231        $_xh[$parser]['method']="";
232
233        // decompose incoming XML into request structure
234
235        xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true);
236        xml_set_element_handler($parser, "xmlrpc_se", "xmlrpc_ee");
237        xml_set_character_data_handler($parser, "xmlrpc_cd");
238        xml_set_default_handler($parser, "xmlrpc_dh");
239        if (!xml_parse($parser, $data, 1)) {
240          // return XML error as a faultCode
241          $r=new xmlrpcresp(0,
242                                                $xmlrpcerrxml+xml_get_error_code($parser),
243                                                sprintf("XML error: %s at line %d",
244                                        xml_error_string(xml_get_error_code($parser)),
245                                  xml_get_current_line_number($parser)));
246          xml_parser_free($parser);
247        } else {
248          xml_parser_free($parser);
249          $m=new xmlrpcmsg($_xh[$parser]['method']);
250          // now add parameters in
251          $plist="";
252          for($i=0; $i<sizeof($_xh[$parser]['params']); $i++) {
253                        //print "<!-- " . $_xh[$parser]['params'][$i]. "-->\n";
254                        $plist.="$i - " .  $_xh[$parser]['params'][$i]. " \n";
255                        eval('$m->addParam(' . $_xh[$parser]['params'][$i]. ");");
256          }
257                // uncomment this to really see what the server's getting!
258                // xmlrpc_debugmsg($plist);
259          // now to deal with the method
260                $methName=$_xh[$parser]['method'];
261                if (ereg("^system\.", $methName)) {
262                        $dmap=$_xmlrpcs_dmap; $sysCall=1;
263                } else {
264                        $dmap=$this->dmap; $sysCall=0;
265                }
266          if (isset($dmap[$methName]['function'])) {
267                        // dispatch if exists
268                        if (isset($dmap[$methName]['signature'])) {
269                                $sr=$this->verifySignature($m, 
270                                                                                                                                        $dmap[$methName]['signature'] );
271                        }
272                        if ( (!isset($dmap[$methName]['signature']))
273                                         || $sr[0]) {
274                                // if no signature or correct signature
275                                if ($sysCall) { 
276                                        eval('$r=' . $dmap[$methName]['function'] . 
277                                                         '($this, $m);');
278                                } else {
279                                        eval('$r=' . $dmap[$methName]['function'] . 
280                                                         '($m);');
281                                }
282                        } else {
283                                $r=new xmlrpcresp(0,
284                                                  $xmlrpcerr["incorrect_params"],
285                                                  $xmlrpcstr["incorrect_params"].": ". $sr[1]);
286                        }
287          } else {
288                // else prepare error response
289                $r=new xmlrpcresp(0,
290                                                  $xmlrpcerr["unknown_method"],
291                                                  $xmlrpcstr["unknown_method"]);
292          }
293        }
294        return $r;
295  }
296
297  function echoInput() {
298        global $HTTP_RAW_POST_DATA;
299
300        // a debugging routine: just echos back the input
301        // packet as a string value
302
303        $r=new xmlrpcresp;
304        $r->xv=new xmlrpcval( "'Aha said I: '" . $HTTP_RAW_POST_DATA, "string");
305        print $r->serialize();
306  }
307}
308
309?>
Note: See TracBrowser for help on using the repository browser.