⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmlrpcs.inc

📁 PHP 知识管理系统(基于树结构的知识管理系统), 英文原版的PHP源码。
💻 INC
📖 第 1 页 / 共 3 页
字号:
			// 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 + -