📄 xmlrpcs.inc.svn-base
字号:
// check if request body has been compressed and decompress it if($content_encoding != '' && strlen($data)) { if($content_encoding == 'deflate' || $content_encoding == 'gzip') { // if decoding works, use it. else assume data wasn't gzencoded if(function_exists('gzinflate') && in_array($content_encoding, $this->accepted_compression)) { if($content_encoding == 'deflate' && $degzdata = @gzuncompress($data)) { $data = $degzdata; if($this->debug > 1) { $this->debugmsg("\n+++INFLATED REQUEST+++[".strlen($data)." chars]+++\n" . $data . "\n+++END+++"); } } elseif($content_encoding == 'gzip' && $degzdata = @gzinflate(substr($data, 10))) { $data = $degzdata; if($this->debug > 1) $this->debugmsg("+++INFLATED REQUEST+++[".strlen($data)." chars]+++\n" . $data . "\n+++END+++"); } else { $r =& new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['server_decompress_fail'], $GLOBALS['xmlrpcstr']['server_decompress_fail']); return $r; } } else { //error_log('The server sent deflated data. Your php install must have the Zlib extension compiled in to support this.'); $r =& new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['server_cannot_decompress'], $GLOBALS['xmlrpcstr']['server_cannot_decompress']); return $r; } } } // check if client specified accepted charsets, and if we know how to fulfill // the request if ($this->response_charset_encoding == 'auto') { $resp_encoding = ''; if (isset($_SERVER['HTTP_ACCEPT_CHARSET'])) { // here we should check if we can match the client-requested encoding // with the encodings we know we can generate. /// @todo we should parse q=0.x preferences instead of getting first charset specified... $client_accepted_charsets = explode(',', strtoupper($_SERVER['HTTP_ACCEPT_CHARSET'])); // Give preference to internal encoding $known_charsets = array($this->internal_encoding, 'UTF-8', 'ISO-8859-1', 'US-ASCII'); foreach ($known_charsets as $charset) { foreach ($client_accepted_charsets as $accepted) if (strpos($accepted, $charset) === 0) { $resp_encoding = $charset; break; } if ($resp_encoding) break; } } } else { $resp_encoding = $this->response_charset_encoding; } if (isset($_SERVER['HTTP_ACCEPT_ENCODING'])) { $resp_compression = $_SERVER['HTTP_ACCEPT_ENCODING']; } else { $resp_compression = ''; } // 'guestimate' request encoding /// @todo check if mbstring is enabled and automagic input conversion is on: it might mingle with this check??? $req_encoding = guess_encoding(isset($_SERVER['CONTENT_TYPE']) ? $_SERVER['CONTENT_TYPE'] : '', $data); return null; } /** * Parse an xml chunk containing an xmlrpc request and execute the corresponding * php function registered with the server * @param string $data the xml request * @param string $req_encoding (optional) the charset encoding of the xml request * @return xmlrpcresp * @access private */ function parseRequest($data, $req_encoding='') { // 2005/05/07 commented and moved into caller function code //if($data=='') //{ // $data=$GLOBALS['HTTP_RAW_POST_DATA']; //} // G. Giunta 2005/02/13: we do NOT expect to receive html entities // so we do not try to convert them into xml character entities //$data = xmlrpc_html_entity_xlate($data); $GLOBALS['_xh']=array(); $GLOBALS['_xh']['ac']=''; $GLOBALS['_xh']['stack']=array(); $GLOBALS['_xh']['valuestack'] = array(); $GLOBALS['_xh']['params']=array(); $GLOBALS['_xh']['pt']=array(); $GLOBALS['_xh']['isf']=0; $GLOBALS['_xh']['isf_reason']=''; $GLOBALS['_xh']['method']=false; // so we can check later if we got a methodname or not $GLOBALS['_xh']['rt']=''; // decompose incoming XML into request structure if ($req_encoding != '') { if (!in_array($req_encoding, array('UTF-8', 'ISO-8859-1', 'US-ASCII'))) // the following code might be better for mb_string enabled installs, but // makes the lib about 200% slower... //if (!is_valid_charset($req_encoding, array('UTF-8', 'ISO-8859-1', 'US-ASCII'))) { error_log('XML-RPC: xmlrpc_server::parseRequest: invalid charset encoding of received request: '.$req_encoding); $req_encoding = $GLOBALS['xmlrpc_defencoding']; } /// @BUG this will fail on PHP 5 if charset is not specified in the xml prologue, // the encoding is not UTF8 and there are non-ascii chars in the text... $parser = xml_parser_create($req_encoding); } else { $parser = xml_parser_create(); } xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true); // G. Giunta 2005/02/13: PHP internally uses ISO-8859-1, so we have to tell // the xml parser to give us back data in the expected charset xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, $GLOBALS['xmlrpc_internalencoding']); if ($this->functions_parameters_type != 'xmlrpcvals') xml_set_element_handler($parser, 'xmlrpc_se', 'xmlrpc_ee_fast'); else xml_set_element_handler($parser, 'xmlrpc_se', 'xmlrpc_ee'); xml_set_character_data_handler($parser, 'xmlrpc_cd'); xml_set_default_handler($parser, 'xmlrpc_dh'); if(!xml_parse($parser, $data, 1)) { // return XML error as a faultCode $r=&new xmlrpcresp(0, $GLOBALS['xmlrpcerrxml']+xml_get_error_code($parser), sprintf('XML error: %s at line %d, column %d', xml_error_string(xml_get_error_code($parser)), xml_get_current_line_number($parser), xml_get_current_column_number($parser))); xml_parser_free($parser); } elseif ($GLOBALS['_xh']['isf']) { xml_parser_free($parser); $r=&new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['invalid_request'], $GLOBALS['xmlrpcstr']['invalid_request'] . ' ' . $GLOBALS['_xh']['isf_reason']); } else { xml_parser_free($parser); if ($this->functions_parameters_type != 'xmlrpcvals') { if($this->debug > 1) { $this->debugmsg("\n+++PARSED+++\n".var_export($GLOBALS['_xh']['params'], true)."\n+++END+++"); } $r = $this->execute($GLOBALS['_xh']['method'], $GLOBALS['_xh']['params'], $GLOBALS['_xh']['pt']); } else { // build an xmlrpcmsg object with data parsed from xml $m=&new xmlrpcmsg($GLOBALS['_xh']['method']); // now add parameters in for($i=0; $i<count($GLOBALS['_xh']['params']); $i++) { $m->addParam($GLOBALS['_xh']['params'][$i]); } if($this->debug > 1) { $this->debugmsg("\n+++PARSED+++\n".var_export($m, true)."\n+++END+++"); } $r = $this->execute($m); } } return $r; } /** * Execute a method invoked by the client, checking parameters used * @param mixed $m either an xmlrpcmsg obj or a method name * @param array $params array with method parameters as php types (if m is method name only) * @param array $paramtypes array with xmlrpc types of method parameters (if m is method name only) * @return xmlrpcresp * @access private */ function execute($m, $params=null, $paramtypes=null) { if (is_object($m)) { $methName = $m->method(); } else { $methName = $m; } $sysCall = $this->allow_system_funcs && (strpos($methName, "system.") === 0); $dmap = $sysCall ? $GLOBALS['_xmlrpcs_dmap'] : $this->dmap; if(!isset($dmap[$methName]['function'])) { // No such method return new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['unknown_method'], $GLOBALS['xmlrpcstr']['unknown_method']); } // Check signature if(isset($dmap[$methName]['signature'])) { $sig = $dmap[$methName]['signature']; if (is_object($m)) { list($ok, $errstr) = $this->verifySignature($m, $sig); } else { list($ok, $errstr) = $this->verifySignature($paramtypes, $sig); } if(!$ok) { // Didn't match. return new xmlrpcresp( 0, $GLOBALS['xmlrpcerr']['incorrect_params'], $GLOBALS['xmlrpcstr']['incorrect_params'] . ": ${errstr}" ); } } $func = $dmap[$methName]['function']; // let the 'class::function' syntax be accepted in dispatch maps if(is_string($func) && strpos($func, '::')) { $func = explode('::', $func); } // verify that function to be invoked is in fact callable if(!is_callable($func)) { error_log("XML-RPC: xmlrpc_server::execute: function $func registered as method handler is not callable"); return new xmlrpcresp( 0, $GLOBALS['xmlrpcerr']['server_error'], $GLOBALS['xmlrpcstr']['server_error'] . ": no function matches method" ); } // If debug level is 3, we should catch all errors generated during // processing of user function, and log them as part of response if($this->debug > 2) { $GLOBALS['_xmlrpcs_prev_ehandler'] = set_error_handler('_xmlrpcs_errorHandler'); } if (is_object($m)) { if($sysCall) { $r = call_user_func($func, $this, $m); } else { $r = call_user_func($func, $m); } if (!is_a($r, 'xmlrpcresp')) { error_log("XML-RPC: xmlrpc_server::execute: function $func registered as method handler does not return an xmlrpcresp object"); if (is_a($r, 'xmlrpcval')) { $r =& new xmlrpcresp($r); } else { $r =& new xmlrpcresp( 0, $GLOBALS['xmlrpcerr']['server_error'], $GLOBALS['xmlrpcstr']['server_error'] . ": function does not return xmlrpcresp object" ); } } } else { // call a 'plain php' function if($sysCall) { array_unshift($params, $this); $r = call_user_func_array($func, $params); } else { // 3rd API convention for method-handling functions: EPI-style if ($this->functions_parameters_type == 'epivals') { $r = call_user_func_array($func, array($methName, $params, $this->user_data)); // mimic EPI behaviour: if we get an array that looks like an error, make it // an eror response if (is_array($r) && array_key_exists('faultCode', $r) && array_key_exists('faultString', $r)) { $r =& new xmlrpcresp(0, (integer)$r['faultCode'], (string)$r['faultString']); } else { // functions using EPI api should NOT return resp objects, // so make sure we encode the return type correctly $r =& new xmlrpcresp(php_xmlrpc_encode($r, array('extension_api'))); } } else { $r = call_user_func_array($func, $params); } } // the return type can be either an xmlrpcresp object or a plain php value... if (!is_a($r, 'xmlrpcresp')) { // what should we assume here about automatic encoding of datetimes // and php classes instances??? $r =& new xmlrpcresp(php_xmlrpc_encode($r, array('auto_dates'))); } } if($this->debug > 2) { // note: restore the error handler we found before calling the // user func, even if it has been changed inside the func itself if($GLOBALS['_xmlrpcs_prev_ehandler']) { set_error_handler($GLOBALS['_xmlrpcs_prev_ehandler']); } else { restore_error_handler(); } } return $r; } /** * add a string to the 'internal debug message' (separate from 'user debug message') * @param string $strings * @access private */ function debugmsg($string) { $this->debug_info .= $string."\n"; } /** * @access private */ function xml_header($charset_encoding='') { if ($charset_encoding != '') { return "<?xml version=\"1.0\" encoding=\"$charset_encoding\"?" . ">\n"; } else { return "<?xml version=\"1.0\"?" . ">\n"; } } /** * A debugging routine: just echoes back the input packet as a string value * DEPRECATED! */ function echoInput() { $r=&new xmlrpcresp(new xmlrpcval( "'Aha said I: '" . $GLOBALS['HTTP_RAW_POST_DATA'], 'string')); print $r->serialize(); } }?>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -