XMLRPC Debugger

1) $pport = $pproxy[1]; else $pport = 8080; $client->setProxy($pproxy[0], $pport, $proxyuser, $proxypwd); } if ($protocol == 2) { $client->setSSLVerifyPeer($verifypeer); $client->setSSLVerifyHost($verifyhost); if ($cainfo) { $client->setCaCertificate($cainfo); } $httpprotocol = 'https'; } else if ($protocol == 1) $httpprotocol = 'http11'; else $httpprotocol = 'http'; if ($username) $client->setCredentials($username, $password, $authtype); $client->setDebug($debug); switch ($requestcompression) { case 0: $client->request_compression = ''; break; case 1: $client->request_compression = 'gzip'; break; case 2: $client->request_compression = 'deflate'; break; } switch ($responsecompression) { case 0: $client->accepted_compression = ''; break; case 1: $client->accepted_compression = array('gzip'); break; case 2: $client->accepted_compression = array('deflate'); break; case 3: $client->accepted_compression = array('gzip', 'deflate'); break; } $cookies = explode(',', $clientcookies); foreach ($cookies as $cookie) { if (strpos($cookie, '=')) { $cookie = explode('=', $cookie); $client->setCookie(trim($cookie[0]), trim(@$cookie[1])); } } $msg = array(); switch ($action) { case 'wrap': @include('xmlrpc_wrappers.inc'); if (!function_exists('build_remote_method_wrapper_code')) { die('Error: to enable creation of method stubs the xmlrpc_wrappers.inc file is needed'); } // fall thru intentionally case 'describe': case 'wrap': $msg[0] =& new $msgclass('system.methodHelp', null, $id); $msg[0]->addparam(new xmlrpcval($method)); $msg[1] =& new $msgclass('system.methodSignature', null, $id+1); $msg[1]->addparam(new xmlrpcval($method)); $actionname = 'Description of method "'.$method.'"'; break; case 'list': $msg[0] =& new $msgclass('system.listMethods', null, $id); $actionname = 'List of available methods'; break; case 'execute': if (!payload_is_safe($payload)) die("Tsk tsk tsk, please stop it or I will have to call in the cops!"); $msg[0] =& new $msgclass($method, null, $id); // hack! build xml payload by hand if ($wstype == 1) { $msg[0]->payload = "{\n". '"method": "' . $method . "\",\n\"params\": [" . $payload . "\n],\n\"id\": "; // fix: if user gave an empty string, use NULL, or we'll break json syntax if ($id == "") { $msg[0]->payload .= "null\n}"; } else { if (is_numeric($id) || $id == 'false' || $id == 'true' || $id == 'null') { $msg[0]->payload .= "$id\n}"; } else { $msg[0]->payload .= "\"$id\"\n}"; } } } else $msg[0]->payload = $msg[0]->xml_header() . '' . $method . "\n" . $payload . "\n" . $msg[0]->xml_footer(); $actionname = 'Execution of method '.$method; break; default: // give a warning $actionname = '[ERROR: unknown action] "'.$action.'"'; } // Before calling execute, echo out brief description of action taken + date and time ??? // this gives good user feedback for long-running methods... echo '

## '.htmlspecialchars($actionname).' on server '.htmlspecialchars($server)." ...

\n"; flush(); $response = null; // execute method(s) if ($debug) echo '

## Debug info:

'; /// @todo use ob_start instead $resp = array(); $mtime = explode(' ',microtime()); $time = (float)$mtime[0] + (float)$mtime[1]; foreach ($msg as $message) { // catch errors: for older xmlrpc libs, send does not return by ref @$response =& $client->send($message, $timeout, $httpprotocol); $resp[] = $response; if (!$response || $response->faultCode()) break; } $mtime = explode(' ',microtime()); $time = (float)$mtime[0] + (float)$mtime[1] - $time; if ($debug) echo "
\n"; if ($response) { if ($response->faultCode()) { // call failed! echo out error msg! //echo '

## '.htmlspecialchars($actionname).' on server '.htmlspecialchars($server).'

'; echo "

### $protoname call FAILED!

\n"; echo "

Fault code: [" . htmlspecialchars($response->faultCode()) . "] Reason: '" . htmlspecialchars($response->faultString()) . "'

\n"; echo (strftime("%d/%b/%Y:%H:%M:%S\n")); } else { // call succeeded: parse results //echo '

## '.htmlspecialchars($actionname).' on server '.htmlspecialchars($server).'

'; printf ("

### %s call(s) OK (%.2f secs.)

\n", $protoname, $time); echo (strftime("%d/%b/%Y:%H:%M:%S\n")); switch ($action) { case 'list': $v = $response->value(); $max = $v->arraysize(); echo "

\n"; echo "
\n
Method | Description
--- | ---
\n
\n
\n"; for($i=0; $i < $max; $i++) { $rec = $v->arraymem($i); if ($i%2) $class=' class="oddrow"'; else $class = ' class="evenrow"'; echo ("
".htmlspecialchars($rec->scalarval())." ". "". "". "". "". "". "". "". "". "". "". "". "". "". "". "". "". "". "". "". "scalarval()."\" />". "". "". "". " "); //echo("
\n"); // generate lo scheletro per il method payload per eventuali test //$methodpayload="\n".$rec->scalarval()."\n\n\n\n"; /*echo (" ". "". "". "". "scalarval()."\" />". "". "". " ");*/ echo("\n"); } echo "
\n

"; break; case 'describe': $r1 = $resp[0]->value(); $r2 = $resp[1]->value(); echo "

\n"; echo "
\n
Method | ".htmlspecialchars($method)." |  |
--- | --- | --- | ---
\n
\n
\n"; $desc = htmlspecialchars($r1->scalarval()); if ($desc == "") $desc = "-"; echo "
Description | $desc
\n"; $payload=""; $alt_payload=""; if ($r2->kindOf()!="array") echo "
Signature | Unknown |
\n"; else { for($i=0; $i < $r2->arraysize(); $i++) { if ($i+1%2) $class=' class="oddrow"'; else $class = ' class="evenrow"'; echo "
Signature ".($i+1).""; $x = $r2->arraymem($i); $ret = $x->arraymem(0); echo "`OUT: " . htmlspecialchars($ret->scalarval()) . "
IN: ("; if ($x->arraysize() > 1) { for($k = 1; $k < $x->arraysize(); $k++) { $y = $x->arraymem($k); echo $y->scalarval(); if ($wstype != 1) { $payload = $payload . '<'.htmlspecialchars($y->scalarval()).'>scalarval()).">\n"; } $alt_payload .= $y->scalarval(); if ($k < $x->arraysize()-1) { $alt_payload .= ';'; echo ", "; } } } echo ")`"; //bottone per testare questo metodo //$payload="\n$method\n\n$payload\n"; echo " ". "". "". "". "". "". "". "". "". "". "". "". "". "". "". "". "". "". "". "". "". "". "". "". ""; if ($wstype != 1) echo ""; echo " \n"; echo " ". "". "". "". "". "". "". "". "". "". "". "". "". "". "". "". "". "". "". "". "". "". "". "". "". "". "". ""; echo "
\n"; } } echo "
\n

"; break; case 'wrap': $r1 = $resp[0]->value(); $r2 = $resp[1]->value(); if ($r2->kindOf()!="array" || $r2->arraysize() <= $methodsig) echo "Error: signature unknown\n"; else { $mdesc = $r1->scalarval(); $msig = php_xmlrpc_decode($r2); $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 "
\n"; highlight_string("'); echo "\n
"; //} //else //{ // echo 'Error while building php code stub...'; } break; case 'execute': echo '

## Response:

'.htmlspecialchars($response->serialize()).'
'; break; default: // give a warning } } // if !$response->faultCode() } // if $response } else { // no action taken yet: give some instructions on debugger usage ?>

### Instructions on usage of the debugger:

1. Run a 'list available methods' action against desired server
2. If list of methods appears, click on 'describe method' for desired method
3. To run method: click on 'load method synopsis' for desired method. This will load a skeleton for method call parameters in the form above. Complete all xmlrpc values with appropriate data and click 'Execute'

You will need to enable the CURL extension to use the HTTPS and HTTP 1.1 transports\n"; } ?>

### Example:

Server Address: phpxmlrpc.sourceforge.net
Path: /server.php

### Notice:

all usernames and passwords entered on the above form will be written to the web server logs of this server. Use with care.

### Changelog

- 2007-02-20: add visual editor for method payload; allow strings, bools as jsonrpc msg id
- 2006-06-26: support building php code stub for calling remote methods
- 2006-05-25: better support for long running queries; check for no-curl installs
- 2006-05-02: added support for JSON-RPC. Note that many interesting json-rpc features are not implemented yet, such as notifications or multicall.
- 2006-04-22: added option for setting custom CA certs to verify peer with in SSLmode
- 2006-03-05: added option for setting Basic/Digest/NTLM auth type
- 2006-01-18: added option echoing to screen xmlrpc request before sending it ('More' debug)
- 2005-10-01: added option for setting cookies to be sent to server
- 2005-08-07: added switches for compression of requests and responses and http 1.1
- 2005-06-27: fixed possible security breach in parsing malformed xml
- 2005-06-24: fixed error with calling methods having parameters...