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