44 'specUrl' =>
new xmlrpcval(
'http://www.xmlrpc.com/spec',
'string'),
49 'system.multicall' =>
new xmlrpcval(array(
50 'specUrl' =>
new xmlrpcval(
'http://www.xmlrpc.com/discuss/msgReader$1208',
'string'),
55 'specUrl' =>
new xmlrpcval(
'http://phpxmlrpc.sourceforge.net/doc-2/ch10.html',
'string'),
62 $_xmlrpcs_getCapabilities_doc=
'This method lists all the capabilites that the XML-RPC server has: the (more or less standard) extensions to the xmlrpc spec that it adheres to';
66 $outAr =
$GLOBALS[
'xmlrpcs_capabilities'];
68 if (
$GLOBALS[
'xmlrpc_null_extension']) {
70 'specUrl' =>
new xmlrpcval(
'http://www.ontosys.com/xml-rpc/extensions.php',
'string'),
86 foreach($server->dmap
as $key => $val)
90 if($server->allow_system_funcs)
92 foreach(
$GLOBALS[
'_xmlrpcs_dmap']
as $key => $val)
101 $_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)';
108 $methName=$m->getParam(0);
109 $methName=$methName->scalarval();
115 if(strpos($methName,
"system.") === 0)
117 $dmap=
$GLOBALS[
'_xmlrpcs_dmap']; $sysCall=1;
121 $dmap=$server->dmap; $sysCall=0;
123 if(isset($dmap[$methName]))
125 if(isset($dmap[$methName][
'signature']))
128 foreach($dmap[$methName][
'signature']
as $inSig)
131 foreach($inSig
as $sig)
161 $methName=$m->getParam(0);
162 $methName=$methName->scalarval();
168 if(strpos($methName,
"system.") === 0)
170 $dmap=
$GLOBALS[
'_xmlrpcs_dmap']; $sysCall=1;
174 $dmap=$server->dmap; $sysCall=0;
176 if(isset($dmap[$methName]))
178 if(isset($dmap[$methName][
'docstring']))
195 $_xmlrpcs_multicall_doc =
'Boxcar multiple RPC calls in one request. See http://www.xmlrpc.com/discuss/msgReader$1208 for details';
196 $_xmlrpcs_multicall_sdoc = array(array(
'list of response structs, where each struct has the usual members',
'list of calls, with each call being represented as a struct, with members "methodname" and "params"'));
201 $str =
$GLOBALS[
'xmlrpcstr'][
"multicall_${err}"];
202 $code =
$GLOBALS[
'xmlrpcerr'][
"multicall_${err}"];
206 $code = $err->faultCode();
207 $str = $err->faultString();
210 $struct[
'faultCode'] =
new xmlrpcval($code,
'int');
211 $struct[
'faultString'] =
new xmlrpcval($str,
'string');
217 if($call->kindOf() !=
'struct')
221 $methName = @$call->structmem(
'methodName');
226 if($methName->kindOf() !=
'scalar' || $methName->scalartyp() !=
'string')
230 if($methName->scalarval() ==
'system.multicall')
235 $params = @$call->structmem(
'params');
240 if($params->kindOf() !=
'array')
244 $numParams = $params->arraysize();
246 $msg =
new xmlrpcmsg($methName->scalarval());
247 for($i = 0; $i < $numParams; $i++)
249 if(!$msg->addParam($params->arraymem($i)))
253 $GLOBALS[
'xmlrpcerr'][
'incorrect_params'],
254 $GLOBALS[
'xmlrpcstr'][
'incorrect_params'] .
": probable xml error in param " . $i));
258 $result = $server->execute($msg);
260 if($result->faultCode() != 0)
265 return new xmlrpcval(array($result->value()),
'array');
274 if(!array_key_exists(
'methodName', $call))
278 if (!is_string($call[
'methodName']))
282 if($call[
'methodName'] ==
'system.multicall')
286 if(!array_key_exists(
'params', $call))
290 if(!is_array($call[
'params']))
297 $numParams = count($call[
'params']);
299 foreach($call[
'params']
as $val)
302 $result = $server->execute($call[
'methodName'], $call[
'params'], $pt);
304 if($result->faultCode() != 0)
309 return new xmlrpcval(array($result->value()),
'array');
318 $calls = $m->getParam(0);
319 $numCalls = $calls->arraysize();
320 for($i = 0; $i < $numCalls; $i++)
322 $call = $calls->arraymem($i);
329 for($i = 0; $i < $numCalls; $i++)
339 'system.listMethods' => array(
340 'function' =>
'_xmlrpcs_listMethods',
344 'system.methodHelp' => array(
345 'function' =>
'_xmlrpcs_methodHelp',
349 'system.methodSignature' => array(
350 'function' =>
'_xmlrpcs_methodSignature',
354 'system.multicall' => array(
355 'function' =>
'_xmlrpcs_multicall',
359 'system.getCapabilities' => array(
360 'function' =>
'_xmlrpcs_getCapabilities',
380 if (error_reporting() == 0)
386 $GLOBALS[
'_xmlrpcs_occurred_errors'] =
$GLOBALS[
'_xmlrpcs_occurred_errors'] . $errstring .
"\n";
390 if(
$GLOBALS[
'_xmlrpcs_prev_ehandler'] ==
'')
394 if(ini_get(
'log_errors') && (intval(ini_get(
'error_reporting')) & $errcode))
396 error_log($errstring);
402 if(
$GLOBALS[
'_xmlrpcs_prev_ehandler'] !=
'_xmlrpcs_errorHandler')
405 if(is_array(
$GLOBALS[
'_xmlrpcs_prev_ehandler']))
408 call_user_func_array(
$GLOBALS[
'_xmlrpcs_prev_ehandler'], array($errcode, $errstring, $filename, $lineno, $context));
412 $GLOBALS[
'_xmlrpcs_prev_ehandler']($errcode, $errstring, $filename, $lineno, $context);
430 $GLOBALS[
'_xmlrpc_debuginfo'] .= $m .
"\n";
482 if(function_exists(
'gzinflate'))
484 $this->accepted_compression = array();
485 $this->compress_response =
true;
489 $this->accepted_charset_encodings = array(
'UTF-8',
'ISO-8859-1',
'US-ASCII');
502 $this->dmap = $dispMap;
542 if ($this->debug_info !=
'')
544 $out .=
"<!-- SERVER DEBUG INFO (BASE64 ENCODED):\n".base64_encode($this->debug_info).
"\n-->\n";
546 if(
$GLOBALS[
'_xmlrpc_debuginfo']!=
'')
563 function service($data=
null, $return_payload=
false)
571 $data = file_get_contents(
'php://input');
575 $data = isset(
$GLOBALS[
'HTTP_RAW_POST_DATA']) ?
$GLOBALS[
'HTTP_RAW_POST_DATA'] :
'';
581 $this->debug_info =
'';
586 $this->
debugmsg(
"+++GOT+++\n" . $data .
"\n+++END+++");
596 $r->raw_data = $raw_data;
598 if($this->debug > 2 &&
$GLOBALS[
'_xmlrpcs_occurred_errors'])
600 $this->
debugmsg(
"+++PROCESSING ERRORS AND WARNINGS+++\n" .
601 $GLOBALS[
'_xmlrpcs_occurred_errors'] .
"+++END+++");
612 if (
empty($r->payload))
614 $r->serialize($resp_charset);
616 $payload = $payload . $r->payload;
627 header(
'Content-Type: '.$r->content_type);
630 header(
"Vary: Accept-Charset");
635 $php_no_self_compress = ini_get(
'zlib.output_compression') ==
'' && (ini_get(
'output_handler') !=
'ob_gzhandler');
636 if($this->compress_response && function_exists(
'gzencode') && $resp_encoding !=
''
637 && $php_no_self_compress)
639 if(strpos($resp_encoding,
'gzip') !==
false)
641 $payload = gzencode($payload);
642 header(
"Content-Encoding: gzip");
643 header(
"Vary: Accept-Encoding");
645 elseif (strpos($resp_encoding,
'deflate') !==
false)
647 $payload = gzcompress($payload);
648 header(
"Content-Encoding: deflate");
649 header(
"Vary: Accept-Encoding");
655 if($php_no_self_compress)
657 header(
'Content-Length: ' . (
int)strlen($payload));
662 error_log(
'XML-RPC: xmlrpc_server::service: http headers already sent before response is fully generated. Check for php warning or error messages');
681 $this->dmap[$methodname] = array(
682 'function' => $function,
687 $this->dmap[$methodname][
'signature'] = $sig;
702 $numParams = $in->getNumParams();
706 $numParams = count($in);
708 foreach($sig
as $cursig)
710 if(count($cursig)==$numParams+1)
713 for($n=0; $n<$numParams; $n++)
717 $p=$in->getParam($n);
718 if($p->kindOf() ==
'scalar')
729 $pt= $in[$n] ==
'i4' ?
'int' : $in[$n];
733 if($pt != $cursig[$n+1] && $cursig[$n+1] !=
$GLOBALS[
'xmlrpcValue'])
737 $wanted=$cursig[$n+1];
750 return array(0,
"Wanted ${wanted}, got ${got} at param ${pno}");
754 return array(0,
"No method signature matches number of parameters");
768 $_SERVER =
$GLOBALS[
'HTTP_SERVER_VARS'];
773 if(function_exists(
'getallheaders'))
776 foreach(getallheaders()
as $name => $val)
778 $this->
debugmsg(
"HEADER: $name: $val");
784 if(isset($_SERVER[
'HTTP_CONTENT_ENCODING']))
786 $content_encoding = str_replace(
'x-',
'', $_SERVER[
'HTTP_CONTENT_ENCODING']);
790 $content_encoding =
'';
794 if($content_encoding !=
'' && strlen($data))
796 if($content_encoding ==
'deflate' || $content_encoding ==
'gzip')
799 if(function_exists(
'gzinflate') && in_array($content_encoding, $this->accepted_compression))
801 if($content_encoding ==
'deflate' && $degzdata = @gzuncompress($data))
806 $this->
debugmsg(
"\n+++INFLATED REQUEST+++[".strlen($data).
" chars]+++\n" . $data .
"\n+++END+++");
809 elseif($content_encoding ==
'gzip' && $degzdata = @gzinflate(substr($data, 10)))
813 $this->
debugmsg(
"+++INFLATED REQUEST+++[".strlen($data).
" chars]+++\n" . $data .
"\n+++END+++");
832 if ($this->response_charset_encoding ==
'auto')
835 if (isset($_SERVER[
'HTTP_ACCEPT_CHARSET']))
840 $client_accepted_charsets = explode(
',', strtoupper($_SERVER[
'HTTP_ACCEPT_CHARSET']));
842 $known_charsets = array(
$GLOBALS[
'xmlrpc_internalencoding'],
'UTF-8',
'ISO-8859-1',
'US-ASCII');
843 foreach ($known_charsets
as $charset)
845 foreach ($client_accepted_charsets
as $accepted)
846 if (strpos($accepted, $charset) === 0)
848 $resp_encoding = $charset;
861 if (isset($_SERVER[
'HTTP_ACCEPT_ENCODING']))
863 $resp_compression = $_SERVER[
'HTTP_ACCEPT_ENCODING'];
867 $resp_compression =
'';
872 $req_encoding =
guess_encoding(isset($_SERVER[
'CONTENT_TYPE']) ? $_SERVER[
'CONTENT_TYPE'] :
'',
901 $GLOBALS[
'_xh'][
'valuestack'] = array();
910 if ($req_encoding !=
'')
912 if (!in_array($req_encoding, array(
'UTF-8',
'ISO-8859-1',
'US-ASCII')))
917 error_log(
'XML-RPC: xmlrpc_server::parseRequest: invalid charset encoding of received request: '.$req_encoding);
918 $req_encoding =
$GLOBALS[
'xmlrpc_defencoding'];
923 $parser = xml_parser_create($req_encoding);
927 $parser = xml_parser_create();
930 xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING,
true);
937 if (!in_array(
$GLOBALS[
'xmlrpc_internalencoding'], array(
'UTF-8',
'ISO-8859-1',
'US-ASCII')))
939 xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING,
'UTF-8');
943 xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING,
$GLOBALS[
'xmlrpc_internalencoding']);
947 xml_set_element_handler($parser,
'xmlrpc_se',
'xmlrpc_ee_fast');
949 xml_set_element_handler($parser,
'xmlrpc_se',
'xmlrpc_ee');
950 xml_set_character_data_handler($parser,
'xmlrpc_cd');
951 xml_set_default_handler($parser,
'xmlrpc_dh');
952 if(!xml_parse($parser, $data, 1))
956 $GLOBALS[
'xmlrpcerrxml']+xml_get_error_code($parser),
957 sprintf(
'XML error: %s at line %d, column %d',
958 xml_error_string(xml_get_error_code($parser)),
959 xml_get_current_line_number($parser), xml_get_current_column_number($parser)));
960 xml_parser_free($parser);
964 xml_parser_free($parser);
966 $GLOBALS[
'xmlrpcerr'][
'invalid_request'],
967 $GLOBALS[
'xmlrpcstr'][
'invalid_request'] .
' ' .
$GLOBALS[
'_xh'][
'isf_reason']);
971 xml_parser_free($parser);
976 $this->
debugmsg(
"\n+++PARSED+++\n".var_export(
$GLOBALS[
'_xh'][
'params'],
true).
"\n+++END+++");
985 for($i=0; $i<count(
$GLOBALS[
'_xh'][
'params']); $i++)
987 $m->addParam(
$GLOBALS[
'_xh'][
'params'][$i]);
992 $this->
debugmsg(
"\n+++PARSED+++\n".var_export($m,
true).
"\n+++END+++");
1008 function execute($m, $params=
null, $paramtypes=
null)
1012 $methName = $m->method();
1018 $sysCall = $this->allow_system_funcs && (strpos($methName,
"system.") === 0);
1021 if(!isset(
$dmap[$methName][
'function']))
1025 $GLOBALS[
'xmlrpcerr'][
'unknown_method'],
1026 $GLOBALS[
'xmlrpcstr'][
'unknown_method']);
1030 if(isset(
$dmap[$methName][
'signature']))
1032 $sig =
$dmap[$methName][
'signature'];
1046 $GLOBALS[
'xmlrpcerr'][
'incorrect_params'],
1047 $GLOBALS[
'xmlrpcstr'][
'incorrect_params'] .
": ${errstr}"
1052 $func =
$dmap[$methName][
'function'];
1054 if(is_string($func) && strpos($func,
'::'))
1056 $func = explode(
'::', $func);
1059 if(!is_callable($func))
1061 error_log(
"XML-RPC: xmlrpc_server::execute: function $func registered as method handler is not callable");
1064 $GLOBALS[
'xmlrpcerr'][
'server_error'],
1065 $GLOBALS[
'xmlrpcstr'][
'server_error'] .
": no function matches method"
1071 if($this->debug > 2)
1073 $GLOBALS[
'_xmlrpcs_prev_ehandler'] = set_error_handler(
'_xmlrpcs_errorHandler');
1079 $r = call_user_func($func, $this, $m);
1083 $r = call_user_func($func, $m);
1085 if (!is_a($r,
'xmlrpcresp'))
1087 error_log(
"XML-RPC: xmlrpc_server::execute: function $func registered as method handler does not return an xmlrpcresp object");
1088 if (is_a($r,
'xmlrpcval'))
1096 $GLOBALS[
'xmlrpcerr'][
'server_error'],
1097 $GLOBALS[
'xmlrpcstr'][
'server_error'] .
": function does not return xmlrpcresp object"
1107 array_unshift($params, $this);
1108 $r = call_user_func_array($func, $params);
1115 $r = call_user_func_array($func, array($methName, $params, $this->user_data));
1118 if (is_array($r) && array_key_exists(
'faultCode', $r) && array_key_exists(
'faultString', $r))
1120 $r =
new xmlrpcresp(0, (integer)$r[
'faultCode'], (
string)$r[
'faultString']);
1131 $r = call_user_func_array($func, $params);
1135 if (!is_a($r,
'xmlrpcresp'))
1142 if($this->debug > 2)
1146 if(
$GLOBALS[
'_xmlrpcs_prev_ehandler'])
1148 set_error_handler(
$GLOBALS[
'_xmlrpcs_prev_ehandler']);
1152 restore_error_handler();
1165 $this->debug_info .= $string.
"\n";
1173 if ($charset_encoding !=
'')
1175 return "<?xml version=\"1.0\" encoding=\"$charset_encoding\"?" .
">\n";
1179 return "<?xml version=\"1.0\"?" .
">\n";
1190 print $r->serialize();