gggeek /
phpxmlrpc
| 1 | <?php |
||
| 2 | /** |
||
| 3 | * @author Gaetano Giunta |
||
| 4 | * @copyright (C) 2005-2025 G. Giunta |
||
| 5 | * @license code licensed under the BSD License: see file license.txt |
||
| 6 | * |
||
| 7 | * @todo switch params for http compression from 0,1,2 to values to be used directly |
||
| 8 | * @todo use ob_start to catch debug info and echo it AFTER method call results? |
||
| 9 | * @todo be smarter in creating client stub for proxy/auth cases: only set appropriate property of client obj |
||
| 10 | **/ |
||
| 11 | |||
| 12 | header('Content-Type: text/html; charset=utf-8'); |
||
| 13 | |||
| 14 | ?><!DOCTYPE html> |
||
| 15 | <html lang="en"> |
||
| 16 | <head> |
||
| 17 | <link rel="icon" type="image/vnd.microsoft.icon" href="favicon.ico"> |
||
| 18 | <title><?php if (defined('DEFAULT_WSTYPE') && (DEFAULT_WSTYPE == 1 || DEFAULT_WSTYPE == 2)) echo 'JSON-RPC'; else echo 'XML-RPC'; ?> Debugger</title> |
||
|
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||
| 19 | <meta name="robots" content="index,nofollow"/> |
||
| 20 | <style type="text/css"> |
||
| 21 | <!-- |
||
| 22 | body { |
||
| 23 | border-top: 1px solid gray; |
||
| 24 | padding: 1em; |
||
| 25 | font-family: Verdana, Arial, Helvetica, sans-serif; |
||
| 26 | font-size: 8pt; |
||
| 27 | } |
||
| 28 | h3 { |
||
| 29 | font-size: 9.5pt; |
||
| 30 | } |
||
| 31 | h2 { |
||
| 32 | font-size: 12pt; |
||
| 33 | } |
||
| 34 | .dbginfo { |
||
| 35 | padding: 1em; |
||
| 36 | background-color: #EEEEEE; |
||
| 37 | border: 1px dashed silver; |
||
| 38 | font-family: monospace; |
||
| 39 | } |
||
| 40 | #response { |
||
| 41 | padding: 1em; |
||
| 42 | margin-top: 1em; |
||
| 43 | background-color: #DDDDDD; |
||
| 44 | border: 1px solid gray; |
||
| 45 | white-space: pre; |
||
| 46 | font-family: monospace; |
||
| 47 | } |
||
| 48 | table { |
||
| 49 | padding: 2px; |
||
| 50 | margin-top: 1em; |
||
| 51 | } |
||
| 52 | th { |
||
| 53 | background-color: navy; |
||
| 54 | color: white; |
||
| 55 | padding: 0.5em; |
||
| 56 | } |
||
| 57 | td { |
||
| 58 | padding: 0.5em; |
||
| 59 | font-family: monospace; |
||
| 60 | } |
||
| 61 | td form { |
||
| 62 | margin: 0; |
||
| 63 | } |
||
| 64 | .oddrow { |
||
| 65 | background-color: #EEEEEE; |
||
| 66 | } |
||
| 67 | .evidence { |
||
| 68 | color: blue; |
||
| 69 | } |
||
| 70 | #phpcode { |
||
| 71 | background-color: #EEEEEE; |
||
| 72 | padding: 1em; |
||
| 73 | margin-top: 1em; |
||
| 74 | } |
||
| 75 | --> |
||
| 76 | </style> |
||
| 77 | </head> |
||
| 78 | <body> |
||
| 79 | <?php |
||
| 80 | |||
| 81 | global $inputcharset, $debug, $protocol, $run, $hasjsonrpcclient, $hasjsonrpc2, $wstype, $id, $host, $port, $path, $action, |
||
| 82 | $method, $methodsig, $payload, $alt_payload, $username, $password, $authtype, $verifyhost, $verifypeer, $cainfo, $proxy, |
||
| 83 | $proxyuser, $proxypwd, $timeout, $requestcompression, $responsecompression, $clientcookies; |
||
| 84 | |||
| 85 | include __DIR__ . '/common.php'; |
||
| 86 | |||
| 87 | if ($action) { |
||
| 88 | |||
| 89 | // avoid php hanging when using the builtin webserver and sending requests to itself |
||
| 90 | $skip = false; |
||
| 91 | if (php_sapi_name() === 'cli-server' && ((int)getenv('PHP_CLI_SERVER_WORKERS') < 2)) { |
||
| 92 | $localHost = explode(':', $_SERVER['HTTP_HOST']); |
||
| 93 | /// @todo support also case where port is null (on either side), and when there is a Proxy in the parameters, |
||
| 94 | /// and that proxy is us |
||
| 95 | if ($localHost[0] == $host && (@$localHost[1] == $port)) { |
||
| 96 | $actionname = '[ERROR: can not make call to self when running php-cli webserver without setting PHP_CLI_SERVER_WORKERS]'; |
||
| 97 | $skip = true; |
||
| 98 | } |
||
| 99 | } |
||
| 100 | |||
| 101 | if (!$skip) { |
||
| 102 | // make sure the script waits long enough for the call to complete... |
||
| 103 | if ($timeout) { |
||
| 104 | set_time_limit($timeout + 10); |
||
| 105 | } |
||
| 106 | |||
| 107 | if ($wstype == 1 || $wstype == 2) { |
||
| 108 | $clientClass = '\PhpXmlRpc\JsonRpc\Client'; |
||
| 109 | $requestClass = '\PhpXmlRpc\JsonRpc\Request'; |
||
| 110 | if ($hasjsonrpc2) { |
||
| 111 | $notificationClass = '\PhpXmlRpc\JsonRpc\Notification'; |
||
| 112 | } else { |
||
| 113 | $notificationClass = '\PhpXmlRpc\JsonRpc\Request'; |
||
| 114 | } |
||
| 115 | $protoName = 'JSON-RPC'; |
||
| 116 | } else { |
||
| 117 | $clientClass = '\PhpXmlRpc\Client'; |
||
| 118 | $requestClass = '\PhpXmlRpc\Request'; |
||
| 119 | $notificationClass = '\PhpXmlRpc\Request'; |
||
| 120 | $protoName = 'XML-RPC'; |
||
| 121 | } |
||
| 122 | |||
| 123 | if ($port != "") { |
||
| 124 | $client = new $clientClass($path, $host, $port); |
||
| 125 | $server = "$host:$port$path"; |
||
| 126 | } else { |
||
| 127 | $client = new $clientClass($path, $host); |
||
| 128 | $server = "$host$path"; |
||
| 129 | } |
||
| 130 | if ($protocol == 2 || $protocol == 3) { |
||
| 131 | $server = 'https://' . $server; |
||
| 132 | } else { |
||
| 133 | $server = 'http://' . $server; |
||
| 134 | } |
||
| 135 | if ($proxy != '') { |
||
| 136 | $pproxy = explode(':', $proxy); |
||
| 137 | if (count($pproxy) > 1) { |
||
| 138 | $pport = $pproxy[1]; |
||
| 139 | } else { |
||
| 140 | $pport = 8080; |
||
| 141 | } |
||
| 142 | $client->setProxy($pproxy[0], $pport, $proxyuser, $proxypwd); |
||
| 143 | } |
||
| 144 | |||
| 145 | if ($protocol == 2 || $protocol == 3) { |
||
| 146 | $client->setOption(\PhpXmlRpc\Client::OPT_VERIFY_PEER, $verifypeer); |
||
| 147 | $client->setOption(\PhpXmlRpc\Client::OPT_VERIFY_HOST, $verifyhost); |
||
| 148 | if ($cainfo) { |
||
| 149 | $client->setCaCertificate($cainfo); |
||
| 150 | } |
||
| 151 | if ($protocol == 3) { |
||
| 152 | $httpprotocol = 'h2'; |
||
| 153 | } else { |
||
| 154 | $httpprotocol = 'https'; |
||
| 155 | } |
||
| 156 | } elseif ($protocol == 4) { |
||
| 157 | $httpprotocol = 'h2c'; |
||
| 158 | } elseif ($protocol == 1) { |
||
| 159 | $httpprotocol = 'http11'; |
||
| 160 | } else { |
||
| 161 | $httpprotocol = 'http'; |
||
| 162 | } |
||
| 163 | |||
| 164 | if ($username) { |
||
| 165 | $client->setCredentials($username, $password, $authtype); |
||
| 166 | } |
||
| 167 | |||
| 168 | $client->setDebug($debug); |
||
| 169 | |||
| 170 | switch ($requestcompression) { |
||
| 171 | case 0: |
||
| 172 | $client->setOption(\PhpXmlRpc\Client::OPT_REQUEST_COMPRESSION, ''); |
||
| 173 | break; |
||
| 174 | case 1: |
||
| 175 | $client->setOption(\PhpXmlRpc\Client::OPT_REQUEST_COMPRESSION, 'gzip'); |
||
| 176 | break; |
||
| 177 | case 2: |
||
| 178 | $client->setOption(\PhpXmlRpc\Client::OPT_REQUEST_COMPRESSION, 'deflate'); |
||
| 179 | break; |
||
| 180 | } |
||
| 181 | |||
| 182 | switch ($responsecompression) { |
||
| 183 | case 0: |
||
| 184 | $client->setOption(\PhpXmlRpc\Client::OPT_ACCEPTED_COMPRESSION, ''); |
||
| 185 | break; |
||
| 186 | case 1: |
||
| 187 | $client->setOption(\PhpXmlRpc\Client::OPT_ACCEPTED_COMPRESSION, array('gzip')); |
||
| 188 | break; |
||
| 189 | case 2: |
||
| 190 | $client->setOption(\PhpXmlRpc\Client::OPT_ACCEPTED_COMPRESSION, ('deflate')); |
||
| 191 | break; |
||
| 192 | case 3: |
||
| 193 | $client->setOption(\PhpXmlRpc\Client::OPT_ACCEPTED_COMPRESSION, array('gzip', 'deflate')); |
||
| 194 | break; |
||
| 195 | } |
||
| 196 | |||
| 197 | $cookies = explode(',', $clientcookies); |
||
| 198 | foreach ($cookies as $cookie) { |
||
| 199 | if (strpos($cookie, '=')) { |
||
| 200 | $cookie = explode('=', $cookie); |
||
| 201 | $client->setCookie(trim($cookie[0]), trim(@$cookie[1])); |
||
| 202 | } |
||
| 203 | } |
||
| 204 | |||
| 205 | $msg = array(); |
||
| 206 | switch ($action) { |
||
| 207 | // fall thru intentionally |
||
| 208 | case 'describe': |
||
| 209 | case 'wrap': |
||
| 210 | $msg[0] = new $requestClass('system.methodHelp', array(), (int)$id); |
||
| 211 | $msg[0]->addparam(new PhpXmlRpc\Value($method)); |
||
| 212 | $msg[1] = new $requestClass('system.methodSignature', array(), (int)$id + 1); |
||
| 213 | $msg[1]->addparam(new PhpXmlRpc\Value($method)); |
||
| 214 | if ($wstype == 2) { |
||
| 215 | $msg[0]->setJsonRpcVersion('2.0'); |
||
| 216 | $msg[1]->setJsonRpcVersion('2.0'); |
||
| 217 | } elseif ($wstype == 1 && $hasjsonrpc2) { |
||
| 218 | $msg[0]->setJsonRpcVersion('1.0'); |
||
| 219 | $msg[1]->setJsonRpcVersion('1.0'); |
||
| 220 | } |
||
| 221 | $actionname = 'Description of method "' . $method . '"'; |
||
| 222 | break; |
||
| 223 | case 'list': |
||
| 224 | $msg[0] = new $requestClass('system.listMethods', array(), (int)$id); |
||
| 225 | if ($wstype == 2) { |
||
| 226 | $msg[0]->setJsonRpcVersion('2.0'); |
||
| 227 | } elseif ($wstype == 1 && $hasjsonrpc2) { |
||
| 228 | $msg[0]->setJsonRpcVersion('1.0'); |
||
| 229 | } |
||
| 230 | $actionname = 'List of available methods'; |
||
| 231 | break; |
||
| 232 | case 'execute': |
||
| 233 | case 'notification': |
||
| 234 | if (!payload_is_safe($payload)) { |
||
| 235 | die("Tsk tsk tsk, please stop it or I will have to call in the cops!"); |
||
| 236 | } |
||
| 237 | if ($action == 'notification') { |
||
| 238 | $msg[0] = new $notificationClass($method, array()); |
||
| 239 | } else { |
||
| 240 | $msg[0] = new $requestClass($method, array(), $id); |
||
| 241 | } |
||
| 242 | // hack! build payload by hand |
||
| 243 | if ($wstype == 2) { |
||
| 244 | $payload = rtrim($payload, "\n"); |
||
| 245 | $payload = "{\n" . |
||
| 246 | '"jsonrpc": "2.0"' . ",\n" . |
||
| 247 | '"method": "' . $method . "\",\n\"params\": [\n" . |
||
| 248 | $payload . |
||
| 249 | "\n]"; |
||
| 250 | if ($action == "notification") { |
||
| 251 | $payload .= "\n"; |
||
| 252 | } else { |
||
| 253 | if (is_numeric($id)) { |
||
| 254 | $payload .= ",\n\"id\": $id\n"; |
||
| 255 | } else { |
||
| 256 | $payload .= ",\n\"id\": \"$id\"\n"; |
||
| 257 | } |
||
| 258 | } |
||
| 259 | $payload .= '}'; |
||
| 260 | $msg[0]->setPayload($payload); |
||
| 261 | $msg[0]->setJsonRpcVersion('2.0'); |
||
| 262 | } elseif ($wstype == 1) { |
||
| 263 | $payload = rtrim($payload, "\n"); |
||
| 264 | $payload = "{\n" . |
||
| 265 | '"method": "' . $method . "\",\n\"params\": [\n" . |
||
| 266 | $payload . |
||
| 267 | "\n],\n\"id\": "; |
||
| 268 | if ($action == "notification") { |
||
| 269 | $payload .= "null\n}"; |
||
| 270 | } else { |
||
| 271 | if (is_numeric($id) || $id == 'false' || $id == 'true') { |
||
| 272 | $payload .= "$id\n}"; |
||
| 273 | } else { |
||
| 274 | // this includes the empty string ;-) |
||
| 275 | $payload .= "\"$id\"\n}"; |
||
| 276 | } |
||
| 277 | } |
||
| 278 | $msg[0]->setPayload($payload); |
||
| 279 | if ($hasjsonrpc2) { |
||
| 280 | $msg[0]->setJsonRpcVersion('1.0'); |
||
| 281 | } |
||
| 282 | } else { |
||
| 283 | $msg[0]->setPayload( |
||
| 284 | $msg[0]->xml_header($inputcharset) . |
||
| 285 | '<methodName>' . $method . "</methodName>\n<params>" . |
||
| 286 | $payload . |
||
| 287 | "</params>\n" . $msg[0]->xml_footer() |
||
| 288 | ); |
||
| 289 | } |
||
| 290 | if ($action == 'notification') { |
||
| 291 | $actionname = 'Execution of notification ' . $method; |
||
| 292 | } else { |
||
| 293 | $actionname = 'Execution of method ' . $method; |
||
| 294 | } |
||
| 295 | break; |
||
| 296 | default: // give a warning |
||
| 297 | $actionname = '[ERROR: unknown action] "' . $action . '"'; |
||
| 298 | } |
||
| 299 | } |
||
| 300 | |||
| 301 | // Before calling execute, echo out brief description of action taken + date and time ??? |
||
| 302 | // this gives good user feedback for long-running methods... |
||
| 303 | echo '<h2>' . htmlspecialchars($actionname, ENT_COMPAT, $inputcharset) . ' on server ' . htmlspecialchars($server, ENT_COMPAT, $inputcharset) . " ...</h2>\n"; |
||
| 304 | flush(); |
||
| 305 | |||
| 306 | $response = null; |
||
| 307 | // execute method(s) |
||
| 308 | if ($debug) { |
||
| 309 | echo '<div class="dbginfo"><h2>Debug info:</h2>'; |
||
| 310 | } /// @todo use ob_start instead |
||
| 311 | $resp = array(); |
||
| 312 | $time = microtime(true); |
||
| 313 | foreach ($msg as $message) { |
||
| 314 | $response = $client->send($message, $timeout, $httpprotocol); |
||
| 315 | $resp[] = $response; |
||
| 316 | |||
| 317 | if (!$response || (is_object($response) && $response->faultCode())) { |
||
| 318 | break; |
||
| 319 | } |
||
| 320 | } |
||
| 321 | $time = microtime(true) - $time; |
||
| 322 | if ($debug) { |
||
| 323 | echo "</div>\n"; |
||
| 324 | } |
||
| 325 | |||
| 326 | if ($response) { |
||
| 327 | if ($response === true) { |
||
| 328 | // we assume that only notification calls can return true instead of a response |
||
| 329 | printf("<h3>%s notification call OK (%.2f secs.)</h3>\n", $protoName, $time); |
||
| 330 | echo(date("d/M/Y:H:i:s\n")); |
||
| 331 | } else if ($response->faultCode()) { |
||
| 332 | // call failed! echo out error msg! |
||
| 333 | //echo '<h2>'.htmlspecialchars($actionname, ENT_COMPAT, $inputcharset).' on server '.htmlspecialchars($server, ENT_COMPAT, $inputcharset).'</h2>'; |
||
| 334 | echo "<h3>$protoName call FAILED!</h3>\n"; |
||
| 335 | echo "<p>Fault code: [" . htmlspecialchars($response->faultCode(), ENT_COMPAT, \PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding) . |
||
| 336 | "] Reason: '" . htmlspecialchars($response->faultString(), ENT_COMPAT, \PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding) . "'</p>\n"; |
||
| 337 | echo(date("d/M/Y:H:i:s\n")); |
||
| 338 | } else { |
||
| 339 | // call succeeded: parse results |
||
| 340 | //echo '<h2>'.htmlspecialchars($actionname, ENT_COMPAT, $inputcharset).' on server '.htmlspecialchars($server, ENT_COMPAT, $inputcharset).'</h2>'; |
||
| 341 | printf("<h3>%s call(s) OK (%.2f secs.)</h3>\n", $protoName, $time); |
||
| 342 | echo(date("d/M/Y:H:i:s\n")); |
||
| 343 | |||
| 344 | switch ($action) { |
||
| 345 | case 'list': |
||
| 346 | |||
| 347 | $v = $response->value(); |
||
| 348 | if ($v->kindOf() == "array") { |
||
| 349 | $max = $v->count(); |
||
| 350 | echo "<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n"; |
||
| 351 | echo "<thead>\n<tr><th>Method ($max)</th><th>Description</th></tr>\n</thead>\n<tbody>\n"; |
||
| 352 | foreach($v as $i => $rec) { |
||
| 353 | if ($i % 2) { |
||
| 354 | $class = ' class="oddrow"'; |
||
| 355 | } else { |
||
| 356 | $class = ' class="evenrow"'; |
||
| 357 | } |
||
| 358 | echo("<tr><td$class>" . htmlspecialchars($rec->scalarval(), ENT_COMPAT, \PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding) . "</td><td$class><form action=\"controller.php\" method=\"get\" target=\"frmcontroller\">" . |
||
| 359 | "<input type=\"hidden\" name=\"host\" value=\"" . htmlspecialchars($host, ENT_COMPAT, $inputcharset) . "\" />" . |
||
| 360 | "<input type=\"hidden\" name=\"port\" value=\"" . htmlspecialchars($port, ENT_COMPAT, $inputcharset) . "\" />" . |
||
| 361 | "<input type=\"hidden\" name=\"path\" value=\"" . htmlspecialchars($path, ENT_COMPAT, $inputcharset) . "\" />" . |
||
| 362 | "<input type=\"hidden\" name=\"id\" value=\"" . htmlspecialchars($id, ENT_COMPAT, $inputcharset) . "\" />" . |
||
| 363 | "<input type=\"hidden\" name=\"debug\" value=\"$debug\" />" . |
||
| 364 | "<input type=\"hidden\" name=\"username\" value=\"" . htmlspecialchars($username, ENT_COMPAT, $inputcharset) . "\" />" . |
||
| 365 | "<input type=\"hidden\" name=\"password\" value=\"" . htmlspecialchars($password, ENT_COMPAT, $inputcharset) . "\" />" . |
||
| 366 | "<input type=\"hidden\" name=\"authtype\" value=\"$authtype\" />" . |
||
| 367 | "<input type=\"hidden\" name=\"verifyhost\" value=\"$verifyhost\" />" . |
||
| 368 | "<input type=\"hidden\" name=\"verifypeer\" value=\"$verifypeer\" />" . |
||
| 369 | "<input type=\"hidden\" name=\"cainfo\" value=\"" . htmlspecialchars($cainfo, ENT_COMPAT, $inputcharset) . "\" />" . |
||
| 370 | "<input type=\"hidden\" name=\"proxy\" value=\"" . htmlspecialchars($proxy, ENT_COMPAT, $inputcharset) . "\" />" . |
||
| 371 | "<input type=\"hidden\" name=\"proxyuser\" value=\"" . htmlspecialchars($proxyuser, ENT_COMPAT, $inputcharset) . "\" />" . |
||
| 372 | "<input type=\"hidden\" name=\"proxypwd\" value=\"" . htmlspecialchars($proxypwd, ENT_COMPAT, $inputcharset) . "\" />" . |
||
| 373 | "<input type=\"hidden\" name=\"responsecompression\" value=\"$responsecompression\" />" . |
||
| 374 | "<input type=\"hidden\" name=\"requestcompression\" value=\"$requestcompression\" />" . |
||
| 375 | "<input type=\"hidden\" name=\"clientcookies\" value=\"" . htmlspecialchars($clientcookies, ENT_COMPAT, $inputcharset) . "\" />" . |
||
| 376 | "<input type=\"hidden\" name=\"protocol\" value=\"$protocol\" />" . |
||
| 377 | "<input type=\"hidden\" name=\"timeout\" value=\"" . htmlspecialchars($timeout, ENT_COMPAT, $inputcharset) . "\" />" . |
||
| 378 | "<input type=\"hidden\" name=\"method\" value=\"" . htmlspecialchars($rec->scalarval(), ENT_COMPAT, \PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding) . "\" />" . |
||
| 379 | "<input type=\"hidden\" name=\"wstype\" value=\"$wstype\" />" . |
||
| 380 | "<input type=\"hidden\" name=\"action\" value=\"describe\" />" . |
||
| 381 | "<input type=\"hidden\" name=\"run\" value=\"now\" />" . |
||
| 382 | "<input type=\"submit\" value=\"Describe\" /></form></td>"); |
||
| 383 | //echo("</tr>\n"); |
||
| 384 | |||
| 385 | // generate the skeleton for method payload per possible tests |
||
| 386 | //$methodpayload="<methodCall>\n<methodName>".$rec->scalarval()."</methodName>\n<params>\n<param><value></value></param>\n</params>\n</methodCall>"; |
||
| 387 | |||
| 388 | /*echo ("<form action=\"{$_SERVER['PHP_SELF']}\" method=\"get\"><td>". |
||
| 389 | "<input type=\"hidden\" name=\"host\" value=\"$host\" />". |
||
| 390 | "<input type=\"hidden\" name=\"port\" value=\"$port\" />". |
||
| 391 | "<input type=\"hidden\" name=\"path\" value=\"$path\" />". |
||
| 392 | "<input type=\"hidden\" name=\"method\" value=\"".$rec->scalarval()."\" />". |
||
| 393 | "<input type=\"hidden\" name=\"methodpayload\" value=\"$payload\" />". |
||
| 394 | "<input type=\"hidden\" name=\"action\" value=\"execute\" />". |
||
| 395 | "<input type=\"submit\" value=\"Test\" /></td></form>");*/ |
||
| 396 | echo("</tr>\n"); |
||
| 397 | } |
||
| 398 | echo "</tbody>\n</table>"; |
||
| 399 | } |
||
| 400 | break; |
||
| 401 | |||
| 402 | case 'describe': |
||
| 403 | |||
| 404 | $r1 = $resp[0]->value(); |
||
| 405 | $r2 = $resp[1]->value(); |
||
| 406 | |||
| 407 | echo "<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n"; |
||
| 408 | echo "<thead>\n<tr><th>Method</th><th>" . htmlspecialchars($method, ENT_COMPAT, $inputcharset) . "</th><th> </th><th> </th></tr>\n</thead>\n<tbody>\n"; |
||
| 409 | $desc = htmlspecialchars($r1->scalarval(), ENT_COMPAT, \PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding); |
||
| 410 | if ($desc == "") { |
||
| 411 | $desc = "-"; |
||
| 412 | } |
||
| 413 | echo "<tr><td class=\"evenrow\">Description</td><td colspan=\"3\" class=\"evenrow\">$desc</td></tr>\n"; |
||
| 414 | |||
| 415 | if ($r2->kindOf() != "array") { |
||
| 416 | echo "<tr><td class=\"oddrow\">Signature</td><td class=\"oddrow\">Unknown</td><td class=\"oddrow\"> </td></tr>\n"; |
||
| 417 | } else { |
||
| 418 | foreach($r2 as $i => $x) { |
||
| 419 | $payload = ""; |
||
| 420 | $alt_payload = ""; |
||
| 421 | if ($i + 1 % 2) { |
||
| 422 | $class = ' class="oddrow"'; |
||
| 423 | } else { |
||
| 424 | $class = ' class="evenrow"'; |
||
| 425 | } |
||
| 426 | echo "<tr><td$class>Signature " . ($i + 1) . "</td><td$class>"; |
||
| 427 | if ($x->kindOf() == "array") { |
||
| 428 | $ret = $x[0]; |
||
| 429 | echo "<code>OUT: " . htmlspecialchars($ret->scalarval(), ENT_COMPAT, \PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding) . "<br />IN: ("; |
||
| 430 | if ($x->count() > 1) { |
||
| 431 | foreach($x as $k => $y) { |
||
| 432 | if ($k == 0) continue; |
||
| 433 | echo htmlspecialchars($y->scalarval(), ENT_COMPAT, \PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding); |
||
| 434 | if ($wstype == 1 || $wstype == 2) { |
||
| 435 | switch($y->scalarval()) { |
||
| 436 | case 'string': |
||
| 437 | case 'dateTime.iso8601': |
||
| 438 | case 'base64': |
||
| 439 | $payload .= '""'; |
||
| 440 | break; |
||
| 441 | case 'i4': |
||
| 442 | case 'i8': |
||
| 443 | case 'int': |
||
| 444 | $payload .= '0'; |
||
| 445 | break; |
||
| 446 | case 'double': |
||
| 447 | $payload .= '0.0'; |
||
| 448 | break; |
||
| 449 | case 'bool': |
||
| 450 | case 'boolean': |
||
| 451 | $payload .= 'true'; |
||
| 452 | break; |
||
| 453 | case 'null': |
||
| 454 | $payload .= 'null'; |
||
| 455 | break; |
||
| 456 | case 'array': |
||
| 457 | $payload .= '[]'; |
||
| 458 | break; |
||
| 459 | case 'struct': |
||
| 460 | $payload .= '{}'; |
||
| 461 | break; |
||
| 462 | default: |
||
| 463 | break; |
||
| 464 | } |
||
| 465 | } else { |
||
| 466 | $type = $y->scalarval(); |
||
| 467 | $payload .= '<param><value>'; |
||
| 468 | switch($type) { |
||
| 469 | case 'undefined': |
||
| 470 | break; |
||
| 471 | case 'null': |
||
| 472 | $type = 'nil'; |
||
| 473 | // fall thru intentionally |
||
| 474 | default: |
||
| 475 | $payload .= '<' . |
||
| 476 | htmlspecialchars($type, ENT_COMPAT, \PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding) . |
||
| 477 | '></' . htmlspecialchars($type, ENT_COMPAT, \PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding) . |
||
| 478 | '>'; |
||
| 479 | } |
||
| 480 | $payload .= "</value></param>\n"; |
||
| 481 | } |
||
| 482 | $alt_payload .= $y->scalarval(); |
||
| 483 | if ($k < $x->count() - 1) { |
||
| 484 | $alt_payload .= ';'; |
||
| 485 | if ($wstype == 1 || $wstype == 2) { |
||
| 486 | $payload .= ', '; |
||
| 487 | } |
||
| 488 | echo ", "; |
||
| 489 | } |
||
| 490 | } |
||
| 491 | } |
||
| 492 | echo ")</code>"; |
||
| 493 | } else { |
||
| 494 | echo 'Unknown'; |
||
| 495 | } |
||
| 496 | echo '</td>'; |
||
| 497 | // button to test this method |
||
| 498 | //$payload="<methodCall>\n<methodName>$method</methodName>\n<params>\n$payload</params>\n</methodCall>"; |
||
| 499 | echo "<td$class><form action=\"controller.php\" target=\"frmcontroller\" method=\"get\">" . |
||
| 500 | "<input type=\"hidden\" name=\"host\" value=\"" . htmlspecialchars($host, ENT_COMPAT, $inputcharset) . "\" />" . |
||
| 501 | "<input type=\"hidden\" name=\"port\" value=\"" . htmlspecialchars($port, ENT_COMPAT, $inputcharset) . "\" />" . |
||
| 502 | "<input type=\"hidden\" name=\"path\" value=\"" . htmlspecialchars($path, ENT_COMPAT, $inputcharset) . "\" />" . |
||
| 503 | "<input type=\"hidden\" name=\"id\" value=\"" . htmlspecialchars($id, ENT_COMPAT, $inputcharset) . "\" />" . |
||
| 504 | "<input type=\"hidden\" name=\"debug\" value=\"$debug\" />" . |
||
| 505 | "<input type=\"hidden\" name=\"username\" value=\"" . htmlspecialchars($username, ENT_COMPAT, $inputcharset) . "\" />" . |
||
| 506 | "<input type=\"hidden\" name=\"password\" value=\"" . htmlspecialchars($password, ENT_COMPAT, $inputcharset) . "\" />" . |
||
| 507 | "<input type=\"hidden\" name=\"authtype\" value=\"$authtype\" />" . |
||
| 508 | "<input type=\"hidden\" name=\"verifyhost\" value=\"$verifyhost\" />" . |
||
| 509 | "<input type=\"hidden\" name=\"verifypeer\" value=\"$verifypeer\" />" . |
||
| 510 | "<input type=\"hidden\" name=\"cainfo\" value=\"" . htmlspecialchars($cainfo, ENT_COMPAT, $inputcharset) . "\" />" . |
||
| 511 | "<input type=\"hidden\" name=\"proxy\" value=\"" . htmlspecialchars($proxy, ENT_COMPAT, $inputcharset) . "\" />" . |
||
| 512 | "<input type=\"hidden\" name=\"proxyuser\" value=\"" . htmlspecialchars($proxyuser, ENT_COMPAT, $inputcharset) . "\" />" . |
||
| 513 | "<input type=\"hidden\" name=\"proxypwd\" value=\"" . htmlspecialchars($proxypwd, ENT_COMPAT, $inputcharset) . "\" />" . |
||
| 514 | "<input type=\"hidden\" name=\"responsecompression\" value=\"$responsecompression\" />" . |
||
| 515 | "<input type=\"hidden\" name=\"requestcompression\" value=\"$requestcompression\" />" . |
||
| 516 | "<input type=\"hidden\" name=\"clientcookies\" value=\"" . htmlspecialchars($clientcookies, ENT_COMPAT, $inputcharset) . "\" />" . |
||
| 517 | "<input type=\"hidden\" name=\"protocol\" value=\"$protocol\" />" . |
||
| 518 | "<input type=\"hidden\" name=\"timeout\" value=\"" . htmlspecialchars($timeout, ENT_COMPAT, $inputcharset) . "\" />" . |
||
| 519 | "<input type=\"hidden\" name=\"method\" value=\"" . htmlspecialchars($method, ENT_COMPAT, $inputcharset) . "\" />" . |
||
| 520 | "<input type=\"hidden\" name=\"methodpayload\" value=\"" . htmlspecialchars($payload, ENT_COMPAT, $inputcharset) . "\" />" . |
||
| 521 | "<input type=\"hidden\" name=\"altmethodpayload\" value=\"" . htmlspecialchars($alt_payload, ENT_COMPAT, $inputcharset) . "\" />" . |
||
| 522 | "<input type=\"hidden\" name=\"wstype\" value=\"$wstype\" />" . |
||
| 523 | "<input type=\"hidden\" name=\"action\" value=\"execute\" />"; |
||
| 524 | //if ($wstype != 1) { |
||
| 525 | echo "<input type=\"submit\" value=\"Load method synopsis\" />"; |
||
| 526 | //} |
||
| 527 | echo "</form></td>\n"; |
||
| 528 | |||
| 529 | echo "<td$class><form action=\"controller.php\" target=\"frmcontroller\" method=\"get\">" . |
||
| 530 | "<input type=\"hidden\" name=\"host\" value=\"" . htmlspecialchars($host, ENT_COMPAT, $inputcharset) . "\" />" . |
||
| 531 | "<input type=\"hidden\" name=\"port\" value=\"" . htmlspecialchars($port, ENT_COMPAT, $inputcharset) . "\" />" . |
||
| 532 | "<input type=\"hidden\" name=\"path\" value=\"" . htmlspecialchars($path, ENT_COMPAT, $inputcharset) . "\" />" . |
||
| 533 | "<input type=\"hidden\" name=\"id\" value=\"" . htmlspecialchars($id, ENT_COMPAT, $inputcharset) . "\" />" . |
||
| 534 | "<input type=\"hidden\" name=\"debug\" value=\"$debug\" />" . |
||
| 535 | "<input type=\"hidden\" name=\"username\" value=\"" . htmlspecialchars($username, ENT_COMPAT, $inputcharset) . "\" />" . |
||
| 536 | "<input type=\"hidden\" name=\"password\" value=\"" . htmlspecialchars($password, ENT_COMPAT, $inputcharset) . "\" />" . |
||
| 537 | "<input type=\"hidden\" name=\"authtype\" value=\"$authtype\" />" . |
||
| 538 | "<input type=\"hidden\" name=\"verifyhost\" value=\"$verifyhost\" />" . |
||
| 539 | "<input type=\"hidden\" name=\"verifypeer\" value=\"$verifypeer\" />" . |
||
| 540 | "<input type=\"hidden\" name=\"cainfo\" value=\"" . htmlspecialchars($cainfo, ENT_COMPAT, $inputcharset) . "\" />" . |
||
| 541 | "<input type=\"hidden\" name=\"proxy\" value=\"" . htmlspecialchars($proxy, ENT_COMPAT, $inputcharset) . "\" />" . |
||
| 542 | "<input type=\"hidden\" name=\"proxyuser\" value=\"" . htmlspecialchars($proxyuser, ENT_COMPAT, $inputcharset) . "\" />" . |
||
| 543 | "<input type=\"hidden\" name=\"proxypwd\" value=\"" . htmlspecialchars($proxypwd, ENT_COMPAT, $inputcharset) . "\" />" . |
||
| 544 | "<input type=\"hidden\" name=\"responsecompression\" value=\"$responsecompression\" />" . |
||
| 545 | "<input type=\"hidden\" name=\"requestcompression\" value=\"$requestcompression\" />" . |
||
| 546 | "<input type=\"hidden\" name=\"clientcookies\" value=\"" . htmlspecialchars($clientcookies, ENT_COMPAT, $inputcharset) . "\" />" . |
||
| 547 | "<input type=\"hidden\" name=\"protocol\" value=\"$protocol\" />" . |
||
| 548 | "<input type=\"hidden\" name=\"timeout\" value=\"" . htmlspecialchars($timeout, ENT_COMPAT, $inputcharset) . "\" />" . |
||
| 549 | "<input type=\"hidden\" name=\"method\" value=\"" . htmlspecialchars($method, ENT_COMPAT, $inputcharset) . "\" />" . |
||
| 550 | "<input type=\"hidden\" name=\"methodsig\" value=\"" . $i . "\" />" . |
||
| 551 | "<input type=\"hidden\" name=\"methodpayload\" value=\"" . htmlspecialchars($payload, ENT_COMPAT, $inputcharset) . "\" />" . |
||
| 552 | "<input type=\"hidden\" name=\"altmethodpayload\" value=\"" . htmlspecialchars($alt_payload, ENT_COMPAT, $inputcharset) . "\" />" . |
||
| 553 | "<input type=\"hidden\" name=\"wstype\" value=\"$wstype\" />" . |
||
| 554 | "<input type=\"hidden\" name=\"action\" value=\"wrap\" />" . |
||
| 555 | "<input type=\"hidden\" name=\"run\" value=\"now\" />" . |
||
| 556 | "<input type=\"submit\" value=\"Generate method call stub code\" />"; |
||
| 557 | echo "</form></td></tr>\n"; |
||
| 558 | } |
||
| 559 | } |
||
| 560 | echo "</tbody>\n</table>"; |
||
| 561 | |||
| 562 | break; |
||
| 563 | |||
| 564 | case 'wrap': |
||
| 565 | $r1 = $resp[0]->value(); |
||
| 566 | $r2 = $resp[1]->value(); |
||
| 567 | if ($r2->kindOf() != "array" || $r2->count() <= $methodsig) { |
||
| 568 | echo "Error: signature unknown\n"; |
||
| 569 | } else { |
||
| 570 | $mdesc = $r1->scalarval(); |
||
| 571 | $encoder = new PhpXmlRpc\Encoder(); |
||
| 572 | $msig = $encoder->decode($r2); |
||
| 573 | $msig = $msig[$methodsig]; |
||
| 574 | $proto = ($protocol == 1) ? 'http11' : ( $protocol == 2 ? 'https' : ( $protocol == 3 ? 'h2' : ( $protocol == 4 ? 'h2c' : '' ) ) ); |
||
| 575 | if ($proxy == '' && $username == '' && !$requestcompression && !$responsecompression && |
||
| 576 | $clientcookies == '') { |
||
| 577 | $opts = 1; // simple client copy in stub code |
||
| 578 | } else { |
||
| 579 | $opts = 0; // complete client copy in stub code |
||
| 580 | } |
||
| 581 | if ($wstype == 1 || $wstype == 2) { |
||
| 582 | $prefix = 'jsonrpc'; |
||
| 583 | } else { |
||
| 584 | $prefix = 'xmlrpc'; |
||
| 585 | } |
||
| 586 | if ($wstype == 1 || $wstype == 2) { |
||
| 587 | $wrapper = new PhpXmlRpc\JsonRpc\Wrapper(); |
||
|
0 ignored issues
–
show
The type
PhpXmlRpc\JsonRpc\Wrapper was not found. Maybe you did not declare it correctly or list all dependencies?
The issue could also be caused by a filter entry in the build configuration.
If the path has been excluded in your configuration, e.g. filter:
dependency_paths: ["lib/*"]
For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths Loading history...
|
|||
| 588 | if ($hasjsonrpc2) { |
||
| 589 | $wrapper->setJsonRpcVersion($wstype == 1 ? \PhpXmlRpc\JsonRpc\PhpJsonRpc::VERSION_1_0 : \PhpXmlRpc\JsonRpc\PhpJsonRpc::VERSION_2_0); |
||
|
0 ignored issues
–
show
The type
PhpXmlRpc\JsonRpc\PhpJsonRpc was not found. Maybe you did not declare it correctly or list all dependencies?
The issue could also be caused by a filter entry in the build configuration.
If the path has been excluded in your configuration, e.g. filter:
dependency_paths: ["lib/*"]
For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths Loading history...
|
|||
| 590 | } |
||
| 591 | } else { |
||
| 592 | $wrapper = new PhpXmlRpc\Wrapper(); |
||
| 593 | } |
||
| 594 | $code = $wrapper->buildWrapMethodSource( |
||
| 595 | $client, |
||
| 596 | $method, |
||
| 597 | array('timeout' => $timeout, 'protocol' => $proto, 'simple_client_copy' => $opts, 'prefix' => $prefix, 'throw_on_fault' => true), |
||
| 598 | str_replace('.', '_', $prefix . '_' . $method), $msig, $mdesc |
||
| 599 | ); |
||
| 600 | //if ($code) |
||
| 601 | //{ |
||
| 602 | echo "<div id=\"phpcode\">\n"; |
||
| 603 | highlight_string("<?php\n" . $code['docstring'] . $code['source']); |
||
| 604 | echo "\n</div>"; |
||
| 605 | //} |
||
| 606 | //else |
||
| 607 | //{ |
||
| 608 | // echo 'Error while building php code stub...'; |
||
| 609 | } |
||
| 610 | |||
| 611 | break; |
||
| 612 | |||
| 613 | case 'execute': |
||
| 614 | echo '<div id="response"><h2>Response:</h2>' . htmlspecialchars($response->serialize()) . '</div>'; |
||
| 615 | break; |
||
| 616 | |||
| 617 | case 'notification': |
||
| 618 | echo '<div id="response"><h2>Response:</h2>' . htmlspecialchars($response->serialize()) . '</div>'; |
||
| 619 | break; |
||
| 620 | |||
| 621 | default: // give a warning |
||
| 622 | } |
||
| 623 | } // if !$response->faultCode() |
||
| 624 | } // if $response |
||
| 625 | } else { |
||
| 626 | // no action taken yet: give some instructions on debugger usage |
||
| 627 | ?> |
||
| 628 | |||
| 629 | <h3>Instructions on usage of the debugger</h3> |
||
| 630 | <b>If the server supports introspection methods `<i>system.listMethods</i>`, `<i>system.methodHelp</i>` and co.</b> |
||
| 631 | <ol> |
||
| 632 | <li>Fill in values for <i>Address</i>, <i>Port</i>, <i>Path</i></li> |
||
| 633 | <li>Run a <i>'List available methods'</i> action against desired server</li> |
||
| 634 | <li>If list of methods appears, click on <i>'Describe method'</i> for desired method</li> |
||
| 635 | <li>To run method: click on <i>'Load method synopsis'</i> for desired method. This will load a skeleton for method call |
||
| 636 | parameters in the form above. Complete all xml-rpc values with appropriate data and click <i>'Execute'</i> |
||
| 637 | </li> |
||
| 638 | </ol> |
||
| 639 | <b>If the server does not support introspection methods</b> |
||
| 640 | <ol> |
||
| 641 | <li>Fill in values for <i>Address</i>, <i>Port</i>, <i>Path</i></li> |
||
| 642 | <li>Select <i>'Execute method'</i></li> |
||
| 643 | <li>Fill in method name and payload - fe. "<param><value><string>hello</string></value></param>" |
||
| 644 | (you can use a wizard to help creating the payload by clicking on the <i>'Edit'</i> link)</li> |
||
| 645 | <li>Click <i>'Execute'</i></li> |
||
| 646 | </ol> |
||
| 647 | <p class="evidence">Use the <i>'Show debug info'</i> switch for troubleshooting.</p> |
||
| 648 | <?php |
||
| 649 | if (!extension_loaded('curl')) { |
||
| 650 | echo "<p class=\"evidence\">You will need to enable the cURL extension to use the HTTPS, HTTP 1.1 and HTTP/2 transports</p>\n"; |
||
| 651 | } |
||
| 652 | ?> |
||
| 653 | |||
| 654 | <h3>Demo server</h3> |
||
| 655 | <p> |
||
| 656 | Server Address: tanoconsulting.com<br/> |
||
| 657 | Path: /sw/xmlrpc/demo/server/server.php |
||
| 658 | </p> |
||
| 659 | |||
| 660 | <h3>Notice</h3> |
||
| 661 | <p>all usernames and passwords entered on the above form will be written to the web server logs of this server. Use |
||
| 662 | with care.</p> |
||
| 663 | |||
| 664 | <h3>Changelog</h3> |
||
| 665 | <ul> |
||
| 666 | <li>2025-10-08: added support for json-rpc 2.0. The debugger now require phpjsonrpc 1.0.0 or later for json-rpc support</li> |
||
| 667 | <li>2023-02-11: display in the top row the version of the libraries in use; made the generated code throw instead |
||
| 668 | of returning a Response object on error; fixes for the json-rpc debugger</li> |
||
| 669 | <li>2022-12-18: fix XSS vulnerability in the debugger; load jsxmlrpc from CDN; minor improvements</li> |
||
| 670 | <li>2022-11-28: allow to use http/2 protocol; two security issues fixed in the underlying library</li> |
||
| 671 | <li>2020-12-11: fix problems with running the debugger on php 8</li> |
||
| 672 | <li>2015-05-30: fix problems with generating method payloads for NIL and Undefined parameters</li> |
||
| 673 | <li>2015-04-19: fix problems with LATIN-1 characters in payload</li> |
||
| 674 | <li>2007-02-20: add visual editor for method payload; allow strings, bools as jsonrpc req id</li> |
||
| 675 | <li>2006-06-26: support building php code stub for calling remote methods</li> |
||
| 676 | <li>2006-05-25: better support for long running queries; check for no-curl installs</li> |
||
| 677 | <li>2006-05-02: added support for JSON-RPC. Note that many interesting json-rpc features are not implemented |
||
| 678 | yet, such as notifications or multicall. |
||
| 679 | </li> |
||
| 680 | <li>2006-04-22: added option for setting custom CA certs to verify peer with in SSLmode</li> |
||
| 681 | <li>2006-03-05: added option for setting Basic/Digest/NTLM auth type</li> |
||
| 682 | <li>2006-01-18: added option echoing to screen xml-rpc request before sending it ('More' debug)</li> |
||
| 683 | <li>2005-10-01: added option for setting cookies to be sent to server</li> |
||
| 684 | <li>2005-08-07: added switches for compression of requests and responses and http 1.1</li> |
||
| 685 | <li>2005-06-27: fixed possible security breach in parsing malformed xml</li> |
||
| 686 | <li>2005-06-24: fixed error with calling methods having parameters...</li> |
||
| 687 | </ul> |
||
| 688 | <?php |
||
| 689 | |||
| 690 | } |
||
| 691 | ?> |
||
| 692 | </body> |
||
| 693 | </html> |
||
| 694 |