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
![]() |
|||
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 ![]() |
|||
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 ![]() |
|||
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 | <ol> |
||
631 | <li>Run a 'list available methods' action against desired server</li> |
||
632 | <li>If list of methods appears, click on 'describe method' for desired method</li> |
||
633 | <li>To run method: click on 'load method synopsis' for desired method. This will load a skeleton for method call |
||
634 | parameters in the form above. Complete all xml-rpc values with appropriate data and click 'Execute' |
||
635 | </li> |
||
636 | </ol> |
||
637 | <?php |
||
638 | if (!extension_loaded('curl')) { |
||
639 | 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"; |
||
640 | } |
||
641 | ?> |
||
642 | |||
643 | <h3>Example</h3> |
||
644 | <p> |
||
645 | Server Address: gggeek.altervista.org<br/> |
||
646 | Path: /sw/xmlrpc/demo/server/server.php |
||
647 | </p> |
||
648 | |||
649 | <h3>Notice</h3> |
||
650 | <p>all usernames and passwords entered on the above form will be written to the web server logs of this server. Use |
||
651 | with care.</p> |
||
652 | |||
653 | <h3>Changelog</h3> |
||
654 | <ul> |
||
655 | <li>2025-10-08: added support for json-rpc 2.0. The debugger now require phpjsonrpc 1.0.0-beta3 or later for json-rpc support</li> |
||
656 | <li>2023-02-11: display in the top row the version of the libraries in use; made the generated code throw instead |
||
657 | of returning a Response object on error; fixes for the json-rpc debugger</li> |
||
658 | <li>2022-12-18: fix XSS vulnerability in the debugger; load jsxmlrpc from CDN; minor improvements</li> |
||
659 | <li>2022-11-28: allow to use http/2 protocol; two security issues fixed in the underlying library</li> |
||
660 | <li>2020-12-11: fix problems with running the debugger on php 8</li> |
||
661 | <li>2015-05-30: fix problems with generating method payloads for NIL and Undefined parameters</li> |
||
662 | <li>2015-04-19: fix problems with LATIN-1 characters in payload</li> |
||
663 | <li>2007-02-20: add visual editor for method payload; allow strings, bools as jsonrpc req id</li> |
||
664 | <li>2006-06-26: support building php code stub for calling remote methods</li> |
||
665 | <li>2006-05-25: better support for long running queries; check for no-curl installs</li> |
||
666 | <li>2006-05-02: added support for JSON-RPC. Note that many interesting json-rpc features are not implemented |
||
667 | yet, such as notifications or multicall. |
||
668 | </li> |
||
669 | <li>2006-04-22: added option for setting custom CA certs to verify peer with in SSLmode</li> |
||
670 | <li>2006-03-05: added option for setting Basic/Digest/NTLM auth type</li> |
||
671 | <li>2006-01-18: added option echoing to screen xml-rpc request before sending it ('More' debug)</li> |
||
672 | <li>2005-10-01: added option for setting cookies to be sent to server</li> |
||
673 | <li>2005-08-07: added switches for compression of requests and responses and http 1.1</li> |
||
674 | <li>2005-06-27: fixed possible security breach in parsing malformed xml</li> |
||
675 | <li>2005-06-24: fixed error with calling methods having parameters...</li> |
||
676 | </ul> |
||
677 | <?php |
||
678 | |||
679 | } |
||
680 | ?> |
||
681 | </body> |
||
682 | </html> |
||
683 |