Seditio Source
Root |
./othercms/wordpress-6.0/wp-includes/IXR/class-IXR-server.php
<?php

/**
 * IXR_Server
 *
 * @package IXR
 * @since 1.5.0
 */
class IXR_Server
{
    var
$data;
    var
$callbacks = array();
    var
$message;
    var
$capabilities;

   
/**
     * PHP5 constructor.
     */
   
function __construct( $callbacks = false, $data = false, $wait = false )
    {
       
$this->setCapabilities();
        if (
$callbacks) {
           
$this->callbacks = $callbacks;
        }
       
$this->setCallbacks();
        if (!
$wait) {
           
$this->serve($data);
        }
    }

   
/**
     * PHP4 constructor.
     */
   
public function IXR_Server( $callbacks = false, $data = false, $wait = false ) {
       
self::__construct( $callbacks, $data, $wait );
    }

    function
serve($data = false)
    {
        if (!
$data) {
            if (isset(
$_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] !== 'POST') {
                if (
function_exists( 'status_header' ) ) {
                   
status_header( 405 ); // WP #20986
                   
header( 'Allow: POST' );
                }
               
header('Content-Type: text/plain'); // merged from WP #9093
               
die('XML-RPC server accepts POST requests only.');
            }

           
$data = file_get_contents('php://input');
        }
       
$this->message = new IXR_Message($data);
        if (!
$this->message->parse()) {
           
$this->error(-32700, 'parse error. not well formed');
        }
        if (
$this->message->messageType != 'methodCall') {
           
$this->error(-32600, 'server error. invalid xml-rpc. not conforming to spec. Request must be a methodCall');
        }
       
$result = $this->call($this->message->methodName, $this->message->params);

       
// Is the result an error?
       
if (is_a($result, 'IXR_Error')) {
           
$this->error($result);
        }

       
// Encode the result
       
$r = new IXR_Value($result);
       
$resultxml = $r->getXml();

       
// Create the XML
       
$xml = <<<EOD
<methodResponse>
  <params>
    <param>
      <value>
     
$resultxml
      </value>
    </param>
  </params>
</methodResponse>

EOD;
     
// Send it
     
$this->output($xml);
    }

    function
call($methodname, $args)
    {
        if (!
$this->hasMethod($methodname)) {
            return new
IXR_Error(-32601, 'server error. requested method '.$methodname.' does not exist.');
        }
       
$method = $this->callbacks[$methodname];

       
// Perform the callback and send the response
       
if (count($args) == 1) {
           
// If only one parameter just send that instead of the whole array
           
$args = $args[0];
        }

       
// Are we dealing with a function or a method?
       
if (is_string($method) && substr($method, 0, 5) == 'this:') {
           
// It's a class method - check it exists
           
$method = substr($method, 5);
            if (!
method_exists($this, $method)) {
                return new
IXR_Error(-32601, 'server error. requested class method "'.$method.'" does not exist.');
            }

           
//Call the method
           
$result = $this->$method($args);
        } else {
           
// It's a function - does it exist?
           
if (is_array($method)) {
                if (!
is_callable(array($method[0], $method[1]))) {
                    return new
IXR_Error(-32601, 'server error. requested object method "'.$method[1].'" does not exist.');
                }
            } else if (!
function_exists($method)) {
                return new
IXR_Error(-32601, 'server error. requested function "'.$method.'" does not exist.');
            }

           
// Call the function
           
$result = call_user_func($method, $args);
        }
        return
$result;
    }

    function
error($error, $message = false)
    {
       
// Accepts either an error object or an error code and message
       
if ($message && !is_object($error)) {
           
$error = new IXR_Error($error, $message);
        }

       
$this->output($error->getXml());
    }

    function
output($xml)
    {
       
$charset = function_exists('get_option') ? get_option('blog_charset') : '';
        if (
$charset)
           
$xml = '<?xml version="1.0" encoding="'.$charset.'"?>'."\n".$xml;
        else
           
$xml = '<?xml version="1.0"?>'."\n".$xml;
       
$length = strlen($xml);
       
header('Connection: close');
        if (
$charset)
           
header('Content-Type: text/xml; charset='.$charset);
        else
           
header('Content-Type: text/xml');
       
header('Date: '.gmdate('r'));
        echo
$xml;
        exit;
    }

    function
hasMethod($method)
    {
        return
in_array($method, array_keys($this->callbacks));
    }

    function
setCapabilities()
    {
       
// Initialises capabilities array
       
$this->capabilities = array(
           
'xmlrpc' => array(
               
'specUrl' => 'http://www.xmlrpc.com/spec',
               
'specVersion' => 1
       
),
           
'faults_interop' => array(
               
'specUrl' => 'http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php',
               
'specVersion' => 20010516
       
),
           
'system.multicall' => array(
               
'specUrl' => 'http://www.xmlrpc.com/discuss/msgReader$1208',
               
'specVersion' => 1
       
),
        );
    }

    function
getCapabilities($args)
    {
        return
$this->capabilities;
    }

    function
setCallbacks()
    {
       
$this->callbacks['system.getCapabilities'] = 'this:getCapabilities';
       
$this->callbacks['system.listMethods'] = 'this:listMethods';
       
$this->callbacks['system.multicall'] = 'this:multiCall';
    }

    function
listMethods($args)
    {
       
// Returns a list of methods - uses array_reverse to ensure user defined
        // methods are listed before server defined methods
       
return array_reverse(array_keys($this->callbacks));
    }

    function
multiCall($methodcalls)
    {
       
// See http://www.xmlrpc.com/discuss/msgReader$1208
       
$return = array();
        foreach (
$methodcalls as $call) {
           
$method = $call['methodName'];
           
$params = $call['params'];
            if (
$method == 'system.multicall') {
               
$result = new IXR_Error(-32600, 'Recursive calls to system.multicall are forbidden');
            } else {
               
$result = $this->call($method, $params);
            }
            if (
is_a($result, 'IXR_Error')) {
               
$return[] = array(
                   
'faultCode' => $result->code,
                   
'faultString' => $result->message
               
);
            } else {
               
$return[] = array($result);
            }
        }
        return
$return;
    }
}