3 * Demo server for xmlrpc library.
5 * Implements a lot of webservices, including a suite of services used for
6 * interoperability testing (validator1 methods), and some whose only purpose
7 * is to be used for unit-testing the library.
9 * Please do not copy this file verbatim into your production server.
12 require_once __DIR__ . "/_prepend.php";
17 * Used to test usage of object methods in dispatch maps and in wrapper code.
19 class xmlrpcServerMethodsContainer
22 * Method used to test logging of php warnings generated by user functions.
23 * @param PhpXmlRpc\Request $req
24 * @return PhpXmlRpc\Response
26 public function phpWarningGenerator($req)
28 $a = $undefinedVariable; // this triggers a warning in E_ALL mode, since $undefinedVariable is undefined
29 return new PhpXmlRpc\Response(new Value(1, Value::$xmlrpcBoolean));
33 * Method used to test catching of exceptions in the server.
34 * @param PhpXmlRpc\Request $req
37 public function exceptionGenerator($req)
39 throw new Exception("it's just a test", 1);
45 public function debugMessageGenerator($msg)
47 PhpXmlRpc\Server::xmlrpc_debugmsg($msg);
51 * A PHP version of the state-number server. Send me an integer and i'll sell you a state.
52 * Used to test wrapping of PHP methods into xmlrpc methods.
58 public static function findState($num)
60 return inner_findstate($num);
64 * Returns an instance of stdClass.
65 * Used to test wrapping of PHP objects with class preservation
67 public function returnObject()
69 $obj = new stdClass();
70 $obj->hello = 'world';
75 // a PHP version of the state-number server
76 // send me an integer and i'll sell you a state
79 "Alabama", "Alaska", "Arizona", "Arkansas", "California",
80 "Colorado", "Columbia", "Connecticut", "Delaware", "Florida",
81 "Georgia", "Hawaii", "Idaho", "Illinois", "Indiana", "Iowa", "Kansas",
82 "Kentucky", "Louisiana", "Maine", "Maryland", "Massachusetts", "Michigan",
83 "Minnesota", "Mississippi", "Missouri", "Montana", "Nebraska", "Nevada",
84 "New Hampshire", "New Jersey", "New Mexico", "New York", "North Carolina",
85 "North Dakota", "Ohio", "Oklahoma", "Oregon", "Pennsylvania", "Rhode Island",
86 "South Carolina", "South Dakota", "Tennessee", "Texas", "Utah", "Vermont",
87 "Virginia", "Washington", "West Virginia", "Wisconsin", "Wyoming",
90 $findstate_sig = array(array(Value::$xmlrpcString, Value::$xmlrpcInt));
91 $findstate_doc = 'When passed an integer between 1 and 51 returns the
92 name of a US state, where the integer is the index of that state name
93 in an alphabetic order.';
95 function findState($req)
100 // get the first param
101 $sno = $req->getParam(0);
103 // param must be there and of the correct type: server object does the validation for us
105 // extract the value of the state number
106 $snv = $sno->scalarval();
107 // look it up in our array (zero-based)
108 if (isset($stateNames[$snv - 1])) {
109 $stateName = $stateNames[$snv - 1];
111 // not there, so complain
112 $err = "I don't have a state for the index '" . $snv . "'";
115 // if we generated an error, create an error return response
117 return new PhpXmlRpc\Response(0, PhpXmlRpc\PhpXmlRpc::$xmlrpcerruser, $err);
119 // otherwise, we create the right response with the state name
120 return new PhpXmlRpc\Response(new Value($stateName));
125 * Inner code of the state-number server.
126 * Used to test wrapping of PHP functions into xmlrpc methods.
128 * @param integer $stateNo the state number
130 * @return string the name of the state (or error description)
132 * @throws Exception if state is not found
134 function inner_findstate($stateNo)
138 if (isset($stateNames[$stateNo - 1])) {
139 return $stateNames[$stateNo - 1];
141 // not, there so complain
142 throw new Exception("I don't have a state for the index '" . $stateNo . "'", PhpXmlRpc\PhpXmlRpc::$xmlrpcerruser);
146 $wrapper = new PhpXmlRpc\Wrapper();
148 $findstate2_sig = $wrapper->wrapPhpFunction('inner_findstate');
150 $findstate3_sig = $wrapper->wrapPhpFunction(array('xmlrpcServerMethodsContainer', 'findState'));
152 $obj = new xmlrpcServerMethodsContainer();
153 $findstate4_sig = $wrapper->wrapPhpFunction(array($obj, 'findstate'));
155 $findstate5_sig = $wrapper->wrapPhpFunction('xmlrpcServerMethodsContainer::findState', '', array('return_source' => true));
156 eval($findstate5_sig['source']);
158 $findstate6_sig = $wrapper->wrapPhpFunction('inner_findstate', '', array('return_source' => true));
159 eval($findstate6_sig['source']);
161 $findstate7_sig = $wrapper->wrapPhpFunction(array('xmlrpcServerMethodsContainer', 'findState'), '', array('return_source' => true));
162 eval($findstate7_sig['source']);
164 $obj = new xmlrpcServerMethodsContainer();
165 $findstate8_sig = $wrapper->wrapPhpFunction(array($obj, 'findstate'), '', array('return_source' => true));
166 eval($findstate8_sig['source']);
168 $findstate9_sig = $wrapper->wrapPhpFunction('xmlrpcServerMethodsContainer::findState', '', array('return_source' => true));
169 eval($findstate9_sig['source']);
171 $findstate10_sig = array(
172 "function" => function ($req) { return findState($req); },
173 "signature" => $findstate_sig,
174 "docstring" => $findstate_doc,
177 $findstate11_sig = $wrapper->wrapPhpFunction(function ($stateNo) { return inner_findstate($stateNo); });
179 $c = new xmlrpcServerMethodsContainer;
180 $moreSignatures = $wrapper->wrapPhpClass($c, array('prefix' => 'tests.', 'method_type' => 'all'));
182 $returnObj_sig = $wrapper->wrapPhpFunction(array($c, 'returnObject'), '', array('encode_php_objs' => true));
184 // used to test signatures with NULL params
185 $findstate12_sig = array(
186 array(Value::$xmlrpcString, Value::$xmlrpcInt, Value::$xmlrpcNull),
187 array(Value::$xmlrpcString, Value::$xmlrpcNull, Value::$xmlrpcInt),
190 function findStateWithNulls($req)
192 $a = $req->getParam(0);
193 $b = $req->getParam(1);
195 if ($a->scalartyp() == Value::$xmlrpcNull)
196 return new PhpXmlRpc\Response(new Value(inner_findstate($b->scalarval())));
198 return new PhpXmlRpc\Response(new Value(inner_findstate($a->scalarval())));
201 $addtwo_sig = array(array(Value::$xmlrpcInt, Value::$xmlrpcInt, Value::$xmlrpcInt));
202 $addtwo_doc = 'Add two integers together and return the result';
203 function addTwo($req)
205 $s = $req->getParam(0);
206 $t = $req->getParam(1);
208 return new PhpXmlRpc\Response(new Value($s->scalarval() + $t->scalarval(), Value::$xmlrpcInt));
211 $addtwodouble_sig = array(array(Value::$xmlrpcDouble, Value::$xmlrpcDouble, Value::$xmlrpcDouble));
212 $addtwodouble_doc = 'Add two doubles together and return the result';
213 function addTwoDouble($req)
215 $s = $req->getParam(0);
216 $t = $req->getParam(1);
218 return new PhpXmlRpc\Response(new Value($s->scalarval() + $t->scalarval(), Value::$xmlrpcDouble));
221 $stringecho_sig = array(array(Value::$xmlrpcString, Value::$xmlrpcString));
222 $stringecho_doc = 'Accepts a string parameter, returns the string.';
223 function stringEcho($req)
225 // just sends back a string
226 return new PhpXmlRpc\Response(new Value($req->getParam(0)->scalarval()));
229 $echoback_sig = array(array(Value::$xmlrpcString, Value::$xmlrpcString));
230 $echoback_doc = 'Accepts a string parameter, returns the entire incoming payload';
231 function echoBack($req)
233 // just sends back a string with what i got sent to me, just escaped, that's all
234 $s = "I got the following message:\n" . $req->serialize();
236 return new PhpXmlRpc\Response(new Value($s));
239 $echosixtyfour_sig = array(array(Value::$xmlrpcString, Value::$xmlrpcBase64));
240 $echosixtyfour_doc = 'Accepts a base64 parameter and returns it decoded as a string';
241 function echoSixtyFour($req)
243 // Accepts an encoded value, but sends it back as a normal string.
244 // This is to test that base64 encoding is working as expected
245 $incoming = $req->getParam(0);
247 return new PhpXmlRpc\Response(new Value($incoming->scalarval(), Value::$xmlrpcString));
250 $bitflipper_sig = array(array(Value::$xmlrpcArray, Value::$xmlrpcArray));
251 $bitflipper_doc = 'Accepts an array of booleans, and returns them inverted';
252 function bitFlipper($req)
254 $v = $req->getParam(0);
255 $rv = new Value(array(), Value::$xmlrpcArray);
258 if ($b->scalarval()) {
259 $rv[] = new Value(false, Value::$xmlrpcBoolean);
261 $rv[] = new Value(true, Value::$xmlrpcBoolean);
265 return new PhpXmlRpc\Response($rv);
270 // send me an array of structs thus:
277 // and I'll return it to you in sorted order
279 function agesorter_compare($a, $b)
281 global $agesorter_arr;
283 // don't even ask me _why_ these come padded with hyphens, I couldn't tell you :p
284 $a = str_replace("-", "", $a);
285 $b = str_replace("-", "", $b);
287 if ($agesorter_arr[$a] == $agesorter_arr[$b]) {
291 return ($agesorter_arr[$a] > $agesorter_arr[$b]) ? -1 : 1;
294 $agesorter_sig = array(array(Value::$xmlrpcArray, Value::$xmlrpcArray));
295 $agesorter_doc = 'Send this method an array of [string, int] structs, eg:
302 And the array will be returned with the entries sorted by their numbers.
304 function ageSorter($req)
306 global $agesorter_arr, $s;
308 PhpXmlRpc\Server::xmlrpc_debugmsg("Entering 'agesorter'");
310 $sno = $req->getParam(0);
311 // error string for [if|when] things go wrong
315 $max = $sno->count();
316 PhpXmlRpc\Server::xmlrpc_debugmsg("Found $max array elements");
317 foreach ($sno as $i => $rec) {
318 if ($rec->kindOf() != "struct") {
319 $err = "Found non-struct in array at element $i";
322 // extract name and age from struct
325 // $n and $a are xmlrpcvals,
326 // so get the scalarval from them
327 $agar[$n->scalarval()] = $a->scalarval();
330 // create the output value
331 $v = new Value(array(), Value::$xmlrpcArray);
333 $agesorter_arr = $agar;
334 // hack, must make global as uksort() won't
335 // allow us to pass any other auxiliary information
336 uksort($agesorter_arr, 'agesorter_compare');
337 foreach($agesorter_arr as $key => $val) {
338 // recreate each struct element
341 "name" => new Value($key),
342 "age" => new Value($val, "int")
349 return new PhpXmlRpc\Response(0, PhpXmlRpc\PhpXmlRpc::$xmlrpcerruser, $err);
351 return new PhpXmlRpc\Response($v);
355 // signature and instructions, place these in the dispatch map
356 $mailsend_sig = array(array(
357 Value::$xmlrpcBoolean, Value::$xmlrpcString, Value::$xmlrpcString,
358 Value::$xmlrpcString, Value::$xmlrpcString, Value::$xmlrpcString,
359 Value::$xmlrpcString, Value::$xmlrpcString,
361 $mailsend_doc = 'mail.send(recipient, subject, text, sender, cc, bcc, mimetype)<br/>
362 recipient, cc, and bcc are strings, comma-separated lists of email addresses, as described above.<br/>
363 subject is a string, the subject of the message.<br/>
364 sender is a string, it\'s the email address of the person sending the message. This string can not be
365 a comma-separated list, it must contain a single email address only.<br/>
366 text is a string, it contains the body of the message.<br/>
367 mimetype, a string, is a standard MIME type, for example, text/plain.
369 // WARNING; this functionality depends on the sendmail -t option
370 // it may not work with Windows machines properly; particularly
371 // the Bcc option. Sneak on your friends at your own risk!
372 function mailSend($req)
376 $mTo = $req->getParam(0);
377 $mSub = $req->getParam(1);
378 $mBody = $req->getParam(2);
379 $mFrom = $req->getParam(3);
380 $mCc = $req->getParam(4);
381 $mBcc = $req->getParam(5);
382 $mMime = $req->getParam(6);
384 if ($mTo->scalarval() == "") {
385 $err = "Error, no 'To' field specified";
388 if ($mFrom->scalarval() == "") {
389 $err = "Error, no 'From' field specified";
392 $msgHdr = "From: " . $mFrom->scalarval() . "\n";
393 $msgHdr .= "To: " . $mTo->scalarval() . "\n";
395 if ($mCc->scalarval() != "") {
396 $msgHdr .= "Cc: " . $mCc->scalarval() . "\n";
398 if ($mBcc->scalarval() != "") {
399 $msgHdr .= "Bcc: " . $mBcc->scalarval() . "\n";
401 if ($mMime->scalarval() != "") {
402 $msgHdr .= "Content-type: " . $mMime->scalarval() . "\n";
404 $msgHdr .= "X-Mailer: XML-RPC for PHP mailer 1.0";
412 $err = "Error, could not send the mail.";
417 return new PhpXmlRpc\Response(0, PhpXmlRpc\PhpXmlRpc::$xmlrpcerruser, $err);
419 return new PhpXmlRpc\Response(new Value(true, Value::$xmlrpcBoolean));
423 $getallheaders_sig = array(array(Value::$xmlrpcStruct));
424 $getallheaders_doc = 'Returns a struct containing all the HTTP headers received with the request. Provides limited functionality with IIS';
425 function getAllHeaders_xmlrpc($req)
427 $encoder = new PhpXmlRpc\Encoder();
429 if (function_exists('getallheaders')) {
430 return new PhpXmlRpc\Response($encoder->encode(getallheaders()));
433 // IIS: poor man's version of getallheaders
434 foreach ($_SERVER as $key => $val) {
435 if (strpos($key, 'HTTP_') === 0) {
436 $key = ucfirst(str_replace('_', '-', strtolower(substr($key, 5))));
437 $headers[$key] = $val;
441 return new PhpXmlRpc\Response($encoder->encode($headers));
445 $setcookies_sig = array(array(Value::$xmlrpcInt, Value::$xmlrpcStruct));
446 $setcookies_doc = 'Sends to client a response containing a single \'1\' digit, and sets to it http cookies as received in the request (array of structs describing a cookie)';
447 function setCookies($req)
449 $encoder = new PhpXmlRpc\Encoder();
450 $cookies = $req->getParam(0);
451 foreach ($cookies as $name => $value) {
452 $cookieDesc = $encoder->decode($value);
453 setcookie($name, @$cookieDesc['value'], @$cookieDesc['expires'], @$cookieDesc['path'], @$cookieDesc['domain'], @$cookieDesc['secure']);
456 return new PhpXmlRpc\Response(new Value(1, Value::$xmlrpcInt));
459 $getcookies_sig = array(array(Value::$xmlrpcStruct));
460 $getcookies_doc = 'Sends to client a response containing all http cookies as received in the request (as struct)';
461 function getCookies($req)
463 $encoder = new PhpXmlRpc\Encoder();
464 return new PhpXmlRpc\Response($encoder->encode($_COOKIE));
467 $v1_arrayOfStructs_sig = array(array(Value::$xmlrpcInt, Value::$xmlrpcArray));
468 $v1_arrayOfStructs_doc = 'This handler takes a single parameter, an array of structs, each of which contains at least three elements named moe, larry and curly, all <i4>s. Your handler must add all the struct elements named curly and return the result.';
469 function v1_arrayOfStructs($req)
471 $sno = $req->getParam(0);
473 foreach ($sno as $str) {
474 foreach ($str as $key => $val) {
475 if ($key == "curly") {
476 $numCurly += $val->scalarval();
481 return new PhpXmlRpc\Response(new Value($numCurly, Value::$xmlrpcInt));
484 $v1_easyStruct_sig = array(array(Value::$xmlrpcInt, Value::$xmlrpcStruct));
485 $v1_easyStruct_doc = 'This handler takes a single parameter, a struct, containing at least three elements named moe, larry and curly, all <i4>s. Your handler must add the three numbers and return the result.';
486 function v1_easyStruct($req)
488 $sno = $req->getParam(0);
490 $larry = $sno["larry"];
491 $curly = $sno["curly"];
492 $num = $moe->scalarval() + $larry->scalarval() + $curly->scalarval();
494 return new PhpXmlRpc\Response(new Value($num, Value::$xmlrpcInt));
497 $v1_echoStruct_sig = array(array(Value::$xmlrpcStruct, Value::$xmlrpcStruct));
498 $v1_echoStruct_doc = 'This handler takes a single parameter, a struct. Your handler must return the struct.';
499 function v1_echoStruct($req)
501 $sno = $req->getParam(0);
503 return new PhpXmlRpc\Response($sno);
506 $v1_manyTypes_sig = array(array(
507 Value::$xmlrpcArray, Value::$xmlrpcInt, Value::$xmlrpcBoolean,
508 Value::$xmlrpcString, Value::$xmlrpcDouble, Value::$xmlrpcDateTime,
509 Value::$xmlrpcBase64,
511 $v1_manyTypes_doc = 'This handler takes six parameters, and returns an array containing all the parameters.';
512 function v1_manyTypes($req)
514 return new PhpXmlRpc\Response(new Value(
527 $v1_moderateSizeArrayCheck_sig = array(array(Value::$xmlrpcString, Value::$xmlrpcArray));
528 $v1_moderateSizeArrayCheck_doc = 'This handler takes a single parameter, which is an array containing between 100 and 200 elements. Each of the items is a string, your handler must return a string containing the concatenated text of the first and last elements.';
529 function v1_moderateSizeArrayCheck($req)
531 $ar = $req->getParam(0);
534 $last = $ar[$sz - 1];
536 return new PhpXmlRpc\Response(new Value($first->scalarval() .
537 $last->scalarval(), Value::$xmlrpcString));
540 $v1_simpleStructReturn_sig = array(array(Value::$xmlrpcStruct, Value::$xmlrpcInt));
541 $v1_simpleStructReturn_doc = 'This handler takes one parameter, and returns a struct containing three elements, times10, times100 and times1000, the result of multiplying the number by 10, 100 and 1000.';
542 function v1_simpleStructReturn($req)
544 $sno = $req->getParam(0);
545 $v = $sno->scalarval();
547 return new PhpXmlRpc\Response(new Value(
549 "times10" => new Value($v * 10, Value::$xmlrpcInt),
550 "times100" => new Value($v * 100, Value::$xmlrpcInt),
551 "times1000" => new Value($v * 1000, Value::$xmlrpcInt)
557 $v1_nestedStruct_sig = array(array(Value::$xmlrpcInt, Value::$xmlrpcStruct));
558 $v1_nestedStruct_doc = 'This handler takes a single parameter, a struct, that models a daily calendar. At the top level, there is one struct for each year. Each year is broken down into months, and months into days. Most of the days are empty in the struct you receive, but the entry for April 1, 2000 contains a least three elements named moe, larry and curly, all <i4>s. Your handler must add the three numbers and return the result.';
559 function v1_nestedStruct($req)
561 $sno = $req->getParam(0);
563 $twoK = $sno["2000"];
564 $april = $twoK["04"];
565 $fools = $april["01"];
566 $curly = $fools["curly"];
567 $larry = $fools["larry"];
568 $moe = $fools["moe"];
570 return new PhpXmlRpc\Response(new Value($curly->scalarval() + $larry->scalarval() + $moe->scalarval(), Value::$xmlrpcInt));
573 $v1_countTheEntities_sig = array(array(Value::$xmlrpcStruct, Value::$xmlrpcString));
574 $v1_countTheEntities_doc = 'This handler takes a single parameter, a string, that contains any number of predefined entities, namely <, >, & \' and ".<BR>Your handler must return a struct that contains five fields, all numbers: ctLeftAngleBrackets, ctRightAngleBrackets, ctAmpersands, ctApostrophes, ctQuotes.';
575 function v1_countTheEntities($req)
577 $sno = $req->getParam(0);
578 $str = $sno->scalarval();
584 for ($i = 0; $i < strlen($str); $i++) {
585 $c = substr($str, $i, 1);
607 return new PhpXmlRpc\Response(new Value(
609 "ctLeftAngleBrackets" => new Value($lt, Value::$xmlrpcInt),
610 "ctRightAngleBrackets" => new Value($gt, Value::$xmlrpcInt),
611 "ctAmpersands" => new Value($amp, Value::$xmlrpcInt),
612 "ctApostrophes" => new Value($ap, Value::$xmlrpcInt),
613 "ctQuotes" => new Value($qu, Value::$xmlrpcInt)
619 // trivial interop tests
620 // http://www.xmlrpc.com/stories/storyReader$1636
622 $i_echoString_sig = array(array(Value::$xmlrpcString, Value::$xmlrpcString));
623 $i_echoString_doc = "Echoes string.";
625 $i_echoStringArray_sig = array(array(Value::$xmlrpcArray, Value::$xmlrpcArray));
626 $i_echoStringArray_doc = "Echoes string array.";
628 $i_echoInteger_sig = array(array(Value::$xmlrpcInt, Value::$xmlrpcInt));
629 $i_echoInteger_doc = "Echoes integer.";
631 $i_echoIntegerArray_sig = array(array(Value::$xmlrpcArray, Value::$xmlrpcArray));
632 $i_echoIntegerArray_doc = "Echoes integer array.";
634 $i_echoFloat_sig = array(array(Value::$xmlrpcDouble, Value::$xmlrpcDouble));
635 $i_echoFloat_doc = "Echoes float.";
637 $i_echoFloatArray_sig = array(array(Value::$xmlrpcArray, Value::$xmlrpcArray));
638 $i_echoFloatArray_doc = "Echoes float array.";
640 $i_echoStruct_sig = array(array(Value::$xmlrpcStruct, Value::$xmlrpcStruct));
641 $i_echoStruct_doc = "Echoes struct.";
643 $i_echoStructArray_sig = array(array(Value::$xmlrpcArray, Value::$xmlrpcArray));
644 $i_echoStructArray_doc = "Echoes struct array.";
646 $i_echoValue_doc = "Echoes any value back.";
647 $i_echoValue_sig = array(array(Value::$xmlrpcValue, Value::$xmlrpcValue));
649 $i_echoBase64_sig = array(array(Value::$xmlrpcBase64, Value::$xmlrpcBase64));
650 $i_echoBase64_doc = "Echoes base64.";
652 $i_echoDate_sig = array(array(Value::$xmlrpcDateTime, Value::$xmlrpcDateTime));
653 $i_echoDate_doc = "Echoes dateTime.";
655 function i_echoParam($req)
657 $s = $req->getParam(0);
659 return new PhpXmlRpc\Response($s);
662 function i_echoString($req)
664 return i_echoParam($req);
667 function i_echoInteger($req)
669 return i_echoParam($req);
672 function i_echoFloat($req)
674 return i_echoParam($req);
677 function i_echoStruct($req)
679 return i_echoParam($req);
682 function i_echoStringArray($req)
684 return i_echoParam($req);
687 function i_echoIntegerArray($req)
689 return i_echoParam($req);
692 function i_echoFloatArray($req)
694 return i_echoParam($req);
697 function i_echoStructArray($req)
699 return i_echoParam($req);
702 function i_echoValue($req)
704 return i_echoParam($req);
707 function i_echoBase64($req)
709 return i_echoParam($req);
712 function i_echoDate($req)
714 return i_echoParam($req);
717 $i_whichToolkit_sig = array(array(Value::$xmlrpcStruct));
718 $i_whichToolkit_doc = "Returns a struct containing the following strings: toolkitDocsUrl, toolkitName, toolkitVersion, toolkitOperatingSystem.";
720 function i_whichToolkit($req)
722 global $SERVER_SOFTWARE;
724 "toolkitDocsUrl" => "http://phpxmlrpc.sourceforge.net/",
725 "toolkitName" => PhpXmlRpc\PhpXmlRpc::$xmlrpcName,
726 "toolkitVersion" => PhpXmlRpc\PhpXmlRpc::$xmlrpcVersion,
727 "toolkitOperatingSystem" => isset($SERVER_SOFTWARE) ? $SERVER_SOFTWARE : $_SERVER['SERVER_SOFTWARE'],
730 $encoder = new PhpXmlRpc\Encoder();
731 return new PhpXmlRpc\Response($encoder->encode($ret));
734 $object = new xmlrpcServerMethodsContainer();
736 "examples.getStateName" => array(
737 "function" => "findState",
738 "signature" => $findstate_sig,
739 "docstring" => $findstate_doc,
741 "examples.sortByAge" => array(
742 "function" => "ageSorter",
743 "signature" => $agesorter_sig,
744 "docstring" => $agesorter_doc,
746 "examples.addtwo" => array(
747 "function" => "addTwo",
748 "signature" => $addtwo_sig,
749 "docstring" => $addtwo_doc,
751 "examples.addtwodouble" => array(
752 "function" => "addTwoDouble",
753 "signature" => $addtwodouble_sig,
754 "docstring" => $addtwodouble_doc,
756 "examples.stringecho" => array(
757 "function" => "stringEcho",
758 "signature" => $stringecho_sig,
759 "docstring" => $stringecho_doc,
761 "examples.echo" => array(
762 "function" => "echoBack",
763 "signature" => $echoback_sig,
764 "docstring" => $echoback_doc,
766 "examples.decode64" => array(
767 "function" => "echoSixtyFour",
768 "signature" => $echosixtyfour_sig,
769 "docstring" => $echosixtyfour_doc,
771 "examples.invertBooleans" => array(
772 "function" => "bitFlipper",
773 "signature" => $bitflipper_sig,
774 "docstring" => $bitflipper_doc,
776 // signature omitted on purpose
777 "tests.generatePHPWarning" => array(
778 "function" => array($object, "phpWarningGenerator"),
780 // signature omitted on purpose
781 "tests.raiseException" => array(
782 "function" => array($object, "exceptionGenerator"),
784 // Greek word 'kosme'. NB: NOT a valid ISO8859 string!
785 // NB: we can only register this when setting internal encoding to UTF-8, or it will break system.listMethods
786 "tests.utf8methodname." . 'κόσμε' => array(
787 "function" => "stringEcho",
788 "signature" => $stringecho_sig,
789 "docstring" => $stringecho_doc,
791 /*"tests.iso88591methodname." . chr(224) . chr(252) . chr(232) => array(
792 "function" => "stringEcho",
793 "signature" => $stringecho_sig,
794 "docstring" => $stringecho_doc,
796 "examples.getallheaders" => array(
797 "function" => 'getAllHeaders_xmlrpc',
798 "signature" => $getallheaders_sig,
799 "docstring" => $getallheaders_doc,
801 "examples.setcookies" => array(
802 "function" => 'setCookies',
803 "signature" => $setcookies_sig,
804 "docstring" => $setcookies_doc,
806 "examples.getcookies" => array(
807 "function" => 'getCookies',
808 "signature" => $getcookies_sig,
809 "docstring" => $getcookies_doc,
811 "mail.send" => array(
812 "function" => "mailSend",
813 "signature" => $mailsend_sig,
814 "docstring" => $mailsend_doc,
816 "validator1.arrayOfStructsTest" => array(
817 "function" => "v1_arrayOfStructs",
818 "signature" => $v1_arrayOfStructs_sig,
819 "docstring" => $v1_arrayOfStructs_doc,
821 "validator1.easyStructTest" => array(
822 "function" => "v1_easyStruct",
823 "signature" => $v1_easyStruct_sig,
824 "docstring" => $v1_easyStruct_doc,
826 "validator1.echoStructTest" => array(
827 "function" => "v1_echoStruct",
828 "signature" => $v1_echoStruct_sig,
829 "docstring" => $v1_echoStruct_doc,
831 "validator1.manyTypesTest" => array(
832 "function" => "v1_manyTypes",
833 "signature" => $v1_manyTypes_sig,
834 "docstring" => $v1_manyTypes_doc,
836 "validator1.moderateSizeArrayCheck" => array(
837 "function" => "v1_moderateSizeArrayCheck",
838 "signature" => $v1_moderateSizeArrayCheck_sig,
839 "docstring" => $v1_moderateSizeArrayCheck_doc,
841 "validator1.simpleStructReturnTest" => array(
842 "function" => "v1_simpleStructReturn",
843 "signature" => $v1_simpleStructReturn_sig,
844 "docstring" => $v1_simpleStructReturn_doc,
846 "validator1.nestedStructTest" => array(
847 "function" => "v1_nestedStruct",
848 "signature" => $v1_nestedStruct_sig,
849 "docstring" => $v1_nestedStruct_doc,
851 "validator1.countTheEntities" => array(
852 "function" => "v1_countTheEntities",
853 "signature" => $v1_countTheEntities_sig,
854 "docstring" => $v1_countTheEntities_doc,
856 "interopEchoTests.echoString" => array(
857 "function" => "i_echoString",
858 "signature" => $i_echoString_sig,
859 "docstring" => $i_echoString_doc,
861 "interopEchoTests.echoStringArray" => array(
862 "function" => "i_echoStringArray",
863 "signature" => $i_echoStringArray_sig,
864 "docstring" => $i_echoStringArray_doc,
866 "interopEchoTests.echoInteger" => array(
867 "function" => "i_echoInteger",
868 "signature" => $i_echoInteger_sig,
869 "docstring" => $i_echoInteger_doc,
871 "interopEchoTests.echoIntegerArray" => array(
872 "function" => "i_echoIntegerArray",
873 "signature" => $i_echoIntegerArray_sig,
874 "docstring" => $i_echoIntegerArray_doc,
876 "interopEchoTests.echoFloat" => array(
877 "function" => "i_echoFloat",
878 "signature" => $i_echoFloat_sig,
879 "docstring" => $i_echoFloat_doc,
881 "interopEchoTests.echoFloatArray" => array(
882 "function" => "i_echoFloatArray",
883 "signature" => $i_echoFloatArray_sig,
884 "docstring" => $i_echoFloatArray_doc,
886 "interopEchoTests.echoStruct" => array(
887 "function" => "i_echoStruct",
888 "signature" => $i_echoStruct_sig,
889 "docstring" => $i_echoStruct_doc,
891 "interopEchoTests.echoStructArray" => array(
892 "function" => "i_echoStructArray",
893 "signature" => $i_echoStructArray_sig,
894 "docstring" => $i_echoStructArray_doc,
896 "interopEchoTests.echoValue" => array(
897 "function" => "i_echoValue",
898 "signature" => $i_echoValue_sig,
899 "docstring" => $i_echoValue_doc,
901 "interopEchoTests.echoBase64" => array(
902 "function" => "i_echoBase64",
903 "signature" => $i_echoBase64_sig,
904 "docstring" => $i_echoBase64_doc,
906 "interopEchoTests.echoDate" => array(
907 "function" => "i_echoDate",
908 "signature" => $i_echoDate_sig,
909 "docstring" => $i_echoDate_doc,
911 "interopEchoTests.whichToolkit" => array(
912 "function" => "i_whichToolkit",
913 "signature" => $i_whichToolkit_sig,
914 "docstring" => $i_whichToolkit_doc,
917 'tests.getStateName.2' => $findstate2_sig,
918 'tests.getStateName.3' => $findstate3_sig,
919 'tests.getStateName.4' => $findstate4_sig,
920 'tests.getStateName.5' => $findstate5_sig,
921 'tests.getStateName.6' => $findstate6_sig,
922 'tests.getStateName.7' => $findstate7_sig,
923 'tests.getStateName.8' => $findstate8_sig,
924 'tests.getStateName.9' => $findstate9_sig,
925 'tests.getStateName.10' => $findstate10_sig,
926 'tests.getStateName.11' => $findstate11_sig,
928 'tests.getStateName.12' => array(
929 "function" => "findStateWithNulls",
930 "signature" => $findstate12_sig,
931 "docstring" => $findstate_doc,
934 'tests.returnPhpObject' => $returnObj_sig,
937 $signatures = array_merge($signatures, $moreSignatures);
939 // Enable support for the NULL extension
940 PhpXmlRpc\PhpXmlRpc::$xmlrpc_null_extension = true;
942 $s = new PhpXmlRpc\Server($signatures, false);
944 $s->compress_response = true;
946 // Out-of-band information: let the client manipulate the server operations.
947 // We do this to help the testsuite script: do not reproduce in production!
948 if (isset($_GET['RESPONSE_ENCODING'])) {
949 $s->response_charset_encoding = $_GET['RESPONSE_ENCODING'];
951 if (isset($_GET['DETECT_ENCODINGS'])) {
952 PhpXmlRpc\PhpXmlRpc::$xmlrpc_detectencodings = $_GET['DETECT_ENCODINGS'];
954 if (isset($_GET['EXCEPTION_HANDLING'])) {
955 $s->exception_handling = $_GET['EXCEPTION_HANDLING'];
957 if (isset($_GET['FORCE_AUTH'])) {
958 // We implement both Basic and Digest auth in php to avoid having to set it up in a vhost.
959 // Code taken from php.net
960 // NB: we do NOT check for valid credentials!
961 if ($_GET['FORCE_AUTH'] == 'Basic') {
962 if (!isset($_SERVER['PHP_AUTH_USER']) && !isset($_SERVER['REMOTE_USER']) && !isset($_SERVER['REDIRECT_REMOTE_USER'])) {
963 header('HTTP/1.0 401 Unauthorized');
964 header('WWW-Authenticate: Basic realm="Phpxmlrpc Basic Realm"');
965 die('Text visible if user hits Cancel button');
967 } elseif ($_GET['FORCE_AUTH'] == 'Digest') {
968 if (empty($_SERVER['PHP_AUTH_DIGEST'])) {
969 header('HTTP/1.1 401 Unauthorized');
970 header('WWW-Authenticate: Digest realm="Phpxmlrpc Digest Realm",qop="auth",nonce="'.uniqid().'",opaque="'.md5('Phpxmlrpc Digest Realm').'"');
971 die('Text visible if user hits Cancel button');
977 // That should do all we need!
979 require_once __DIR__ . "/_append.php";