예제 #1
0
         $msig = $msig[$methodsig];
         $proto = $protocol == 2 ? 'https' : $protocol == 1 ? 'http11' : '';
         if ($proxy == '' && $username == '' && !$requestcompression && !$responsecompression && $clientcookies == '') {
             $opts = 0;
             // simple client copy in stub code
         } else {
             $opts = 1;
             // complete client copy in stub code
         }
         if ($wstype == 1) {
             $prefix = 'jsonrpc';
         } else {
             $prefix = 'xmlrpc';
         }
         //$code = wrap_xmlrpc_method($client, $method, $methodsig, 0, $proto, '', $opts);
         $code = build_remote_method_wrapper_code($client, $method, str_replace('.', '_', $prefix . '_' . $method), $msig, $mdesc, $timeout, $proto, $opts, $prefix);
         //if ($code)
         //{
         echo "<div id=\"phpcode\">\n";
         highlight_string("<?php\n" . $code['docstring'] . $code['source'] . '?>');
         echo "\n</div>";
         //}
         //else
         //{
         //  echo 'Error while building php code stub...';
     }
     break;
 case 'execute':
     echo '<div id="response"><h2>Response:</h2>' . htmlspecialchars($response->serialize()) . '</div>';
     break;
 default:
예제 #2
0
/**
 * Given an xmlrpc client and a method name, register a php wrapper function
 * that will call it and return results using native php types for both
 * params and results. The generated php function will return an xmlrpcresp
 * oject for failed xmlrpc calls
 *
 * Known limitations:
 * - server must support system.methodsignature for the wanted xmlrpc method
 * - for methods that expose many signatures, only one can be picked (we
 *   could in priciple check if signatures differ only by number of params
 *   and not by type, but it would be more complication than we can spare time)
 * - nested xmlrpc params: the caller of the generated php function has to
 *   encode on its own the params passed to the php function if these are structs
 *   or arrays whose (sub)members include values of type datetime or base64
 *
 * Notes: the connection properties of the given client will be copied
 * and reused for the connection used during the call to the generated
 * php function.
 * Calling the generated php function 'might' be slow: a new xmlrpc client
 * is created on every invocation and an xmlrpc-connection opened+closed.
 * An extra 'debug' param is appended to param list of xmlrpc method, useful
 * for debugging purposes.
 *
 * @param xmlrpc_client $client     an xmlrpc client set up correctly to communicate with target server
 * @param string        $methodname the xmlrpc method to be mapped to a php function
 * @param array         $extra_options array of options that specify conversion details. valid ptions include
 *        integer       signum      the index of the method signature to use in mapping (if method exposes many sigs)
 *        integer       timeout     timeout (in secs) to be used when executing function/calling remote method
 *        string        protocol    'http' (default), 'http11' or 'https'
 *        string        new_function_name the name of php function to create. If unsepcified, lib will pick an appropriate name
 *        string        return_source if true return php code w. function definition instead fo function name
 *        bool          encode_php_objs let php objects be sent to server using the 'improved' xmlrpc notation, so server can deserialize them as php objects
 *        bool          decode_php_objs --- WARNING !!! possible security hazard. only use it with trusted servers ---
 *        mixed         return_on_fault a php value to be returned when the xmlrpc call fails/returns a fault response (by default the xmlrpcresp object is returned in this case). If a string is used, '%faultCode%' and '%faultString%' tokens will be substituted with actual error values
 *        bool          debug        set it to 1 or 2 to see debug results of querying server for method synopsis
 * @return string                   the name of the generated php function (or false) - OR AN ARRAY...
 */
function wrap_xmlrpc_method($client, $methodname, $extra_options = 0, $timeout = 0, $protocol = '', $newfuncname = '')
{
    // mind numbing: let caller use sane calling convention (as per javadoc, 3 params),
    // OR the 2.0 calling convention (no options) - we really love backward compat, don't we?
    if (!is_array($extra_options)) {
        $signum = $extra_options;
        $extra_options = array();
    } else {
        $signum = isset($extra_options['signum']) ? (int) $extra_options['signum'] : 0;
        $timeout = isset($extra_options['timeout']) ? (int) $extra_options['timeout'] : 0;
        $protocol = isset($extra_options['protocol']) ? $extra_options['protocol'] : '';
        $newfuncname = isset($extra_options['new_function_name']) ? $extra_options['new_function_name'] : '';
    }
    //$encode_php_objects = in_array('encode_php_objects', $extra_options);
    //$verbatim_client_copy = in_array('simple_client_copy', $extra_options) ? 1 :
    //	in_array('build_class_code', $extra_options) ? 2 : 0;
    $encode_php_objects = isset($extra_options['encode_php_objs']) ? (bool) $extra_options['encode_php_objs'] : false;
    $decode_php_objects = isset($extra_options['decode_php_objs']) ? (bool) $extra_options['decode_php_objs'] : false;
    $simple_client_copy = isset($extra_options['simple_client_copy']) ? (int) $extra_options['simple_client_copy'] : 0;
    $buildit = isset($extra_options['return_source']) ? !$extra_options['return_source'] : true;
    $prefix = isset($extra_options['prefix']) ? $extra_options['prefix'] : 'xmlrpc';
    if (isset($extra_options['return_on_fault'])) {
        $decode_fault = true;
        $fault_response = $extra_options['return_on_fault'];
    } else {
        $decode_fault = false;
        $fault_response = '';
    }
    $debug = isset($extra_options['debug']) ? $extra_options['debug'] : 0;
    $msgclass = $prefix . 'msg';
    $valclass = $prefix . 'val';
    $decodefunc = 'php_' . $prefix . '_decode';
    $msg = new $msgclass('system.methodSignature');
    $msg->addparam(new $valclass($methodname));
    $client->setDebug($debug);
    $response =& $client->send($msg, $timeout, $protocol);
    if ($response->faultCode()) {
        error_log('XML-RPC: could not retrieve method signature from remote server for method ' . $methodname);
        return false;
    } else {
        $msig = $response->value();
        if ($client->return_type != 'phpvals') {
            $msig = $decodefunc($msig);
        }
        if (!is_array($msig) || count($msig) <= $signum) {
            error_log('XML-RPC: could not retrieve method signature nr.' . $signum . ' from remote server for method ' . $methodname);
            return false;
        } else {
            // pick a suitable name for the new function, avoiding collisions
            if ($newfuncname != '') {
                $xmlrpcfuncname = $newfuncname;
            } else {
                // take care to insure that methodname is translated to valid
                // php function name
                $xmlrpcfuncname = $prefix . '_' . preg_replace(array('/\\./', '/[^a-zA-Z0-9_\\x7f-\\xff]/'), array('_', ''), $methodname);
            }
            while ($buildit && function_exists($xmlrpcfuncname)) {
                $xmlrpcfuncname .= 'x';
            }
            $msig = $msig[$signum];
            $mdesc = '';
            // if in 'offline' mode, get method description too.
            // in online mode, favour speed of operation
            if (!$buildit) {
                $msg = new $msgclass('system.methodHelp');
                $msg->addparam(new $valclass($methodname));
                $response =& $client->send($msg, $timeout, $protocol);
                if (!$response->faultCode()) {
                    $mdesc = $response->value();
                    if ($client->return_type != 'phpvals') {
                        $mdesc = $mdesc->scalarval();
                    }
                }
            }
            $results = build_remote_method_wrapper_code($client, $methodname, $xmlrpcfuncname, $msig, $mdesc, $timeout, $protocol, $simple_client_copy, $prefix, $decode_php_objects, $encode_php_objects, $decode_fault, $fault_response);
            //print_r($code);
            if ($buildit) {
                $allOK = 0;
                eval($results['source'] . '$allOK=1;');
                // alternative
                //$xmlrpcfuncname = create_function('$m', $innercode);
                if ($allOK) {
                    return $xmlrpcfuncname;
                } else {
                    error_log('XML-RPC: could not create function ' . $xmlrpcfuncname . ' to wrap remote method ' . $methodname);
                    return false;
                }
            } else {
                $results['function'] = $xmlrpcfuncname;
                return $results;
            }
        }
    }
}