source: sipes/cord/includes/xmlrpcs.inc @ 4b26eb0

stableversion-3.0
Last change on this file since 4b26eb0 was 6627152, checked in by José Gregorio Puentes <jpuentes@…>, 8 años ago

se actualizo el cord

  • Propiedad mode establecida a 100755
File size: 9.8 KB
Línea 
1<?php
2
3/**
4 * The main entry point for XML-RPC requests.
5 *
6 * @param $callbacks
7 *   Array of external XML-RPC method names with the callbacks they map to.
8 */
9function xmlrpc_server($callbacks) {
10  $xmlrpc_server = new stdClass();
11  // Define built-in XML-RPC method names
12  $defaults = array(
13      'system.multicall' => 'xmlrpc_server_multicall',
14    array(
15      'system.methodSignature',
16      'xmlrpc_server_method_signature',
17      array('array', 'string'),
18      'Returns an array describing the return type and required parameters of a method.'
19    ),
20    array(
21      'system.getCapabilities',
22      'xmlrpc_server_get_capabilities',
23      array('struct'),
24      'Returns a struct describing the XML-RPC specifications supported by this server.'
25    ),
26    array(
27      'system.listMethods',
28      'xmlrpc_server_list_methods',
29      array('array'),
30      'Returns an array of available methods on this server.'),
31    array(
32      'system.methodHelp',
33      'xmlrpc_server_method_help',
34      array('string', 'string'),
35      'Returns a documentation string for the specified method.')
36  );
37  // We build an array of all method names by combining the built-ins
38  // with those defined by modules implementing the _xmlrpc hook.
39  // Built-in methods are overridable.
40  foreach (array_merge($defaults, (array)$callbacks) as $key => $callback) {
41    // we could check for is_array($callback)
42    if (is_int($key)) {
43      $method = $callback[0];
44      $xmlrpc_server->callbacks[$method] = $callback[1];
45      $xmlrpc_server->signatures[$method] = $callback[2];
46      $xmlrpc_server->help[$method] = $callback[3];
47    }
48    else {
49      $xmlrpc_server->callbacks[$key] = $callback;
50      $xmlrpc_server->signatures[$key] = '';
51      $xmlrpc_server->help[$key] = '';
52    }
53  }
54
55  $data = file_get_contents('php://input');
56  if (!$data) {
57    die('XML-RPC server accepts POST requests only.');
58  }
59  $xmlrpc_server->message = xmlrpc_message($data);
60  if (!xmlrpc_message_parse($xmlrpc_server->message)) {
61    xmlrpc_server_error(-32700, t('Parse error. Request not well formed.'));
62  }
63  if ($xmlrpc_server->message->messagetype != 'methodCall') {
64    xmlrpc_server_error(-32600, t('Server error. Invalid XML-RPC. Request must be a methodCall.'));
65  }
66  if (!isset($xmlrpc_server->message->params)) {
67    $xmlrpc_server->message->params = array();
68  }
69  xmlrpc_server_set($xmlrpc_server);
70  $result = xmlrpc_server_call($xmlrpc_server, $xmlrpc_server->message->methodname, $xmlrpc_server->message->params);
71
72  if (is_object($result) && !empty($result->is_error)) {
73    xmlrpc_server_error($result);
74  }
75  // Encode the result
76  $r = xmlrpc_value($result);
77  // Create the XML
78  $xml = '
79<methodResponse>
80  <params>
81  <param>
82    <value>'.
83    xmlrpc_value_get_xml($r)
84    .'</value>
85  </param>
86  </params>
87</methodResponse>
88
89';
90  // Send it
91  xmlrpc_server_output($xml);
92}
93
94/**
95 * Throw an XML-RPC error.
96 *
97 * @param $error
98 *   an error object OR integer error code
99 * @param $message
100 *   description of error, used only if integer error code was passed
101 */
102function xmlrpc_server_error($error, $message = FALSE) {
103  if ($message && !is_object($error)) {
104    $error = xmlrpc_error($error, $message);
105  }
106  xmlrpc_server_output(xmlrpc_error_get_xml($error));
107}
108
109function xmlrpc_server_output($xml) {
110  $xml = '<?xml version="1.0"?>'."\n". $xml;
111  header('Connection: close');
112  header('Content-Length: '. strlen($xml));
113  header('Content-Type: text/xml');
114  header('Date: '. date('r'));
115  echo $xml;
116  exit;
117}
118
119/**
120 * Store a copy of the request temporarily.
121 *
122 * @param $xmlrpc_server
123 *   Request object created by xmlrpc_server().
124 */
125function xmlrpc_server_set($xmlrpc_server = NULL) {
126  static $server;
127  if (!isset($server)) {
128    $server = $xmlrpc_server;
129  }
130  return $server;
131}
132
133// Retrieve the stored request.
134function xmlrpc_server_get() {
135  return xmlrpc_server_set();
136}
137
138/**
139 * Dispatch the request and any parameters to the appropriate handler.
140 *
141 * @param $xmlrpc_server
142 * @param $methodname
143 *   The external XML-RPC method name, e.g. 'system.methodHelp'
144 * @param $args
145 *   Array containing any parameters that were sent along with the request.
146 */
147function xmlrpc_server_call($xmlrpc_server, $methodname, $args) {
148  // Make sure parameters are in an array
149  if ($args && !is_array($args)) {
150    $args = array($args);
151  }
152  // Has this method been mapped to a Drupal function by us or by modules?
153  if (!isset($xmlrpc_server->callbacks[$methodname])) {
154    return xmlrpc_error(-32601, t('Server error. Requested method @methodname not specified.', array("@methodname" => $xmlrpc_server->message->methodname)));
155  }
156  $method = $xmlrpc_server->callbacks[$methodname];
157  $signature = $xmlrpc_server->signatures[$methodname];
158
159  // If the method has a signature, validate the request against the signature
160  if (is_array($signature)) {
161    $ok = TRUE;
162    $return_type = array_shift($signature);
163    // Check the number of arguments
164    if (count($args) != count($signature)) {
165      return xmlrpc_error(-32602, t('Server error. Wrong number of method parameters.'));
166    }
167    // Check the argument types
168    foreach ($signature as $key => $type) {
169      $arg = $args[$key];
170      switch ($type) {
171        case 'int':
172        case 'i4':
173          if (is_array($arg) || !is_int($arg)) {
174            $ok = FALSE;
175          }
176          break;
177        case 'base64':
178        case 'string':
179          if (!is_string($arg)) {
180            $ok = FALSE;
181          }
182          break;
183        case 'boolean':
184          if ($arg !== FALSE && $arg !== TRUE) {
185            $ok = FALSE;
186          }
187          break;
188        case 'float':
189        case 'double':
190          if (!is_float($arg)) {
191            $ok = FALSE;
192          }
193          break;
194        case 'date':
195        case 'dateTime.iso8601':
196          if (!$arg->is_date) {
197            $ok = FALSE;
198          }
199          break;
200      }
201      if (!$ok) {
202        return xmlrpc_error(-32602, t('Server error. Invalid method parameters.'));
203      }
204    }
205  }
206
207  if (!function_exists($method)) {
208    return xmlrpc_error(-32601, t('Server error. Requested function @method does not exist.', array("@method" => $method)));
209  }
210  // Call the mapped function
211  return call_user_func_array($method, $args);
212}
213
214function xmlrpc_server_multicall($methodcalls) {
215  // See http://www.xmlrpc.com/discuss/msgReader$1208
216  // To avoid multicall expansion attacks, limit the number of duplicate method
217  // calls allowed with a default of 1. Set to -1 for unlimited.
218  $duplicate_method_limit = variable_get('xmlrpc_multicall_duplicate_method_limit', 1);
219  $method_count = array();
220  $return = array();
221  $xmlrpc_server = xmlrpc_server_get();
222  foreach ($methodcalls as $call) {
223    $ok = TRUE;
224    if (!isset($call['methodName']) || !isset($call['params'])) {
225      $result = xmlrpc_error(3, t('Invalid syntax for system.multicall.'));
226      $ok = FALSE;
227    }
228    $method = $call['methodName'];
229    $method_count[$method] = isset($method_count[$method]) ? $method_count[$method] + 1 : 1;
230    $params = $call['params'];
231    if ($method == 'system.multicall') {
232      $result = xmlrpc_error(-32600, t('Recursive calls to system.multicall are forbidden.'));
233    }
234    elseif ($duplicate_method_limit > 0 && $method_count[$method] > $duplicate_method_limit) {
235      $result = xmlrpc_error(-156579, t('Too many duplicate method calls in system.multicall.'));
236    }
237    elseif ($ok) {
238      $result = xmlrpc_server_call($xmlrpc_server, $method, $params);
239    }
240    if (is_object($result) && !empty($result->is_error)) {
241      $return[] = array(
242        'faultCode' => $result->code,
243        'faultString' => $result->message
244      );
245    }
246    else {
247      $return[] = $result;
248    }
249  }
250  return $return;
251}
252
253
254/**
255 * XML-RPC method system.listMethods maps to this function.
256 */
257function xmlrpc_server_list_methods() {
258  $xmlrpc_server = xmlrpc_server_get();
259  return array_keys($xmlrpc_server->callbacks);
260}
261
262/**
263 * XML-RPC method system.getCapabilities maps to this function.
264 * See http://groups.yahoo.com/group/xml-rpc/message/2897
265 */
266function xmlrpc_server_get_capabilities() {
267  return array(
268    'xmlrpc' => array(
269      'specUrl' => 'http://www.xmlrpc.com/spec',
270      'specVersion' => 1
271    ),
272    'faults_interop' => array(
273      'specUrl' => 'http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php',
274      'specVersion' => 20010516
275    ),
276    'system.multicall' => array(
277      'specUrl' => 'http://www.xmlrpc.com/discuss/msgReader$1208',
278      'specVersion' => 1
279    ),
280    'introspection' => array(
281    'specUrl' => 'http://scripts.incutio.com/xmlrpc/introspection.html',
282    'specVersion' => 1
283    )
284  );
285}
286
287/**
288 * XML-RPC method system.methodSignature maps to this function.
289 *
290 * @param $methodname
291 *   Name of method for which we return a method signature.
292 * @return array
293 *   An array of types representing the method signature of the
294 *   function that the methodname maps to. The methodSignature of
295 *   this function is 'array', 'string' because it takes an array
296 *   and returns a string.
297 */
298function xmlrpc_server_method_signature($methodname) {
299  $xmlrpc_server = xmlrpc_server_get();
300  if (!isset($xmlrpc_server->callbacks[$methodname])) {
301    return xmlrpc_error(-32601, t('Server error. Requested method @methodname not specified.', array("@methodname" => $methodname)));
302  }
303  if (!is_array($xmlrpc_server->signatures[$methodname])) {
304    return xmlrpc_error(-32601, t('Server error. Requested method @methodname signature not specified.', array("@methodname" => $methodname)));
305  }
306  // We array of types
307  $return = array();
308  foreach ($xmlrpc_server->signatures[$methodname] as $type) {
309    $return[] = $type;
310  }
311  return $return;
312}
313
314/**
315 * XML-RPC method system.methodHelp maps to this function.
316 *
317 * @param $method
318 *   Name of method for which we return a help string.
319 */
320function xmlrpc_server_method_help($method) {
321  $xmlrpc_server = xmlrpc_server_get();
322  return $xmlrpc_server->help[$method];
323}
Nota: Vea TracBrowser para ayuda de uso del navegador del repositorio.