add favicon to debugger
[plcapi.git] / debugger / action.php
1 <?php
2 /**
3  * @author Gaetano Giunta
4  * @copyright (C) 2005-2021 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 ?>
15 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
16     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
17 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
18 <head>
19     <link rel="icon" type="image/vnd.microsoft.icon" href="favicon.ico">
20     <title><?php if (defined('DEFAULT_WSTYPE') && DEFAULT_WSTYPE == 1) echo 'JSONRPC'; else echo 'XMLRPC'; ?> Debugger</title>
21     <meta name="robots" content="index,nofollow"/>
22     <style type="text/css">
23         <!--
24         body {
25             border-top: 1px solid gray;
26             padding: 1em;
27             font-family: Verdana, Arial, Helvetica;
28             font-size: 8pt;
29         }
30
31         h3 {
32             font-size: 9.5pt;
33         }
34
35         h2 {
36             font-size: 12pt;
37         }
38
39         .dbginfo {
40             padding: 1em;
41             background-color: #EEEEEE;
42             border: 1px dashed silver;
43             font-family: monospace;
44         }
45
46         #response {
47             padding: 1em;
48             margin-top: 1em;
49             background-color: #DDDDDD;
50             border: 1px solid gray;
51             white-space: pre;
52             font-family: monospace;
53         }
54
55         table {
56             padding: 2px;
57             margin-top: 1em;
58         }
59
60         th {
61             background-color: navy;
62             color: white;
63             padding: 0.5em;
64         }
65
66         td {
67             padding: 0.5em;
68             font-family: monospace;
69         }
70
71         td form {
72             margin: 0;
73         }
74
75         .oddrow {
76             background-color: #EEEEEE;
77         }
78
79         .evidence {
80             color: blue;
81         }
82
83         #phpcode {
84             background-color: #EEEEEE;
85             padding: 1em;
86             margin-top: 1em;
87         }
88
89         -->
90     </style>
91 </head>
92 <body>
93 <?php
94
95 include __DIR__ . '/common.php';
96
97 if ($action) {
98
99     // make sure the script waits long enough for the call to complete...
100     if ($timeout) {
101         set_time_limit($timeout + 10);
102     }
103
104     if ($wstype == 1) {
105         //@include 'jsonrpc.inc';
106         if (!class_exists('\PhpXmlRpc\JsonRpc\Client')) {
107             die('Error: to debug the jsonrpc protocol the phpxmlrpc/jsonrpc package is needed');
108         }
109         $clientClass = '\PhpXmlRpc\JsonRpc\Client';
110         $requestClass = '\PhpXmlRpc\JsonRpc\Request';
111         $protoName = 'JSONRPC';
112     } else {
113         $clientClass = '\PhpXmlRpc\Client';
114         $requestClass = '\PhpXmlRpc\Request';
115         $protoName = 'XMLRPC';
116     }
117
118     if ($port != "") {
119         $client = new $clientClass($path, $host, $port);
120         $server = "$host:$port$path";
121     } else {
122         $client = new $clientClass($path, $host);
123         $server = "$host$path";
124     }
125     if ($protocol == 2) {
126         $server = 'https://' . $server;
127     } else {
128         $server = 'http://' . $server;
129     }
130     if ($proxy != '') {
131         $pproxy = explode(':', $proxy);
132         if (count($pproxy) > 1) {
133             $pport = $pproxy[1];
134         } else {
135             $pport = 8080;
136         }
137         $client->setProxy($pproxy[0], $pport, $proxyuser, $proxypwd);
138     }
139
140     if ($protocol == 2) {
141         $client->setSSLVerifyPeer($verifypeer);
142         $client->setSSLVerifyHost($verifyhost);
143         if ($cainfo) {
144             $client->setCaCertificate($cainfo);
145         }
146         $httpprotocol = 'https';
147     } elseif ($protocol == 1) {
148         $httpprotocol = 'http11';
149     } else {
150         $httpprotocol = 'http';
151     }
152
153     if ($username) {
154         $client->setCredentials($username, $password, $authtype);
155     }
156
157     $client->setDebug($debug);
158
159     switch ($requestcompression) {
160         case 0:
161             $client->request_compression = '';
162             break;
163         case 1:
164             $client->request_compression = 'gzip';
165             break;
166         case 2:
167             $client->request_compression = 'deflate';
168             break;
169     }
170
171     switch ($responsecompression) {
172         case 0:
173             $client->accepted_compression = '';
174             break;
175         case 1:
176             $client->accepted_compression = array('gzip');
177             break;
178         case 2:
179             $client->accepted_compression = array('deflate');
180             break;
181         case 3:
182             $client->accepted_compression = array('gzip', 'deflate');
183             break;
184     }
185
186     $cookies = explode(',', $clientcookies);
187     foreach ($cookies as $cookie) {
188         if (strpos($cookie, '=')) {
189             $cookie = explode('=', $cookie);
190             $client->setCookie(trim($cookie[0]), trim(@$cookie[1]));
191         }
192     }
193
194     $msg = array();
195     switch ($action) {
196         // fall thru intentionally
197         case 'describe':
198         case 'wrap':
199             $msg[0] = new $requestClass('system.methodHelp', array(), $id);
200             $msg[0]->addparam(new PhpXmlRpc\Value($method));
201             $msg[1] = new $requestClass('system.methodSignature', array(), (int)$id + 1);
202             $msg[1]->addparam(new PhpXmlRpc\Value($method));
203             $actionname = 'Description of method "' . $method . '"';
204             break;
205         case 'list':
206             $msg[0] = new $requestClass('system.listMethods', array(), $id);
207             $actionname = 'List of available methods';
208             break;
209         case 'execute':
210             if (!payload_is_safe($payload)) {
211                 die("Tsk tsk tsk, please stop it or I will have to call in the cops!");
212             }
213             $msg[0] = new $requestClass($method, array(), $id);
214             // hack! build xml payload by hand
215             if ($wstype == 1) {
216                 $msg[0]->payload = "{\n" .
217                     '"method": "' . $method . "\",\n\"params\": [" .
218                     $payload .
219                     "\n],\n\"id\": ";
220                 // fix: if user gave an empty string, use NULL, or we'll break json syntax
221                 if ($id == "") {
222                     $msg[0]->payload .= "null\n}";
223                 } else {
224                     if (is_numeric($id) || $id == 'false' || $id == 'true' || $id == 'null') {
225                         $msg[0]->payload .= "$id\n}";
226                     } else {
227                         $msg[0]->payload .= "\"$id\"\n}";
228                     }
229                 }
230             } else {
231                 $msg[0]->payload = $msg[0]->xml_header($inputcharset) .
232                     '<methodName>' . $method . "</methodName>\n<params>" .
233                     $payload .
234                     "</params>\n" . $msg[0]->xml_footer();
235             }
236             $actionname = 'Execution of method ' . $method;
237             break;
238         default: // give a warning
239             $actionname = '[ERROR: unknown action] "' . $action . '"';
240     }
241
242     // Before calling execute, echo out brief description of action taken + date and time ???
243     // this gives good user feedback for long-running methods...
244     echo '<h2>' . htmlspecialchars($actionname, ENT_COMPAT, $inputcharset) . ' on server ' . htmlspecialchars($server, ENT_COMPAT, $inputcharset) . " ...</h2>\n";
245     flush();
246
247     $response = null;
248     // execute method(s)
249     if ($debug) {
250         echo '<div class="dbginfo"><h2>Debug info:</h2>';
251     }  /// @todo use ob_start instead
252     $resp = array();
253     $time = microtime(true);
254     foreach ($msg as $message) {
255         // catch errors: for older xmlrpc libs, send does not return by ref
256         @$response = $client->send($message, $timeout, $httpprotocol);
257         $resp[] = $response;
258         if (!$response || $response->faultCode()) {
259             break;
260         }
261     }
262     $time = microtime(true) - $time;
263     if ($debug) {
264         echo "</div>\n";
265     }
266
267     if ($response) {
268         if ($response->faultCode()) {
269             // call failed! echo out error msg!
270             //echo '<h2>'.htmlspecialchars($actionname, ENT_COMPAT, $inputcharset).' on server '.htmlspecialchars($server, ENT_COMPAT, $inputcharset).'</h2>';
271             echo "<h3>$protoName call FAILED!</h3>\n";
272             echo "<p>Fault code: [" . htmlspecialchars($response->faultCode(), ENT_COMPAT, \PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding) .
273                 "] Reason: '" . htmlspecialchars($response->faultString(), ENT_COMPAT, \PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding) . "'</p>\n";
274             echo(strftime("%d/%b/%Y:%H:%M:%S\n"));
275         } else {
276             // call succeeded: parse results
277             //echo '<h2>'.htmlspecialchars($actionname, ENT_COMPAT, $inputcharset).' on server '.htmlspecialchars($server, ENT_COMPAT, $inputcharset).'</h2>';
278             printf("<h3>%s call(s) OK (%.2f secs.)</h3>\n", $protoName, $time);
279             echo(strftime("%d/%b/%Y:%H:%M:%S\n"));
280
281             switch ($action) {
282                 case 'list':
283
284                     $v = $response->value();
285                     if ($v->kindOf() == "array") {
286                         $max = $v->count();
287                         echo "<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n";
288                         echo "<thead>\n<tr><th>Method ($max)</th><th>Description</th></tr>\n</thead>\n<tbody>\n";
289                         foreach($v as $i => $rec) {
290                             if ($i % 2) {
291                                 $class = ' class="oddrow"';
292                             } else {
293                                 $class = ' class="evenrow"';
294                             }
295                             echo("<tr><td$class>" . htmlspecialchars($rec->scalarval(), ENT_COMPAT, \PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding) . "</td><td$class><form action=\"controller.php\" method=\"get\" target=\"frmcontroller\">" .
296                                 "<input type=\"hidden\" name=\"host\" value=\"" . htmlspecialchars($host, ENT_COMPAT, $inputcharset) . "\" />" .
297                                 "<input type=\"hidden\" name=\"port\" value=\"" . htmlspecialchars($port, ENT_COMPAT, $inputcharset) . "\" />" .
298                                 "<input type=\"hidden\" name=\"path\" value=\"" . htmlspecialchars($path, ENT_COMPAT, $inputcharset) . "\" />" .
299                                 "<input type=\"hidden\" name=\"id\" value=\"" . htmlspecialchars($id, ENT_COMPAT, $inputcharset) . "\" />" .
300                                 "<input type=\"hidden\" name=\"debug\" value=\"$debug\" />" .
301                                 "<input type=\"hidden\" name=\"username\" value=\"" . htmlspecialchars($username, ENT_COMPAT, $inputcharset) . "\" />" .
302                                 "<input type=\"hidden\" name=\"password\" value=\"" . htmlspecialchars($password, ENT_COMPAT, $inputcharset) . "\" />" .
303                                 "<input type=\"hidden\" name=\"authtype\" value=\"$authtype\" />" .
304                                 "<input type=\"hidden\" name=\"verifyhost\" value=\"$verifyhost\" />" .
305                                 "<input type=\"hidden\" name=\"verifypeer\" value=\"$verifypeer\" />" .
306                                 "<input type=\"hidden\" name=\"cainfo\" value=\"" . htmlspecialchars($cainfo, ENT_COMPAT, $inputcharset) . "\" />" .
307                                 "<input type=\"hidden\" name=\"proxy\" value=\"" . htmlspecialchars($proxy, ENT_COMPAT, $inputcharset) . "\" />" .
308                                 "<input type=\"hidden\" name=\"proxyuser\" value=\"" . htmlspecialchars($proxyuser, ENT_COMPAT, $inputcharset) . "\" />" .
309                                 "<input type=\"hidden\" name=\"proxypwd\" value=\"" . htmlspecialchars($proxypwd, ENT_COMPAT, $inputcharset) . "\" />" .
310                                 "<input type=\"hidden\" name=\"responsecompression\" value=\"$responsecompression\" />" .
311                                 "<input type=\"hidden\" name=\"requestcompression\" value=\"$requestcompression\" />" .
312                                 "<input type=\"hidden\" name=\"clientcookies\" value=\"" . htmlspecialchars($clientcookies, ENT_COMPAT, $inputcharset) . "\" />" .
313                                 "<input type=\"hidden\" name=\"protocol\" value=\"$protocol\" />" .
314                                 "<input type=\"hidden\" name=\"timeout\" value=\"" . htmlspecialchars($timeout, ENT_COMPAT, $inputcharset) . "\" />" .
315                                 "<input type=\"hidden\" name=\"method\" value=\"" . htmlspecialchars($rec->scalarval(), ENT_COMPAT, \PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding) . "\" />" .
316                                 "<input type=\"hidden\" name=\"wstype\" value=\"$wstype\" />" .
317                                 "<input type=\"hidden\" name=\"action\" value=\"describe\" />" .
318                                 "<input type=\"hidden\" name=\"run\" value=\"now\" />" .
319                                 "<input type=\"submit\" value=\"Describe\" /></form></td>");
320                             //echo("</tr>\n");
321
322                             // generate the skeleton for method payload per possible tests
323                             //$methodpayload="<methodCall>\n<methodName>".$rec->scalarval()."</methodName>\n<params>\n<param><value></value></param>\n</params>\n</methodCall>";
324
325                             /*echo ("<form action=\"{$_SERVER['PHP_SELF']}\" method=\"get\"><td>".
326                               "<input type=\"hidden\" name=\"host\" value=\"$host\" />".
327                               "<input type=\"hidden\" name=\"port\" value=\"$port\" />".
328                               "<input type=\"hidden\" name=\"path\" value=\"$path\" />".
329                               "<input type=\"hidden\" name=\"method\" value=\"".$rec->scalarval()."\" />".
330                               "<input type=\"hidden\" name=\"methodpayload\" value=\"$payload\" />".
331                               "<input type=\"hidden\" name=\"action\" value=\"execute\" />".
332                               "<input type=\"submit\" value=\"Test\" /></td></form>");*/
333                             echo("</tr>\n");
334                         }
335                         echo "</tbody>\n</table>";
336                     }
337                     break;
338
339                 case 'describe':
340
341                     $r1 = $resp[0]->value();
342                     $r2 = $resp[1]->value();
343
344                     echo "<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n";
345                     echo "<thead>\n<tr><th>Method</th><th>" . htmlspecialchars($method, ENT_COMPAT, $inputcharset) . "</th><th>&nbsp;</th><th>&nbsp;</th></tr>\n</thead>\n<tbody>\n";
346                     $desc = htmlspecialchars($r1->scalarval(), ENT_COMPAT, \PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding);
347                     if ($desc == "") {
348                         $desc = "-";
349                     }
350                     echo "<tr><td class=\"evenrow\">Description</td><td colspan=\"3\" class=\"evenrow\">$desc</td></tr>\n";
351
352                     if ($r2->kindOf() != "array") {
353                         echo "<tr><td class=\"oddrow\">Signature</td><td class=\"oddrow\">Unknown</td><td class=\"oddrow\">&nbsp;</td></tr>\n";
354                     } else {
355                         foreach($r2 as $i => $x) {
356                             $payload = "";
357                             $alt_payload = "";
358                             if ($i + 1 % 2) {
359                                 $class = ' class="oddrow"';
360                             } else {
361                                 $class = ' class="evenrow"';
362                             }
363                             echo "<tr><td$class>Signature&nbsp;" . ($i + 1) . "</td><td$class>";
364                             if ($x->kindOf() == "array") {
365                                 $ret = $x[0];
366                                 echo "<code>OUT:&nbsp;" . htmlspecialchars($ret->scalarval(), ENT_COMPAT, \PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding) . "<br />IN: (";
367                                 if ($x->count() > 1) {
368                                     foreach($x as $k => $y) {
369                                         if ($k == 0) continue;
370                                         echo htmlspecialchars($y->scalarval(), ENT_COMPAT, \PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding);
371                                         if ($wstype != 1) {
372                                             $type = $y->scalarval();
373                                             $payload .= '<param><value>';
374                                             switch($type) {
375                                                 case 'undefined':
376                                                     break;
377                                                 case 'null';
378                                                     $type = 'nil';
379                                                     // fall thru intentionally
380                                                 default:
381                                                     $payload .= '<' .
382                                                         htmlspecialchars($type, ENT_COMPAT, \PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding) .
383                                                         '></' . htmlspecialchars($type, ENT_COMPAT, \PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding) .
384                                                         '>';
385                                             }
386                                             $payload .= "</value></param>\n";
387                                         }
388                                         $alt_payload .= $y->scalarval();
389                                         if ($k < $x->count() - 1) {
390                                             $alt_payload .= ';';
391                                             echo ", ";
392                                         }
393                                     }
394                                 }
395                                 echo ")</code>";
396                             } else {
397                                 echo 'Unknown';
398                             }
399                             echo '</td>';
400                             // button to test this method
401                             //$payload="<methodCall>\n<methodName>$method</methodName>\n<params>\n$payload</params>\n</methodCall>";
402                             echo "<td$class><form action=\"controller.php\" target=\"frmcontroller\" method=\"get\">" .
403                                 "<input type=\"hidden\" name=\"host\" value=\"" . htmlspecialchars($host, ENT_COMPAT, $inputcharset) . "\" />" .
404                                 "<input type=\"hidden\" name=\"port\" value=\"" . htmlspecialchars($port, ENT_COMPAT, $inputcharset) . "\" />" .
405                                 "<input type=\"hidden\" name=\"path\" value=\"" . htmlspecialchars($path, ENT_COMPAT, $inputcharset) . "\" />" .
406                                 "<input type=\"hidden\" name=\"id\" value=\"" . htmlspecialchars($id, ENT_COMPAT, $inputcharset) . "\" />" .
407                                 "<input type=\"hidden\" name=\"debug\" value=\"$debug\" />" .
408                                 "<input type=\"hidden\" name=\"username\" value=\"" . htmlspecialchars($username, ENT_COMPAT, $inputcharset) . "\" />" .
409                                 "<input type=\"hidden\" name=\"password\" value=\"" . htmlspecialchars($password, ENT_COMPAT, $inputcharset) . "\" />" .
410                                 "<input type=\"hidden\" name=\"authtype\" value=\"$authtype\" />" .
411                                 "<input type=\"hidden\" name=\"verifyhost\" value=\"$verifyhost\" />" .
412                                 "<input type=\"hidden\" name=\"verifypeer\" value=\"$verifypeer\" />" .
413                                 "<input type=\"hidden\" name=\"cainfo\" value=\"" . htmlspecialchars($cainfo, ENT_COMPAT, $inputcharset) . "\" />" .
414                                 "<input type=\"hidden\" name=\"proxy\" value=\"" . htmlspecialchars($proxy, ENT_COMPAT, $inputcharset) . "\" />" .
415                                 "<input type=\"hidden\" name=\"proxyuser\" value=\"" . htmlspecialchars($proxyuser, ENT_COMPAT, $inputcharset) . "\" />" .
416                                 "<input type=\"hidden\" name=\"proxypwd\" value=\"" . htmlspecialchars($proxypwd, ENT_COMPAT, $inputcharset) . "\" />" .
417                                 "<input type=\"hidden\" name=\"responsecompression\" value=\"$responsecompression\" />" .
418                                 "<input type=\"hidden\" name=\"requestcompression\" value=\"$requestcompression\" />" .
419                                 "<input type=\"hidden\" name=\"clientcookies\" value=\"" . htmlspecialchars($clientcookies, ENT_COMPAT, $inputcharset) . "\" />" .
420                                 "<input type=\"hidden\" name=\"protocol\" value=\"$protocol\" />" .
421                                 "<input type=\"hidden\" name=\"timeout\" value=\"" . htmlspecialchars($timeout, ENT_COMPAT, $inputcharset) . "\" />" .
422                                 "<input type=\"hidden\" name=\"method\" value=\"" . htmlspecialchars($method, ENT_COMPAT, $inputcharset) . "\" />" .
423                                 "<input type=\"hidden\" name=\"methodpayload\" value=\"" . htmlspecialchars($payload, ENT_COMPAT, $inputcharset) . "\" />" .
424                                 "<input type=\"hidden\" name=\"altmethodpayload\" value=\"" . htmlspecialchars($alt_payload, ENT_COMPAT, $inputcharset) . "\" />" .
425                                 "<input type=\"hidden\" name=\"wstype\" value=\"$wstype\" />" .
426                                 "<input type=\"hidden\" name=\"action\" value=\"execute\" />";
427                             if ($wstype != 1) {
428                                 echo "<input type=\"submit\" value=\"Load method synopsis\" />";
429                             }
430                             echo "</form></td>\n";
431
432                             echo "<td$class><form action=\"controller.php\" target=\"frmcontroller\" method=\"get\">" .
433                                 "<input type=\"hidden\" name=\"host\" value=\"" . htmlspecialchars($host, ENT_COMPAT, $inputcharset) . "\" />" .
434                                 "<input type=\"hidden\" name=\"port\" value=\"" . htmlspecialchars($port, ENT_COMPAT, $inputcharset) . "\" />" .
435                                 "<input type=\"hidden\" name=\"path\" value=\"" . htmlspecialchars($path, ENT_COMPAT, $inputcharset) . "\" />" .
436                                 "<input type=\"hidden\" name=\"id\" value=\"" . htmlspecialchars($id, ENT_COMPAT, $inputcharset) . "\" />" .
437                                 "<input type=\"hidden\" name=\"debug\" value=\"$debug\" />" .
438                                 "<input type=\"hidden\" name=\"username\" value=\"" . htmlspecialchars($username, ENT_COMPAT, $inputcharset) . "\" />" .
439                                 "<input type=\"hidden\" name=\"password\" value=\"" . htmlspecialchars($password, ENT_COMPAT, $inputcharset) . "\" />" .
440                                 "<input type=\"hidden\" name=\"authtype\" value=\"$authtype\" />" .
441                                 "<input type=\"hidden\" name=\"verifyhost\" value=\"$verifyhost\" />" .
442                                 "<input type=\"hidden\" name=\"verifypeer\" value=\"$verifypeer\" />" .
443                                 "<input type=\"hidden\" name=\"cainfo\" value=\"" . htmlspecialchars($cainfo, ENT_COMPAT, $inputcharset) . "\" />" .
444                                 "<input type=\"hidden\" name=\"proxy\" value=\"" . htmlspecialchars($proxy, ENT_COMPAT, $inputcharset) . "\" />" .
445                                 "<input type=\"hidden\" name=\"proxyuser\" value=\"" . htmlspecialchars($proxyuser, ENT_COMPAT, $inputcharset) . "\" />" .
446                                 "<input type=\"hidden\" name=\"proxypwd\" value=\"" . htmlspecialchars($proxypwd, ENT_COMPAT, $inputcharset) . "\" />" .
447                                 "<input type=\"hidden\" name=\"responsecompression\" value=\"$responsecompression\" />" .
448                                 "<input type=\"hidden\" name=\"requestcompression\" value=\"$requestcompression\" />" .
449                                 "<input type=\"hidden\" name=\"clientcookies\" value=\"" . htmlspecialchars($clientcookies, ENT_COMPAT, $inputcharset) . "\" />" .
450                                 "<input type=\"hidden\" name=\"protocol\" value=\"$protocol\" />" .
451                                 "<input type=\"hidden\" name=\"timeout\" value=\"" . htmlspecialchars($timeout, ENT_COMPAT, $inputcharset) . "\" />" .
452                                 "<input type=\"hidden\" name=\"method\" value=\"" . htmlspecialchars($method, ENT_COMPAT, $inputcharset) . "\" />" .
453                                 "<input type=\"hidden\" name=\"methodsig\" value=\"" . $i . "\" />" .
454                                 "<input type=\"hidden\" name=\"methodpayload\" value=\"" . htmlspecialchars($payload, ENT_COMPAT, $inputcharset) . "\" />" .
455                                 "<input type=\"hidden\" name=\"altmethodpayload\" value=\"" . htmlspecialchars($alt_payload, ENT_COMPAT, $inputcharset) . "\" />" .
456                                 "<input type=\"hidden\" name=\"wstype\" value=\"$wstype\" />" .
457                                 "<input type=\"hidden\" name=\"run\" value=\"now\" />" .
458                                 "<input type=\"hidden\" name=\"action\" value=\"wrap\" />" .
459                                 "<input type=\"submit\" value=\"Generate method call stub code\" />";
460                             echo "</form></td></tr>\n";
461                         }
462                     }
463                     echo "</tbody>\n</table>";
464
465                     break;
466
467                 case 'wrap':
468                     $r1 = $resp[0]->value();
469                     $r2 = $resp[1]->value();
470                     if ($r2->kindOf() != "array" || $r2->count() <= $methodsig) {
471                         echo "Error: signature unknown\n";
472                     } else {
473                         $mdesc = $r1->scalarval();
474                         $encoder = new PhpXmlRpc\Encoder();
475                         $msig = $encoder->decode($r2);
476                         $msig = $msig[$methodsig];
477                         $proto = $protocol == 2 ? 'https' : ( $protocol == 1 ? 'http11' : '' );
478                         if ($proxy == '' && $username == '' && !$requestcompression && !$responsecompression &&
479                             $clientcookies == ''
480                         ) {
481                             $opts = 1; // simple client copy in stub code
482                         } else {
483                             $opts = 0; // complete client copy in stub code
484                         }
485                         if ($wstype == 1) {
486                             $prefix = 'jsonrpc';
487                         } else {
488                             $prefix = 'xmlrpc';
489                         }
490                         $wrapper = new PhpXmlRpc\Wrapper();
491                         $code = $wrapper->buildWrapMethodSource($client, $method, array('timeout' => $timeout, 'protocol' => $proto, 'simple_client_copy' => $opts, 'prefix' => $prefix), str_replace('.', '_', $prefix . '_' . $method), $msig, $mdesc);
492                         //if ($code)
493                         //{
494                         echo "<div id=\"phpcode\">\n";
495                         highlight_string("<?php\n" . $code['docstring'] . $code['source'] . '?>');
496                         echo "\n</div>";
497                         //}
498                         //else
499                         //{
500                         //  echo 'Error while building php code stub...';
501                     }
502
503                     break;
504
505                 case 'execute':
506                     echo '<div id="response"><h2>Response:</h2>' . htmlspecialchars($response->serialize()) . '</div>';
507                     break;
508
509                 default: // give a warning
510             }
511         } // if !$response->faultCode()
512     } // if $response
513 } else {
514     // no action taken yet: give some instructions on debugger usage
515     ?>
516
517     <h3>Instructions on usage of the debugger</h3>
518     <ol>
519         <li>Run a 'list available methods' action against desired server</li>
520         <li>If list of methods appears, click on 'describe method' for desired method</li>
521         <li>To run method: click on 'load method synopsis' for desired method. This will load a skeleton for method call
522             parameters in the form above. Complete all xmlrpc values with appropriate data and click 'Execute'
523         </li>
524     </ol>
525     <?php
526     if (!extension_loaded('curl')) {
527         echo "<p class=\"evidence\">You will need to enable the CURL extension to use the HTTPS and HTTP 1.1 transports</p>\n";
528     }
529     ?>
530
531     <h3>Example</h3>
532     <p>
533         Server Address: phpxmlrpc.sourceforge.net<br/>
534         Path: /server.php
535     </p>
536
537     <h3>Notice</h3>
538     <p>all usernames and passwords entered on the above form will be written to the web server logs of this server. Use
539         with care.</p>
540
541     <h3>Changelog</h3>
542     <ul>
543         <li>2020-12-11: fix problems with running the debugger on php 8</li>
544         <li>2015-05-30: fix problems with generating method payloads for NIL and Undefined parameters</li>
545         <li>2015-04-19: fix problems with LATIN-1 characters in payload</li>
546         <li>2007-02-20: add visual editor for method payload; allow strings, bools as jsonrpc msg id</li>
547         <li>2006-06-26: support building php code stub for calling remote methods</li>
548         <li>2006-05-25: better support for long running queries; check for no-curl installs</li>
549         <li>2006-05-02: added support for JSON-RPC. Note that many interesting json-rpc features are not implemented
550             yet, such as notifications or multicall.
551         </li>
552         <li>2006-04-22: added option for setting custom CA certs to verify peer with in SSLmode</li>
553         <li>2006-03-05: added option for setting Basic/Digest/NTLM auth type</li>
554         <li>2006-01-18: added option echoing to screen xmlrpc request before sending it ('More' debug)</li>
555         <li>2005-10-01: added option for setting cookies to be sent to server</li>
556         <li>2005-08-07: added switches for compression of requests and responses and http 1.1</li>
557         <li>2005-06-27: fixed possible security breach in parsing malformed xml</li>
558         <li>2005-06-24: fixed error with calling methods having parameters...</li>
559     </ul>
560 <?php
561
562 }
563 ?>
564 </body>
565 </html>