first commit

This commit is contained in:
2026-02-07 09:46:32 +08:00
commit 5fcd5dc646
443 changed files with 89466 additions and 0 deletions

View File

@@ -0,0 +1,92 @@
<?php
/**
* @author JoakimLofgren
*/
use PhpXmlRpc\Helper\Charset;
/**
* Test conversion between encodings
*
* For Windows if you want to test the output use Consolas font
* and run the following in cmd:
* chcp 28591 (latin1)
* chcp 65001 (utf8)
*/
class CharsetTest extends PHPUnit_Framework_TestCase
{
// Consolas font should render these properly
protected $runes = "ᚠᛇᚻ᛫ᛒᛦᚦ᛫ᚠᚱᚩᚠᚢᚱ᛫ᚠᛁᚱᚪ᛫ᚷᛖᚻᚹᛦᛚᚳᚢᛗ";
protected $greek = "Τὴ γλῶσσα μοῦ ἔδωσαν ἑλληνικὴ";
protected $russian = "Река неслася; бедный чёлн";
protected $chinese = "我能吞下玻璃而不伤身体。";
protected $latinString;
protected function setUp()
{
// construct a latin string with all chars (except control ones)
$this->latinString = "\n\r\t";
for($i = 32; $i < 127; $i++) {
$this->latinString .= chr($i);
}
for($i = 160; $i < 256; $i++) {
$this->latinString .= chr($i);
}
}
protected function utfToLatin($data)
{
return Charset::instance()->encodeEntities(
$data,
'UTF-8',
'ISO-8859-1'
);
}
public function testUtf8ToLatin1All()
{
/*$this->assertEquals(
'ISO-8859-1',
mb_detect_encoding($this->latinString, 'ISO-8859-1, UTF-8, WINDOWS-1251, ASCII', true),
'Setup latinString is not ISO-8859-1 encoded...'
);*/
$string = utf8_encode($this->latinString);
$encoded = $this->utfToLatin($string);
$this->assertEquals(str_replace(array('&', '"', "'", '<', '>'), array('&amp;', '&quot;', '&apos;', '&lt;', '&gt;'), $this->latinString), $encoded);
}
public function testUtf8ToLatin1EuroSymbol()
{
$string = 'a.b.c.å.ä.ö.€.';
$encoded = $this->utfToLatin($string);
$this->assertEquals(utf8_decode('a.b.c.å.ä.ö.&#8364;.'), $encoded);
}
public function testUtf8ToLatin1Runes()
{
$string = $this->runes;
$encoded = $this->utfToLatin($string);
$this->assertEquals('&#5792;&#5831;&#5819;&#5867;&#5842;&#5862;&#5798;&#5867;&#5792;&#5809;&#5801;&#5792;&#5794;&#5809;&#5867;&#5792;&#5825;&#5809;&#5802;&#5867;&#5815;&#5846;&#5819;&#5817;&#5862;&#5850;&#5811;&#5794;&#5847;', $encoded);
}
public function testUtf8ToLatin1Greek()
{
$string = $this->greek;
$encoded = $this->utfToLatin($string);
$this->assertEquals('&#932;&#8052; &#947;&#955;&#8182;&#963;&#963;&#945; &#956;&#959;&#8166; &#7956;&#948;&#969;&#963;&#945;&#957; &#7953;&#955;&#955;&#951;&#957;&#953;&#954;&#8052;', $encoded);
}
public function testUtf8ToLatin1Russian()
{
$string = $this->russian;
$encoded = $this->utfToLatin($string);
$this->assertEquals('&#1056;&#1077;&#1082;&#1072; &#1085;&#1077;&#1089;&#1083;&#1072;&#1089;&#1103;; &#1073;&#1077;&#1076;&#1085;&#1099;&#1081; &#1095;&#1105;&#1083;&#1085;', $encoded);
}
public function testUtf8ToLatin1Chinese()
{
$string = $this->chinese;
$encoded = $this->utfToLatin($string);
$this->assertEquals('&#25105;&#33021;&#21534;&#19979;&#29627;&#29827;&#32780;&#19981;&#20260;&#36523;&#20307;&#12290;', $encoded);
}
}

View File

@@ -0,0 +1,639 @@
<?php
/**
* NB: do not let your IDE fool you. The correct encoding for this file is NOT UTF8.
*/
include_once __DIR__ . '/../lib/xmlrpc.inc';
include_once __DIR__ . '/../lib/xmlrpcs.inc';
include_once __DIR__ . '/parse_args.php';
/**
* Tests involving parsing of xml and handling of xmlrpc values
*/
class ParsingBugsTests extends PHPUnit_Framework_TestCase
{
public $args = array();
protected function setUp()
{
$this->args = argParser::getArgs();
if ($this->args['DEBUG'] == 1)
ob_start();
}
protected function tearDown()
{
if ($this->args['DEBUG'] != 1)
return;
$out = ob_get_clean();
$status = $this->getStatus();
if ($status == PHPUnit_Runner_BaseTestRunner::STATUS_ERROR
|| $status == PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE) {
echo $out;
}
}
protected function newMsg($methodName, $params = array())
{
$msg = new xmlrpcmsg($methodName, $params);
$msg->setDebug($this->args['DEBUG']);
return $msg;
}
public function testMinusOneString()
{
$v = new xmlrpcval('-1');
$u = new xmlrpcval('-1', 'string');
$t = new xmlrpcval(-1, 'string');
$this->assertEquals($v->scalarval(), $u->scalarval());
$this->assertEquals($v->scalarval(), $t->scalarval());
}
/**
* This looks funny, and we might call it a bug. But we strive for 100 backwards compat...
*/
public function testMinusOneInt()
{
$u = new xmlrpcval();
$v = new xmlrpcval(-1);
$this->assertEquals($u->scalarval(), $v->scalarval());
}
public function testUnicodeInMemberName()
{
$str = "G" . chr(252) . "nter, El" . chr(232) . "ne";
$v = array($str => new xmlrpcval(1));
$r = new xmlrpcresp(new xmlrpcval($v, 'struct'));
$r = $r->serialize();
$m = $this->newMsg('dummy');
$r = $m->parseResponse($r);
$v = $r->value();
$this->assertEquals(true, $v->structmemexists($str));
}
public function testUnicodeInErrorString()
{
$response = utf8_encode(
'<?xml version="1.0"?>
<!-- $Id -->
<!-- found by G. giunta, covers what happens when lib receives
UTF8 chars in response text and comments -->
<!-- ' . chr(224) . chr(252) . chr(232) . '&#224;&#252;&#232; -->
<methodResponse>
<fault>
<value>
<struct>
<member>
<name>faultCode</name>
<value><int>888</int></value>
</member>
<member>
<name>faultString</name>
<value><string>' . chr(224) . chr(252) . chr(232) . '&#224;&#252;&#232;</string></value>
</member>
</struct>
</value>
</fault>
</methodResponse>');
$m = $this->newMsg('dummy');
$r = $m->parseResponse($response);
$v = $r->faultString();
$this->assertEquals(chr(224) . chr(252) . chr(232) . chr(224) . chr(252) . chr(232), $v);
}
public function testValidNumbers()
{
$m = $this->newMsg('dummy');
$fp =
'<?xml version="1.0"?>
<methodResponse>
<params>
<param>
<value>
<struct>
<member>
<name>integer1</name>
<value><int>01</int></value>
</member>
<member>
<name>integer2</name>
<value><int>+1</int></value>
</member>
<member>
<name>integer3</name>
<value><i4>1</i4></value>
</member>
<member>
<name>float1</name>
<value><double>01.10</double></value>
</member>
<member>
<name>float2</name>
<value><double>+1.10</double></value>
</member>
<member>
<name>float3</name>
<value><double>-1.10e2</double></value>
</member>
</struct>
</value>
</param>
</params>
</methodResponse>';
$r = $m->parseResponse($fp);
$v = $r->value();
$s = $v->structmem('integer1');
$t = $v->structmem('integer2');
$u = $v->structmem('integer3');
$x = $v->structmem('float1');
$y = $v->structmem('float2');
$z = $v->structmem('float3');
$this->assertEquals(1, $s->scalarval());
$this->assertEquals(1, $t->scalarval());
$this->assertEquals(1, $u->scalarval());
$this->assertEquals(1.1, $x->scalarval());
$this->assertEquals(1.1, $y->scalarval());
$this->assertEquals(-110.0, $z->scalarval());
}
public function testI8()
{
if (PHP_INT_SIZE == 4 ) {
$this->markTestSkipped('did not find a locale which sets decimal separator to comma');
return;
}
$m = $this->newMsg('dummy');
$fp =
'<?xml version="1.0"?>
<methodResponse>
<params>
<param>
<value>
<struct>
<member>
<name>integer1</name>
<value><i8>1</i8></value>
</member>
</struct>
</value>
</param>
</params>
</methodResponse>';
$r = $m->parseResponse($fp);
$v = $r->value();
$s = $v->structmem('integer1');
$this->assertEquals(1, $s->scalarval());
}
public function testAddScalarToStruct()
{
$v = new xmlrpcval(array('a' => 'b'), 'struct');
// use @ operator in case error_log gets on screen
$r = @$v->addscalar('c');
$this->assertEquals(0, $r);
}
public function testAddStructToStruct()
{
$v = new xmlrpcval(array('a' => new xmlrpcval('b')), 'struct');
$r = $v->addstruct(array('b' => new xmlrpcval('c')));
$this->assertEquals(2, $v->structsize());
$this->assertEquals(1, $r);
$r = $v->addstruct(array('b' => new xmlrpcval('b')));
$this->assertEquals(2, $v->structsize());
}
public function testAddArrayToArray()
{
$v = new xmlrpcval(array(new xmlrpcval('a'), new xmlrpcval('b')), 'array');
$r = $v->addarray(array(new xmlrpcval('b'), new xmlrpcval('c')));
$this->assertEquals(4, $v->arraysize());
$this->assertEquals(1, $r);
}
public function testEncodeArray()
{
$r = range(1, 100);
$v = php_xmlrpc_encode($r);
$this->assertEquals('array', $v->kindof());
}
public function testEncodeRecursive()
{
$v = php_xmlrpc_encode(php_xmlrpc_encode('a simple string'));
$this->assertEquals('scalar', $v->kindof());
}
public function testBrokenRequests()
{
$s = new xmlrpc_server();
// omitting the 'params' tag: not tolerated by the lib anymore
$f = '<?xml version="1.0"?>
<methodCall>
<methodName>system.methodHelp</methodName>
<param>
<value><string>system.methodHelp</string></value>
</param>
</methodCall>';
$r = $s->parserequest($f);
$this->assertEquals(15, $r->faultCode());
// omitting a 'param' tag
$f = '<?xml version="1.0"?>
<methodCall>
<methodName>system.methodHelp</methodName>
<params>
<value><string>system.methodHelp</string></value>
</params>
</methodCall>';
$r = $s->parserequest($f);
$this->assertEquals(15, $r->faultCode());
// omitting a 'value' tag
$f = '<?xml version="1.0"?>
<methodCall>
<methodName>system.methodHelp</methodName>
<params>
<param><string>system.methodHelp</string></param>
</params>
</methodCall>';
$r = $s->parserequest($f);
$this->assertEquals(15, $r->faultCode());
}
public function testBrokenResponses()
{
$m = $this->newMsg('dummy');
// omitting the 'params' tag: no more tolerated by the lib...
$f = '<?xml version="1.0"?>
<methodResponse>
<param>
<value><string>system.methodHelp</string></value>
</param>
</methodResponse>';
$r = $m->parseResponse($f);
$this->assertEquals(2, $r->faultCode());
// omitting the 'param' tag: no more tolerated by the lib...
$f = '<?xml version="1.0"?>
<methodResponse>
<params>
<value><string>system.methodHelp</string></value>
</params>
</methodResponse>';
$r = $m->parseResponse($f);
$this->assertEquals(2, $r->faultCode());
// omitting a 'value' tag: KO
$f = '<?xml version="1.0"?>
<methodResponse>
<params>
<param><string>system.methodHelp</string></param>
</params>
</methodResponse>';
$r = $m->parseResponse($f);
$this->assertEquals(2, $r->faultCode());
}
public function testBuggyHttp()
{
$s = $this->newMsg('dummy');
$f = 'HTTP/1.1 100 Welcome to the jungle
HTTP/1.0 200 OK
X-Content-Marx-Brothers: Harpo
Chico and Groucho
Content-Length: who knows?
<?xml version="1.0"?>
<!-- First of all, let\'s check out if the lib properly handles a commented </methodResponse> tag... -->
<methodResponse><params><param><value><struct><member><name>userid</name><value>311127</value></member>
<member><name>dateCreated</name><value><dateTime.iso8601>20011126T09:17:52</dateTime.iso8601></value></member><member><name>content</name><value>hello world. 2 newlines follow
and there they were.</value></member><member><name>postid</name><value>7414222</value></member></struct></value></param></params></methodResponse>
<script type="text\javascript">document.write(\'Hello, my name is added nag, I\\\'m happy to serve your content for free\');</script>
';
$r = $s->parseResponse($f);
$v = $r->value();
$s = $v->structmem('content');
$this->assertEquals("hello world. 2 newlines follow\n\n\nand there they were.", $s->scalarval());
}
public function testStringBug()
{
$s = $this->newMsg('dummy');
$f = '<?xml version="1.0"?>
<!-- $Id -->
<!-- found by 2z69xks7bpy001@sneakemail.com, amongst others
covers what happens when there\'s character data after </string>
and before </value> -->
<methodResponse>
<params>
<param>
<value>
<struct>
<member>
<name>success</name>
<value>
<boolean>1</boolean>
</value>
</member>
<member>
<name>sessionID</name>
<value>
<string>S300510007I</string>
</value>
</member>
</struct>
</value>
</param>
</params>
</methodResponse> ';
$r = $s->parseResponse($f);
$v = $r->value();
$s = $v->structmem('sessionID');
$this->assertEquals('S300510007I', $s->scalarval());
}
public function testWhiteSpace()
{
$s = $this->newMsg('dummy');
$f = '<?xml version="1.0"?><methodResponse><params><param><value><struct><member><name>userid</name><value>311127</value></member>
<member><name>dateCreated</name><value><dateTime.iso8601>20011126T09:17:52</dateTime.iso8601></value></member><member><name>content</name><value>hello world. 2 newlines follow
and there they were.</value></member><member><name>postid</name><value>7414222</value></member></struct></value></param></params></methodResponse>
';
$r = $s->parseResponse($f);
$v = $r->value();
$s = $v->structmem('content');
$this->assertEquals("hello world. 2 newlines follow\n\n\nand there they were.", $s->scalarval());
}
public function testDoubleDataInArrayTag()
{
$s = $this->newMsg('dummy');
$f = '<?xml version="1.0"?><methodResponse><params><param><value><array>
<data></data>
<data></data>
</array></value></param></params></methodResponse>
';
$r = $s->parseResponse($f);
$v = $r->faultCode();
$this->assertEquals(2, $v);
$f = '<?xml version="1.0"?><methodResponse><params><param><value><array>
<data><value>Hello world</value></data>
<data></data>
</array></value></param></params></methodResponse>
';
$r = $s->parseResponse($f);
$v = $r->faultCode();
$this->assertEquals(2, $v);
}
public function testDoubleStuffInValueTag()
{
$s = $this->newMsg('dummy');
$f = '<?xml version="1.0"?><methodResponse><params><param><value>
<string>hello world</string>
<array><data></data></array>
</value></param></params></methodResponse>
';
$r = $s->parseResponse($f);
$v = $r->faultCode();
$this->assertEquals(2, $v);
$f = '<?xml version="1.0"?><methodResponse><params><param><value>
<string>hello</string>
<string>world</string>
</value></param></params></methodResponse>
';
$r = $s->parseResponse($f);
$v = $r->faultCode();
$this->assertEquals(2, $v);
$f = '<?xml version="1.0"?><methodResponse><params><param><value>
<string>hello</string>
<struct><member><name>hello><value>world</value></member></struct>
</value></param></params></methodResponse>
';
$r = $s->parseResponse($f);
$v = $r->faultCode();
$this->assertEquals(2, $v);
}
public function testAutodecodeResponse()
{
$s = $this->newMsg('dummy');
$f = '<?xml version="1.0"?><methodResponse><params><param><value><struct><member><name>userid</name><value>311127</value></member>
<member><name>dateCreated</name><value><dateTime.iso8601>20011126T09:17:52</dateTime.iso8601></value></member><member><name>content</name><value>hello world. 2 newlines follow
and there they were.</value></member><member><name>postid</name><value>7414222</value></member></struct></value></param></params></methodResponse>
';
$r = $s->parseResponse($f, true, 'phpvals');
$v = $r->value();
$s = $v['content'];
$this->assertEquals("hello world. 2 newlines follow\n\n\nand there they were.", $s);
}
public function testNoDecodeResponse()
{
$s = $this->newMsg('dummy');
$f = '<?xml version="1.0"?><methodResponse><params><param><value><struct><member><name>userid</name><value>311127</value></member>
<member><name>dateCreated</name><value><dateTime.iso8601>20011126T09:17:52</dateTime.iso8601></value></member><member><name>content</name><value>hello world. 2 newlines follow
and there they were.</value></member><member><name>postid</name><value>7414222</value></member></struct></value></param></params></methodResponse>';
$r = $s->parseResponse($f, true, 'xml');
$v = $r->value();
$this->assertEquals($f, $v);
}
public function testAutoCoDec()
{
$data1 = array(1, 1.0, 'hello world', true, '20051021T23:43:00', -1, 11.0, '~!@#$%^&*()_+|', false, '20051021T23:43:00');
$data2 = array('zero' => $data1, 'one' => $data1, 'two' => $data1, 'three' => $data1, 'four' => $data1, 'five' => $data1, 'six' => $data1, 'seven' => $data1, 'eight' => $data1, 'nine' => $data1);
$data = array($data2, $data2, $data2, $data2, $data2, $data2, $data2, $data2, $data2, $data2);
//$keys = array('zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine');
$v1 = php_xmlrpc_encode($data, array('auto_dates'));
$v2 = php_xmlrpc_decode_xml($v1->serialize());
$this->assertEquals($v1, $v2);
$r1 = new PhpXmlRpc\Response($v1);
$r2 = php_xmlrpc_decode_xml($r1->serialize());
$r2->serialize(); // needed to set internal member payload
$this->assertEquals($r1, $r2);
$m1 = new PhpXmlRpc\Request('hello dolly', array($v1));
$m2 = php_xmlrpc_decode_xml($m1->serialize());
$m2->serialize(); // needed to set internal member payload
$this->assertEquals($m1, $m2);
}
public function testUTF8Request()
{
$sendstring = 'κόσμε'; // Greek word 'kosme'. NB: NOT a valid ISO8859 string!
$GLOBALS['xmlrpc_internalencoding'] = 'UTF-8';
\PhpXmlRpc\PhpXmlRpc::importGlobals();
$f = new xmlrpcval($sendstring, 'string');
$v = $f->serialize();
$this->assertEquals("<value><string>&#954;&#8057;&#963;&#956;&#949;</string></value>\n", $v);
$GLOBALS['xmlrpc_internalencoding'] = 'ISO-8859-1';
\PhpXmlRpc\PhpXmlRpc::importGlobals();
}
public function testUTF8Response()
{
$string = chr(224) . chr(252) . chr(232);
$s = $this->newMsg('dummy');
$f = "HTTP/1.1 200 OK\r\nContent-type: text/xml; charset=UTF-8\r\n\r\n" . '<?xml version="1.0"?><methodResponse><params><param><value><struct><member><name>userid</name><value>311127</value></member>
<member><name>dateCreated</name><value><dateTime.iso8601>20011126T09:17:52</dateTime.iso8601></value></member><member><name>content</name><value>' . utf8_encode($string) . '</value></member><member><name>postid</name><value>7414222</value></member></struct></value></param></params></methodResponse>
';
$r = $s->parseResponse($f, false, 'phpvals');
$v = $r->value();
$v = $v['content'];
$this->assertEquals($string, $v);
$f = '<?xml version="1.0" encoding="UTF-8"?><methodResponse><params><param><value><struct><member><name>userid</name><value>311127</value></member>
<member><name>dateCreated</name><value><dateTime.iso8601>20011126T09:17:52</dateTime.iso8601></value></member><member><name>content</name><value>' . utf8_encode($string) . '</value></member><member><name>postid</name><value>7414222</value></member></struct></value></param></params></methodResponse>
';
$r = $s->parseResponse($f, false, 'phpvals');
$v = $r->value();
$v = $v['content'];
$this->assertEquals($string, $v);
$r = php_xmlrpc_decode_xml($f);
$v = $r->value();
$v = $v->structmem('content')->scalarval();
$this->assertEquals($string, $v);
}
public function testLatin1Response()
{
$string = chr(224) . chr(252) . chr(232);
$s = $this->newMsg('dummy');
$f = "HTTP/1.1 200 OK\r\nContent-type: text/xml; charset=ISO-8859-1\r\n\r\n" . '<?xml version="1.0"?><methodResponse><params><param><value><struct><member><name>userid</name><value>311127</value></member>
<member><name>dateCreated</name><value><dateTime.iso8601>20011126T09:17:52</dateTime.iso8601></value></member><member><name>content</name><value>' . $string . '</value></member><member><name>postid</name><value>7414222</value></member></struct></value></param></params></methodResponse>
';
$r = $s->parseResponse($f, false, 'phpvals');
$v = $r->value();
$v = $v['content'];
$this->assertEquals($string, $v);
$f = '<?xml version="1.0" encoding="ISO-8859-1"?><methodResponse><params><param><value><struct><member><name>userid</name><value>311127</value></member>
<member><name>dateCreated</name><value><dateTime.iso8601>20011126T09:17:52</dateTime.iso8601></value></member><member><name>content</name><value>' . $string . '</value></member><member><name>postid</name><value>7414222</value></member></struct></value></param></params></methodResponse>
';
$r = $s->parseResponse($f, false, 'phpvals');
$v = $r->value();
$v = $v['content'];
$this->assertEquals($string, $v);
$r = php_xmlrpc_decode_xml($f);
$v = $r->value();
$v = $v->structmem('content')->scalarval();
$this->assertEquals($string, $v);
}
public function testUTF8IntString()
{
$v = new xmlrpcval(100, 'int');
$s = $v->serialize('UTF-8');
$this->assertequals("<value><int>100</int></value>\n", $s);
}
public function testStringInt()
{
$v = new xmlrpcval('hello world', 'int');
$s = $v->serialize();
$this->assertequals("<value><int>0</int></value>\n", $s);
}
public function testStructMemExists()
{
$v = php_xmlrpc_encode(array('hello' => 'world'));
$b = $v->structmemexists('hello');
$this->assertequals(true, $b);
$b = $v->structmemexists('world');
$this->assertequals(false, $b);
}
public function testNilvalue()
{
// default case: we do not accept nil values received
$v = new xmlrpcval('hello', 'null');
$r = new xmlrpcresp($v);
$s = $r->serialize();
$m = $this->newMsg('dummy');
$r = $m->parseresponse($s);
$this->assertequals(2, $r->faultCode());
// enable reception of nil values
$GLOBALS['xmlrpc_null_extension'] = true;
\PhpXmlRpc\PhpXmlRpc::importGlobals();
$r = $m->parseresponse($s);
$v = $r->value();
$this->assertequals('null', $v->scalartyp());
// test with the apache version: EX:NIL
$GLOBALS['xmlrpc_null_apache_encoding'] = true;
\PhpXmlRpc\PhpXmlRpc::importGlobals();
// serialization
$v = new xmlrpcval('hello', 'null');
$s = $v->serialize();
$this->assertequals(1, preg_match('#<value><ex:nil/></value>#', $s));
// deserialization
$r = new xmlrpcresp($v);
$s = $r->serialize();
$r = $m->parseresponse($s);
$v = $r->value();
$this->assertequals('null', $v->scalartyp());
$GLOBALS['xmlrpc_null_extension'] = false;
\PhpXmlRpc\PhpXmlRpc::importGlobals();
$r = $m->parseresponse($s);
$this->assertequals(2, $r->faultCode());
}
public function testLocale()
{
$locale = setlocale(LC_NUMERIC, 0);
/// @todo on php 5.3/win setting locale to german does not seem to set decimal separator to comma...
if (setlocale(LC_NUMERIC, 'deu', 'de_DE@euro', 'de_DE', 'de', 'ge') !== false) {
$v = new xmlrpcval(1.1, 'double');
if (strpos($v->scalarval(), ',') == 1) {
$r = $v->serialize();
$this->assertequals(false, strpos($r, ','));
setlocale(LC_NUMERIC, $locale);
} else {
setlocale(LC_NUMERIC, $locale);
$this->markTestSkipped('did not find a locale which sets decimal separator to comma');
}
} else {
$this->markTestSkipped('did not find a locale which sets decimal separator to comma');
}
}
public function testArrayAccess()
{
$v1 = new xmlrpcval(array(new xmlrpcval('one'), new xmlrpcval('two')), 'array');
$this->assertequals(1, count($v1));
$out = array('me' => array(), 'mytype' => 2, '_php_class' => null);
foreach($v1 as $key => $val)
{
$expected = each($out);
$this->assertequals($expected['key'], $key);
if (gettype($expected['value']) == 'array') {
$this->assertequals('array', gettype($val));
} else {
$this->assertequals($expected['value'], $val);
}
}
$v2 = new \PhpXmlRpc\Value(array(new \PhpXmlRpc\Value('one'), new \PhpXmlRpc\Value('two')), 'array');
$this->assertequals(2, count($v2));
$out = array(0 => 'object', 1 => 'object');
foreach($v2 as $key => $val)
{
$expected = each($out);
$this->assertequals($expected['key'], $key);
$this->assertequals($expected['value'], gettype($val));
}
}
}

View File

@@ -0,0 +1,94 @@
<?php
include_once __DIR__ . '/../lib/xmlrpc.inc';
include_once __DIR__ . '/parse_args.php';
/**
* Tests involving requests sent to non-existing servers
*/
class InvalidHostTest extends PHPUnit_Framework_TestCase
{
/** @var xmlrpc_client $client */
public $client = null;
public $args = array();
public function setUp()
{
$this->args = argParser::getArgs();
$this->client = new xmlrpc_client('/NOTEXIST.php', $this->args['LOCALSERVER'], 80);
$this->client->setDebug($this->args['DEBUG']);
if ($this->args['DEBUG'] == 1)
ob_start();
}
protected function tearDown()
{
if ($this->args['DEBUG'] != 1)
return;
$out = ob_get_clean();
$status = $this->getStatus();
if ($status == PHPUnit_Runner_BaseTestRunner::STATUS_ERROR
|| $status == PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE) {
echo $out;
}
}
public function test404()
{
$m = new xmlrpcmsg('examples.echo', array(
new xmlrpcval('hello', 'string'),
));
$r = $this->client->send($m, 5);
$this->assertEquals(5, $r->faultCode());
}
public function testSrvNotFound()
{
$m = new xmlrpcmsg('examples.echo', array(
new xmlrpcval('hello', 'string'),
));
$this->client->server .= 'XXX';
$r = $this->client->send($m, 5);
// make sure there's no freaking catchall DNS in effect
$dnsinfo = dns_get_record($this->client->server);
if ($dnsinfo) {
$this->markTestSkipped('Seems like there is a catchall DNS in effect: host ' . $this->client->server . ' found');
} else {
$this->assertEquals(5, $r->faultCode());
}
}
public function testCurlKAErr()
{
if (!function_exists('curl_init')) {
$this->markTestSkipped('CURL missing: cannot test curl keepalive errors');
return;
}
$m = new xmlrpcmsg('examples.stringecho', array(
new xmlrpcval('hello', 'string'),
));
// test 2 calls w. keepalive: 1st time connection ko, second time ok
$this->client->server .= 'XXX';
$this->client->keepalive = true;
$r = $this->client->send($m, 5, 'http11');
// in case we have a "universal dns resolver" getting in the way, we might get a 302 instead of a 404
$this->assertTrue($r->faultCode() === 8 || $r->faultCode() == 5);
// now test a successful connection
$server = explode(':', $this->args['LOCALSERVER']);
if (count($server) > 1) {
$this->client->port = $server[1];
}
$this->client->server = $server[0];
$this->client->path = $this->args['URI'];
$r = $this->client->send($m, 5, 'http11');
$this->assertEquals(0, $r->faultCode());
$ro = $r->value();
is_object($ro) && $this->assertEquals('hello', $ro->scalarVal());
}
}

View File

@@ -0,0 +1,955 @@
<?php
include_once __DIR__ . '/../lib/xmlrpc.inc';
include_once __DIR__ . '/../lib/xmlrpc_wrappers.inc';
include_once __DIR__ . '/parse_args.php';
/**
* Tests which involve interaction between the client and the server.
* They are run against the server found in demo/server.php
*/
class LocalhostTest extends PHPUnit_Framework_TestCase
{
/** @var xmlrpc_client $client */
protected $client = null;
protected $method = 'http';
protected $timeout = 10;
protected $request_compression = null;
protected $accepted_compression = '';
protected $args = array();
protected static $failed_tests = array();
protected $testId;
/** @var boolean $collectCodeCoverageInformation */
protected $collectCodeCoverageInformation;
protected $coverageScriptUrl;
public static function fail($message = '')
{
// save in a static var that this particular test has failed
// (but only if not called from subclass objects / multitests)
if (function_exists('debug_backtrace') && strtolower(get_called_class()) == 'localhosttests') {
$trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
for ($i = 0; $i < count($trace); $i++) {
if (strpos($trace[$i]['function'], 'test') === 0) {
self::$failed_tests[$trace[$i]['function']] = true;
break;
}
}
}
parent::fail($message);
}
/**
* Reimplemented to allow us to collect code coverage info from the target server.
* Code taken from PHPUnit_Extensions_Selenium2TestCase
*
* @param PHPUnit_Framework_TestResult $result
* @return PHPUnit_Framework_TestResult
* @throws Exception
*/
public function run(PHPUnit_Framework_TestResult $result = NULL)
{
$this->testId = get_class($this) . '__' . $this->getName();
if ($result === NULL) {
$result = $this->createResult();
}
$this->collectCodeCoverageInformation = $result->getCollectCodeCoverageInformation();
parent::run($result);
if ($this->collectCodeCoverageInformation) {
$coverage = new PHPUnit_Extensions_SeleniumCommon_RemoteCoverage(
$this->coverageScriptUrl,
$this->testId
);
$result->getCodeCoverage()->append(
$coverage->get(), $this
);
}
// do not call this before to give the time to the Listeners to run
//$this->getStrategy()->endOfTest($this->session);
return $result;
}
public function setUp()
{
$this->args = argParser::getArgs();
$server = explode(':', $this->args['LOCALSERVER']);
if (count($server) > 1) {
$this->client = new xmlrpc_client($this->args['URI'], $server[0], $server[1]);
} else {
$this->client = new xmlrpc_client($this->args['URI'], $this->args['LOCALSERVER']);
}
$this->client->setDebug($this->args['DEBUG']);
$this->client->request_compression = $this->request_compression;
$this->client->accepted_compression = $this->accepted_compression;
$this->coverageScriptUrl = 'http://' . $this->args['LOCALSERVER'] . '/' . str_replace( '/demo/server/server.php', 'tests/phpunit_coverage.php', $this->args['URI'] );
if ($this->args['DEBUG'] == 1)
ob_start();
}
protected function tearDown()
{
if ($this->args['DEBUG'] != 1)
return;
$out = ob_get_clean();
$status = $this->getStatus();
if ($status == PHPUnit_Runner_BaseTestRunner::STATUS_ERROR
|| $status == PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE) {
echo $out;
}
}
/**
* @param PhpXmlRpc\Request|array $msg
* @param int|array $errorCode
* @param bool $returnResponse
* @return mixed|\PhpXmlRpc\Response|\PhpXmlRpc\Response[]|\PhpXmlRpc\Value|string|void
*/
protected function send($msg, $errorCode = 0, $returnResponse = false)
{
if ($this->collectCodeCoverageInformation) {
$this->client->setCookie('PHPUNIT_SELENIUM_TEST_ID', $this->testId);
}
$r = $this->client->send($msg, $this->timeout, $this->method);
// for multicall, return directly array of responses
if (is_array($r)) {
return $r;
}
if (is_array($errorCode)) {
$this->assertContains($r->faultCode(), $errorCode, 'Error ' . $r->faultCode() . ' connecting to server: ' . $r->faultString());
} else {
$this->assertEquals($errorCode, $r->faultCode(), 'Error ' . $r->faultCode() . ' connecting to server: ' . $r->faultString());
}
if (!$r->faultCode()) {
if ($returnResponse) {
return $r;
} else {
return $r->value();
}
} else {
return;
}
}
public function testString()
{
$sendString = "here are 3 \"entities\": < > & " .
"and here's a dollar sign: \$pretendvarname and a backslash too: " . chr(92) .
" - isn't that great? \\\"hackery\\\" at it's best " .
" also don't want to miss out on \$item[0]. " .
"The real weird stuff follows: CRLF here" . chr(13) . chr(10) .
"a simple CR here" . chr(13) .
"a simple LF here" . chr(10) .
"and then LFCR" . chr(10) . chr(13) .
"last but not least weird names: G" . chr(252) . "nter, El" . chr(232) . "ne, and an xml comment closing tag: -->";
$m = new xmlrpcmsg('examples.stringecho', array(
new xmlrpcval($sendString, 'string'),
));
$v = $this->send($m);
if ($v) {
// when sending/receiving non-US-ASCII encoded strings, XML says cr-lf can be normalized.
// so we relax our tests...
$l1 = strlen($sendString);
$l2 = strlen($v->scalarval());
if ($l1 == $l2) {
$this->assertEquals($sendString, $v->scalarval());
} else {
$this->assertEquals(str_replace(array("\r\n", "\r"), array("\n", "\n"), $sendString), $v->scalarval());
}
}
}
public function testLatin1String()
{
$sendString =
"last but not least weird names: G" . chr(252) . "nter, El" . chr(232) . "ne";
$x = '<?xml version="1.0" encoding="ISO-8859-1"?><methodCall><methodName>examples.stringecho</methodName><params><param><value>'.
$sendString.
'</value></param></params></methodCall>';
$v = $this->send($x);
if ($v) {
$this->assertEquals($sendString, $v->scalarval());
}
}
public function testExoticCharsetsRequests()
{
// note that we should disable this call also when mbstring is missing server-side
if (!function_exists('mb_convert_encoding')) {
$this->markTestSkipped('Miss mbstring extension to test exotic charsets');
return;
}
$sendString = 'κόσμε'; // Greek word 'kosme'. NB: NOT a valid ISO8859 string!
$str = '<?xml version="1.0" encoding="_ENC_"?>
<methodCall>
<methodName>examples.stringecho</methodName>
<params>
<param>
<value><string>'.$sendString.'</string></value>
</param>
</params>
</methodCall>';
PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding = 'UTF-8';
// we have to set the encoding declaration either in the http header or xml prolog, as mb_detect_encoding
// (used on the server side) will fail recognizing these 2 charsets
$v = $this->send(mb_convert_encoding(str_replace('_ENC_', 'UCS-4', $str), 'UCS-4', 'UTF-8'));
$this->assertEquals($sendString, $v->scalarval());
$v = $this->send(mb_convert_encoding(str_replace('_ENC_', 'UTF-16', $str), 'UTF-16', 'UTF-8'));
$this->assertEquals($sendString, $v->scalarval());
PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding = 'ISO-8859-1';
}
public function testExoticCharsetsRequests2()
{
// note that we should disable this call also when mbstring is missing server-side
if (!function_exists('mb_convert_encoding')) {
$this->markTestSkipped('Miss mbstring extension to test exotic charsets');
return;
}
$sendString = '安室奈美恵'; // No idea what this means :-) NB: NOT a valid ISO8859 string!
$str = '<?xml version="1.0"?>
<methodCall>
<methodName>examples.stringecho</methodName>
<params>
<param>
<value><string>'.$sendString.'</string></value>
</param>
</params>
</methodCall>';
PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding = 'UTF-8';
// no encoding declaration either in the http header or xml prolog, let mb_detect_encoding
// (used on the server side) sort it out
$this->client->path = $this->args['URI'].'?DETECT_ENCODINGS[]=EUC-JP&DETECT_ENCODINGS[]=UTF-8';
$v = $this->send(mb_convert_encoding($str, 'EUC-JP', 'UTF-8'));
$this->assertEquals($sendString, $v->scalarval());
PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding = 'ISO-8859-1';
}
public function testExoticCharsetsRequests3()
{
// note that we should disable this call also when mbstring is missing server-side
if (!function_exists('mb_convert_encoding')) {
$this->markTestSkipped('Miss mbstring extension to test exotic charsets');
return;
}
$sendString = utf8_decode('élève');
$str = '<?xml version="1.0"?>
<methodCall>
<methodName>examples.stringecho</methodName>
<params>
<param>
<value><string>'.$sendString.'</string></value>
</param>
</params>
</methodCall>';
// no encoding declaration either in the http header or xml prolog, let mb_detect_encoding
// (used on the server side) sort it out
$this->client->path = $this->args['URI'].'?DETECT_ENCODINGS[]=ISO-8859-1&DETECT_ENCODINGS[]=UTF-8';
$v = $this->send($str);
$this->assertEquals($sendString, $v->scalarval());
}
/*public function testLatin1Method()
{
$f = new xmlrpcmsg("tests.iso88591methodname." . chr(224) . chr(252) . chr(232), array(
new xmlrpcval('hello')
));
$v = $this->send($f);
if ($v) {
$this->assertEquals('hello', $v->scalarval());
}
}*/
public function testUtf8Method()
{
PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding = 'UTF-8';
$m = new xmlrpcmsg("tests.utf8methodname." . 'κόσμε', array(
new xmlrpcval('hello')
));
$v = $this->send($m);
if ($v) {
$this->assertEquals('hello', $v->scalarval());
}
PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding = 'ISO-8859-1';
}
public function testAddingDoubles()
{
// note that rounding errors mean we
// keep precision to sensible levels here ;-)
$a = 12.13;
$b = -23.98;
$m = new xmlrpcmsg('examples.addtwodouble', array(
new xmlrpcval($a, 'double'),
new xmlrpcval($b, 'double'),
));
$v = $this->send($m);
if ($v) {
$this->assertEquals($a + $b, $v->scalarval());
}
}
public function testAdding()
{
$m = new xmlrpcmsg('examples.addtwo', array(
new xmlrpcval(12, 'int'),
new xmlrpcval(-23, 'int'),
));
$v = $this->send($m);
if ($v) {
$this->assertEquals(12 - 23, $v->scalarval());
}
}
public function testInvalidNumber()
{
$m = new xmlrpcmsg('examples.addtwo', array(
new xmlrpcval('fred', 'int'),
new xmlrpcval("\"; exec('ls')", 'int'),
));
$v = $this->send($m);
/// @todo a fault condition should be generated here
/// by the server, which we pick up on
if ($v) {
$this->assertEquals(0, $v->scalarval());
}
}
public function testBoolean()
{
$m = new xmlrpcmsg('examples.invertBooleans', array(
new xmlrpcval(array(
new xmlrpcval(true, 'boolean'),
new xmlrpcval(false, 'boolean'),
new xmlrpcval(1, 'boolean'),
new xmlrpcval(0, 'boolean')
),
'array'
),));
$answer = '0101';
$v = $this->send($m);
if ($v) {
$sz = $v->arraysize();
$got = '';
for ($i = 0; $i < $sz; $i++) {
$b = $v->arraymem($i);
if ($b->scalarval()) {
$got .= '1';
} else {
$got .= '0';
}
}
$this->assertEquals($answer, $got);
}
}
public function testBase64()
{
$sendString = 'Mary had a little lamb,
Whose fleece was white as snow,
And everywhere that Mary went
the lamb was sure to go.
Mary had a little lamb
She tied it to a pylon
Ten thousand volts went down its back
And turned it into nylon';
$m = new xmlrpcmsg('examples.decode64', array(
new xmlrpcval($sendString, 'base64'),
));
$v = $this->send($m);
if ($v) {
if (strlen($sendString) == strlen($v->scalarval())) {
$this->assertEquals($sendString, $v->scalarval());
} else {
$this->assertEquals(str_replace(array("\r\n", "\r"), array("\n", "\n"), $sendString), $v->scalarval());
}
}
}
public function testDateTime()
{
$time = time();
$t1 = new xmlrpcval($time, 'dateTime.iso8601');
$t2 = new xmlrpcval(iso8601_encode($time), 'dateTime.iso8601');
$this->assertEquals($t1->serialize(), $t2->serialize());
if (class_exists('DateTime')) {
$datetime = new DateTime();
// skip this test for php 5.2. It is a bit harder there to build a DateTime from unix timestamp with proper TZ info
if (is_callable(array($datetime, 'setTimestamp'))) {
$t3 = new xmlrpcval($datetime->setTimestamp($time), 'dateTime.iso8601');
$this->assertEquals($t1->serialize(), $t3->serialize());
}
}
}
public function testCountEntities()
{
$sendString = "h'fd>onc>>l>>rw&bpu>q>e<v&gxs<ytjzkami<";
$m = new xmlrpcmsg('validator1.countTheEntities', array(
new xmlrpcval($sendString, 'string'),
));
$v = $this->send($m);
if ($v) {
$got = '';
$expected = '37210';
$expect_array = array('ctLeftAngleBrackets', 'ctRightAngleBrackets', 'ctAmpersands', 'ctApostrophes', 'ctQuotes');
while (list(, $val) = each($expect_array)) {
$b = $v->structmem($val);
$got .= $b->me['int'];
}
$this->assertEquals($expected, $got);
}
}
public function _multicall_msg($method, $params)
{
$struct['methodName'] = new xmlrpcval($method, 'string');
$struct['params'] = new xmlrpcval($params, 'array');
return new xmlrpcval($struct, 'struct');
}
public function testServerMulticall()
{
// We manually construct a system.multicall() call to ensure
// that the server supports it.
// NB: This test will NOT pass if server does not support system.multicall.
// Based on http://xmlrpc-c.sourceforge.net/hacks/test_multicall.py
$good1 = $this->_multicall_msg(
'system.methodHelp',
array(php_xmlrpc_encode('system.listMethods')));
$bad = $this->_multicall_msg(
'test.nosuch',
array(php_xmlrpc_encode(1), php_xmlrpc_encode(2)));
$recursive = $this->_multicall_msg(
'system.multicall',
array(new xmlrpcval(array(), 'array')));
$good2 = $this->_multicall_msg(
'system.methodSignature',
array(php_xmlrpc_encode('system.listMethods')));
$arg = new xmlrpcval(
array($good1, $bad, $recursive, $good2),
'array'
);
$m = new xmlrpcmsg('system.multicall', array($arg));
$v = $this->send($m);
if ($v) {
//$this->assertTrue($r->faultCode() == 0, "fault from system.multicall");
$this->assertTrue($v->arraysize() == 4, "bad number of return values");
$r1 = $v->arraymem(0);
$this->assertTrue(
$r1->kindOf() == 'array' && $r1->arraysize() == 1,
"did not get array of size 1 from good1"
);
$r2 = $v->arraymem(1);
$this->assertTrue(
$r2->kindOf() == 'struct',
"no fault from bad"
);
$r3 = $v->arraymem(2);
$this->assertTrue(
$r3->kindOf() == 'struct',
"recursive system.multicall did not fail"
);
$r4 = $v->arraymem(3);
$this->assertTrue(
$r4->kindOf() == 'array' && $r4->arraysize() == 1,
"did not get array of size 1 from good2"
);
}
}
public function testClientMulticall1()
{
// NB: This test will NOT pass if server does not support system.multicall.
$this->client->no_multicall = false;
$good1 = new xmlrpcmsg('system.methodHelp',
array(php_xmlrpc_encode('system.listMethods')));
$bad = new xmlrpcmsg('test.nosuch',
array(php_xmlrpc_encode(1), php_xmlrpc_encode(2)));
$recursive = new xmlrpcmsg('system.multicall',
array(new xmlrpcval(array(), 'array')));
$good2 = new xmlrpcmsg('system.methodSignature',
array(php_xmlrpc_encode('system.listMethods'))
);
$r = $this->send(array($good1, $bad, $recursive, $good2));
if ($r) {
$this->assertTrue(count($r) == 4, "wrong number of return values");
}
$this->assertTrue($r[0]->faultCode() == 0, "fault from good1");
if (!$r[0]->faultCode()) {
$val = $r[0]->value();
$this->assertTrue(
$val->kindOf() == 'scalar' && $val->scalartyp() == 'string',
"good1 did not return string"
);
}
$this->assertTrue($r[1]->faultCode() != 0, "no fault from bad");
$this->assertTrue($r[2]->faultCode() != 0, "no fault from recursive system.multicall");
$this->assertTrue($r[3]->faultCode() == 0, "fault from good2");
if (!$r[3]->faultCode()) {
$val = $r[3]->value();
$this->assertTrue($val->kindOf() == 'array', "good2 did not return array");
}
// This is the only assert in this test which should fail
// if the test server does not support system.multicall.
$this->assertTrue($this->client->no_multicall == false,
"server does not support system.multicall"
);
}
public function testClientMulticall2()
{
// NB: This test will NOT pass if server does not support system.multicall.
$this->client->no_multicall = true;
$good1 = new xmlrpcmsg('system.methodHelp',
array(php_xmlrpc_encode('system.listMethods')));
$bad = new xmlrpcmsg('test.nosuch',
array(php_xmlrpc_encode(1), php_xmlrpc_encode(2)));
$recursive = new xmlrpcmsg('system.multicall',
array(new xmlrpcval(array(), 'array')));
$good2 = new xmlrpcmsg('system.methodSignature',
array(php_xmlrpc_encode('system.listMethods'))
);
$r = $this->send(array($good1, $bad, $recursive, $good2));
if ($r) {
$this->assertTrue(count($r) == 4, "wrong number of return values");
}
$this->assertTrue($r[0]->faultCode() == 0, "fault from good1");
if (!$r[0]->faultCode()) {
$val = $r[0]->value();
$this->assertTrue(
$val->kindOf() == 'scalar' && $val->scalartyp() == 'string',
"good1 did not return string");
}
$this->assertTrue($r[1]->faultCode() != 0, "no fault from bad");
$this->assertTrue($r[2]->faultCode() == 0, "fault from (non recursive) system.multicall");
$this->assertTrue($r[3]->faultCode() == 0, "fault from good2");
if (!$r[3]->faultCode()) {
$val = $r[3]->value();
$this->assertTrue($val->kindOf() == 'array', "good2 did not return array");
}
}
public function testClientMulticall3()
{
// NB: This test will NOT pass if server does not support system.multicall.
$this->client->return_type = 'phpvals';
$this->client->no_multicall = false;
$good1 = new xmlrpcmsg('system.methodHelp',
array(php_xmlrpc_encode('system.listMethods')));
$bad = new xmlrpcmsg('test.nosuch',
array(php_xmlrpc_encode(1), php_xmlrpc_encode(2)));
$recursive = new xmlrpcmsg('system.multicall',
array(new xmlrpcval(array(), 'array')));
$good2 = new xmlrpcmsg('system.methodSignature',
array(php_xmlrpc_encode('system.listMethods'))
);
$r = $this->send(array($good1, $bad, $recursive, $good2));
if ($r) {
$this->assertTrue(count($r) == 4, "wrong number of return values");
}
$this->assertTrue($r[0]->faultCode() == 0, "fault from good1");
if (!$r[0]->faultCode()) {
$val = $r[0]->value();
$this->assertTrue(
is_string($val), "good1 did not return string");
}
$this->assertTrue($r[1]->faultCode() != 0, "no fault from bad");
$this->assertTrue($r[2]->faultCode() != 0, "no fault from recursive system.multicall");
$this->assertTrue($r[3]->faultCode() == 0, "fault from good2");
if (!$r[3]->faultCode()) {
$val = $r[3]->value();
$this->assertTrue(is_array($val), "good2 did not return array");
}
$this->client->return_type = 'xmlrpcvals';
}
public function testCatchWarnings()
{
$m = new xmlrpcmsg('tests.generatePHPWarning', array(
new xmlrpcval('whatever', 'string'),
));
$v = $this->send($m);
if ($v) {
$this->assertEquals(true, $v->scalarval());
}
}
public function testCatchExceptions()
{
$m = new xmlrpcmsg('tests.raiseException', array(
new xmlrpcval('whatever', 'string'),
));
$v = $this->send($m, $GLOBALS['xmlrpcerr']['server_error']);
$this->client->path = $this->args['URI'] . '?EXCEPTION_HANDLING=1';
$v = $this->send($m, 1); // the error code of the expected exception
$this->client->path = $this->args['URI'] . '?EXCEPTION_HANDLING=2';
// depending on whether display_errors is ON or OFF on the server, we will get back a different error here,
// as php will generate an http status code of either 200 or 500...
$v = $this->send($m, array($GLOBALS['xmlrpcerr']['invalid_return'], $GLOBALS['xmlrpcerr']['http_error']));
}
public function testZeroParams()
{
$m = new xmlrpcmsg('system.listMethods');
$v = $this->send($m);
}
public function testNullParams()
{
$m = new xmlrpcmsg('tests.getStateName.12', array(
new xmlrpcval('whatever', 'null'),
new xmlrpcval(23, 'int'),
));
$v = $this->send($m);
if ($v) {
$this->assertEquals('Michigan', $v->scalarval());
}
$m = new xmlrpcmsg('tests.getStateName.12', array(
new xmlrpcval(23, 'int'),
new xmlrpcval('whatever', 'null'),
));
$v = $this->send($m);
if ($v) {
$this->assertEquals('Michigan', $v->scalarval());
}
$m = new xmlrpcmsg('tests.getStateName.12', array(
new xmlrpcval(23, 'int')
));
$v = $this->send($m, array($GLOBALS['xmlrpcerr']['incorrect_params']));
}
public function testCodeInjectionServerSide()
{
$m = new xmlrpcmsg('system.MethodHelp');
$m->payload = "<?xml version=\"1.0\"?><methodCall><methodName>validator1.echoStructTest</methodName><params><param><value><struct><member><name>','')); echo('gotcha!'); die(); //</name></member></struct></value></param></params></methodCall>";
$v = $this->send($m);
if ($v) {
$this->assertEquals(0, $v->structsize());
}
}
public function testServerWrappedFunction()
{
$m = new xmlrpcmsg('tests.getStateName.2', array(
new xmlrpcval(23, 'int'),
));
$v = $this->send($m);
$this->assertEquals('Michigan', $v->scalarval());
// this generates an exception in the function which was wrapped, which is by default wrapped in a known error response
$m = new xmlrpcmsg('tests.getStateName.2', array(
new xmlrpcval(0, 'int'),
));
$v = $this->send($m, $GLOBALS['xmlrpcerr']['server_error']);
// check if the generated function dispatch map is fine, by checking if the server registered it
$m = new xmlrpcmsg('system.methodSignature', array(
new xmlrpcval('tests.getStateName.2'),
));
$v = $this->send($m);
$encoder = new \PhpXmlRpc\Encoder();
$this->assertEquals(array(array('string', 'int')), $encoder->decode($v));
}
public function testServerWrappedFunctionAsSource()
{
$m = new xmlrpcmsg('tests.getStateName.6', array(
new xmlrpcval(23, 'int'),
));
$v = $this->send($m);
$this->assertEquals('Michigan', $v->scalarval());
// this generates an exception in the function which was wrapped, which is by default wrapped in a known error response
$m = new xmlrpcmsg('tests.getStateName.6', array(
new xmlrpcval(0, 'int'),
));
$v = $this->send($m, $GLOBALS['xmlrpcerr']['server_error']);
}
public function testServerWrappedObjectMethods()
{
$m = new xmlrpcmsg('tests.getStateName.3', array(
new xmlrpcval(23, 'int'),
));
$v = $this->send($m);
$this->assertEquals('Michigan', $v->scalarval());
$m = new xmlrpcmsg('tests.getStateName.4', array(
new xmlrpcval(23, 'int'),
));
$v = $this->send($m);
$this->assertEquals('Michigan', $v->scalarval());
$m = new xmlrpcmsg('tests.getStateName.5', array(
new xmlrpcval(23, 'int'),
));
$v = $this->send($m);
$this->assertEquals('Michigan', $v->scalarval());
$m = new xmlrpcmsg('tests.getStateName.7', array(
new xmlrpcval(23, 'int'),
));
$v = $this->send($m);
$this->assertEquals('Michigan', $v->scalarval());
$m = new xmlrpcmsg('tests.getStateName.8', array(
new xmlrpcval(23, 'int'),
));
$v = $this->send($m);
$this->assertEquals('Michigan', $v->scalarval());
$m = new xmlrpcmsg('tests.getStateName.9', array(
new xmlrpcval(23, 'int'),
));
$v = $this->send($m);
$this->assertEquals('Michigan', $v->scalarval());
}
public function testServerWrappedObjectMethodsAsSource()
{
$m = new xmlrpcmsg('tests.getStateName.7', array(
new xmlrpcval(23, 'int'),
));
$v = $this->send($m);
$this->assertEquals('Michigan', $v->scalarval());
$m = new xmlrpcmsg('tests.getStateName.8', array(
new xmlrpcval(23, 'int'),
));
$v = $this->send($m);
$this->assertEquals('Michigan', $v->scalarval());
$m = new xmlrpcmsg('tests.getStateName.9', array(
new xmlrpcval(23, 'int'),
));
$v = $this->send($m);
$this->assertEquals('Michigan', $v->scalarval());
}
public function testServerClosure()
{
$m = new xmlrpcmsg('tests.getStateName.10', array(
new xmlrpcval(23, 'int'),
));
$v = $this->send($m);
$this->assertEquals('Michigan', $v->scalarval());
}
public function testServerWrappedClosure()
{
$m = new xmlrpcmsg('tests.getStateName.11', array(
new xmlrpcval(23, 'int'),
));
$v = $this->send($m);
$this->assertEquals('Michigan', $v->scalarval());
}
public function testServerWrappedClass()
{
$m = new xmlrpcmsg('tests.xmlrpcServerMethodsContainer.findState', array(
new xmlrpcval(23, 'int'),
));
$v = $this->send($m);
$this->assertEquals('Michigan', $v->scalarval());
}
public function testWrappedMethod()
{
// make a 'deep client copy' as the original one might have many properties set
$func = wrap_xmlrpc_method($this->client, 'examples.getStateName', array('simple_client_copy' => 0));
if ($func == false) {
$this->fail('Registration of examples.getStateName failed');
} else {
$v = $func(23);
// work around bug in current (or old?) version of phpunit when reporting the error
/*if (is_object($v)) {
$v = var_export($v, true);
}*/
$this->assertEquals('Michigan', $v);
}
}
public function testWrappedMethodAsSource()
{
// make a 'deep client copy' as the original one might have many properties set
$func = wrap_xmlrpc_method($this->client, 'examples.getStateName', array('simple_client_copy' => 0, 'return_source' => true));
if ($func == false) {
$this->fail('Registration of examples.getStateName failed');
} else {
eval($func['source']);
$func = $func['function'];
$v = $func(23);
// work around bug in current (or old?) version of phpunit when reporting the error
/*if (is_object($v)) {
$v = var_export($v, true);
}*/
$this->assertEquals('Michigan', $v);
}
}
public function testWrappedClass()
{
// make a 'deep client copy' as the original one might have many properties set
// also for speed only wrap one method of the whole server
$class = wrap_xmlrpc_server($this->client, array('simple_client_copy' => 0, 'method_filter' => '/examples\.getStateName/' ));
if ($class == '') {
$this->fail('Registration of remote server failed');
} else {
$obj = new $class();
$v = $obj->examples_getStateName(23);
// work around bug in current (or old?) version of phpunit when reporting the error
/*if (is_object($v)) {
$v = var_export($v, true);
}*/
$this->assertEquals('Michigan', $v);
}
}
public function testTransferOfObjectViaWrapping()
{
// make a 'deep client copy' as the original one might have many properties set
$func = wrap_xmlrpc_method($this->client, 'tests.returnPhpObject', array('simple_client_copy' => true,
'decode_php_objs' => true));
if ($func == false) {
$this->fail('Registration of tests.returnPhpObject failed');
} else {
$v = $func();
$obj = new stdClass();
$obj->hello = 'world';
$this->assertEquals($obj, $v);
}
}
public function testGetCookies()
{
// let server set to us some cookies we tell it
$cookies = array(
//'c1' => array(),
'c2' => array('value' => 'c2'),
'c3' => array('value' => 'c3', 'expires' => time() + 60 * 60 * 24 * 30),
'c4' => array('value' => 'c4', 'expires' => time() + 60 * 60 * 24 * 30, 'path' => '/'),
'c5' => array('value' => 'c5', 'expires' => time() + 60 * 60 * 24 * 30, 'path' => '/', 'domain' => 'localhost'),
);
$cookiesval = php_xmlrpc_encode($cookies);
$m = new xmlrpcmsg('examples.setcookies', array($cookiesval));
$r = $this->send($m, 0, true);
if ($r) {
$v = $r->value();
$this->assertEquals(1, $v->scalarval());
// now check if we decoded the cookies as we had set them
$rcookies = $r->cookies();
// remove extra cookies which might have been set by proxies
foreach ($rcookies as $c => $v) {
if (!in_array($c, array('c2', 'c3', 'c4', 'c5'))) {
unset($rcookies[$c]);
}
// Seems like we get this when using php-fpm and php 5.5+ ...
if (isset($rcookies[$c]['Max-Age'])) {
unset($rcookies[$c]['Max-Age']);
}
}
foreach ($cookies as $c => $v) {
// format for date string in cookies: 'Mon, 31 Oct 2005 13:50:56 GMT'
// but PHP versions differ on that, some use 'Mon, 31-Oct-2005 13:50:56 GMT'...
if (isset($v['expires'])) {
if (isset($rcookies[$c]['expires']) && strpos($rcookies[$c]['expires'], '-')) {
$cookies[$c]['expires'] = gmdate('D, d\-M\-Y H:i:s \G\M\T', $cookies[$c]['expires']);
} else {
$cookies[$c]['expires'] = gmdate('D, d M Y H:i:s \G\M\T', $cookies[$c]['expires']);
}
}
}
$this->assertEquals($cookies, $rcookies);
}
}
public function testSetCookies()
{
// let server set to us some cookies we tell it
$cookies = array(
'c0' => null,
'c1' => 1,
'c2' => '2 3',
'c3' => '!@#$%^&*()_+|}{":?><,./\';[]\\=-',
);
$m = new xmlrpcmsg('examples.getcookies', array());
foreach ($cookies as $cookie => $val) {
$this->client->setCookie($cookie, $val);
$cookies[$cookie] = (string)$cookies[$cookie];
}
$r = $this->client->send($m, $this->timeout, $this->method);
$this->assertEquals(0, $r->faultCode(), 'Error ' . $r->faultCode() . ' connecting to server: ' . $r->faultString());
if (!$r->faultCode()) {
$v = $r->value();
$v = php_xmlrpc_decode($v);
// take care for the extra cookie used for coverage collection
if (isset($v['PHPUNIT_SELENIUM_TEST_ID'])) {
unset($v['PHPUNIT_SELENIUM_TEST_ID']);
}
// on IIS and Apache getallheaders returns something slightly different...
$this->assertEquals($cookies, $v);
}
}
public function testServerComments()
{
$m = new xmlrpcmsg('tests.xmlrpcServerMethodsContainer.debugMessageGenerator', array(
new xmlrpcval('hello world', 'string'),
));
$r = $this->send($m, 0, true);
$this->assertContains('hello world', $r->raw_data);
}
public function testSendTwiceSameMsg()
{
$m = new xmlrpcmsg('examples.stringecho', array(
new xmlrpcval('hello world', 'string'),
));
$v1 = $this->send($m);
$v2 = $this->send($m);
if ($v1 && $v2) {
$this->assertEquals($v1, $v2);
}
}
}

View File

@@ -0,0 +1,215 @@
<?php
include_once __DIR__ . '/../lib/xmlrpc.inc';
include_once __DIR__ . '/../lib/xmlrpc_wrappers.inc';
include_once __DIR__ . '/parse_args.php';
include_once __DIR__ . '/3LocalhostTest.php';
/**
* Tests which stress http features of the library.
* Each of these tests iterates over (almost) all of the 'localhost' tests
*/
class LocalhostMultiTest extends LocalhostTest
{
/**
* @todo reintroduce skipping of tests which failed when executed individually if test runs happen as separate processes
* @todo reintroduce skipping of tests within the loop
*/
function _runtests()
{
$unsafeMethods = array('testHttps', 'testCatchExceptions', 'testUtf8Method', 'testServerComments', 'testExoticCharsetsRequests', 'testExoticCharsetsRequests2', 'testExoticCharsetsRequests3');
foreach(get_class_methods('LocalhostTest') as $method)
{
if(strpos($method, 'test') === 0 && !in_array($method, $unsafeMethods))
{
if (!isset(self::$failed_tests[$method]))
$this->$method();
}
/*if ($this->_failed)
{
break;
}*/
}
}
function testDeflate()
{
if(!function_exists('gzdeflate'))
{
$this->markTestSkipped('Zlib missing: cannot test deflate functionality');
return;
}
$this->client->accepted_compression = array('deflate');
$this->client->request_compression = 'deflate';
$this->_runtests();
}
function testGzip()
{
if(!function_exists('gzdeflate'))
{
$this->markTestSkipped('Zlib missing: cannot test gzip functionality');
return;
}
$this->client->accepted_compression = array('gzip');
$this->client->request_compression = 'gzip';
$this->_runtests();
}
function testKeepAlives()
{
if(!function_exists('curl_init'))
{
$this->markTestSkipped('CURL missing: cannot test http 1.1');
return;
}
$this->method = 'http11';
$this->client->keepalive = true;
$this->_runtests();
}
function testProxy()
{
if ($this->args['PROXYSERVER'])
{
$this->client->setProxy($this->args['PROXYSERVER'], $this->args['PROXYPORT']);
$this->_runtests();
}
else
$this->markTestSkipped('PROXY definition missing: cannot test proxy');
}
function testHttp11()
{
if(!function_exists('curl_init'))
{
$this->markTestSkipped('CURL missing: cannot test http 1.1');
return;
}
$this->method = 'http11'; // not an error the double assignment!
$this->client->method = 'http11';
//$this->client->verifyhost = 0;
//$this->client->verifypeer = 0;
$this->client->keepalive = false;
$this->_runtests();
}
function testHttp11Gzip()
{
if(!function_exists('curl_init'))
{
$this->markTestSkipped('CURL missing: cannot test http 1.1');
return;
}
$this->method = 'http11'; // not an error the double assignment!
$this->client->method = 'http11';
$this->client->keepalive = false;
$this->client->accepted_compression = array('gzip');
$this->client->request_compression = 'gzip';
$this->_runtests();
}
function testHttp11Deflate()
{
if(!function_exists('curl_init'))
{
$this->markTestSkipped('CURL missing: cannot test http 1.1');
return;
}
$this->method = 'http11'; // not an error the double assignment!
$this->client->method = 'http11';
$this->client->keepalive = false;
$this->client->accepted_compression = array('deflate');
$this->client->request_compression = 'deflate';
$this->_runtests();
}
function testHttp11Proxy()
{
if(!function_exists('curl_init'))
{
$this->markTestSkipped('CURL missing: cannot test http 1.1 w. proxy');
return;
}
else if ($this->args['PROXYSERVER'] == '')
{
$this->markTestSkipped('PROXY definition missing: cannot test proxy w. http 1.1');
return;
}
$this->method = 'http11'; // not an error the double assignment!
$this->client->method = 'http11';
$this->client->setProxy($this->args['PROXYSERVER'], $this->args['PROXYPORT']);
//$this->client->verifyhost = 0;
//$this->client->verifypeer = 0;
$this->client->keepalive = false;
$this->_runtests();
}
function testHttps()
{
if(!function_exists('curl_init'))
{
$this->markTestSkipped('CURL missing: cannot test https functionality');
return;
}
$this->client->server = $this->args['HTTPSSERVER'];
$this->method = 'https';
$this->client->method = 'https';
$this->client->path = $this->args['HTTPSURI'];
$this->client->setSSLVerifyPeer(!$this->args['HTTPSIGNOREPEER']);
$this->client->setSSLVerifyHost($this->args['HTTPSVERIFYHOST']);
$this->client->setSSLVersion($this->args['SSLVERSION']);
$this->_runtests();
}
function testHttpsProxy()
{
if(!function_exists('curl_init'))
{
$this->markTestSkipped('CURL missing: cannot test https functionality');
return;
}
else if ($this->args['PROXYSERVER'] == '')
{
$this->markTestSkipped('PROXY definition missing: cannot test proxy w. http 1.1');
return;
}
$this->client->server = $this->args['HTTPSSERVER'];
$this->method = 'https';
$this->client->method = 'https';
$this->client->setProxy($this->args['PROXYSERVER'], $this->args['PROXYPORT']);
$this->client->path = $this->args['HTTPSURI'];
$this->client->setSSLVerifyPeer(!$this->args['HTTPSIGNOREPEER']);
$this->client->setSSLVerifyHost($this->args['HTTPSVERIFYHOST']);
$this->client->setSSLVersion($this->args['SSLVERSION']);
$this->_runtests();
}
function testUTF8Responses()
{
//$this->client->path = strpos($URI, '?') === null ? $URI.'?RESPONSE_ENCODING=UTF-8' : $URI.'&RESPONSE_ENCODING=UTF-8';
$this->client->path = $this->args['URI'].'?RESPONSE_ENCODING=UTF-8';
$this->_runtests();
}
function testUTF8Requests()
{
$this->client->request_charset_encoding = 'UTF-8';
$this->_runtests();
}
function testISOResponses()
{
//$this->client->path = strpos($URI, '?') === null ? $URI.'?RESPONSE_ENCODING=UTF-8' : $URI.'&RESPONSE_ENCODING=UTF-8';
$this->client->path = $this->args['URI'].'?RESPONSE_ENCODING=ISO-8859-1';
$this->_runtests();
}
function testISORequests()
{
$this->client->request_charset_encoding = 'ISO-8859-1';
$this->_runtests();
}
}

View File

@@ -0,0 +1,76 @@
<?php
include_once __DIR__ . '/LocalFileTestCase.php';
/**
* Tests for php files in the 'demo' directory
*/
class DemoFilesTest extends PhpXmlRpc_LocalFileTestCase
{
public function setUp()
{
$this->args = argParser::getArgs();
$this->baseUrl = $this->args['LOCALSERVER'] . str_replace( '/demo/server/server.php', '/demo/', $this->args['URI'] );
$this->coverageScriptUrl = 'http://' . $this->args['LOCALSERVER'] . '/' . str_replace( '/demo/server/server.php', 'tests/phpunit_coverage.php', $this->args['URI'] );
}
public function testAgeSort()
{
$page = $this->request('client/agesort.php');
}
public function testGetStateName()
{
$page = $this->request('client/getstatename.php');
$page = $this->request('client/getstatename.php', 'POST', array('stateno' => '1'));
}
public function testIntrospect()
{
$page = $this->request('client/introspect.php');
}
public function testMail()
{
$page = $this->request('client/mail.php');
$page = $this->request('client/mail.php', 'POST', array(
"mailto" => '',
"mailsub" => '',
"mailmsg" => '',
"mailfrom" => '',
"mailcc" => '',
"mailbcc" => '',
));
}
public function testProxy()
{
$page = $this->request('client/proxy.php', 'GET', null, true);
}
public function testWhich()
{
$page = $this->request('client/which.php');
}
public function testWrap()
{
$page = $this->request('client/wrap.php');
}
public function testDiscussServer()
{
$page = $this->request('server/discuss.php');
$this->assertContains('<name>faultCode</name>', $page);
$this->assertRegexp('#<int>10(5|3)</int>#', $page);
}
public function testProxyServer()
{
$page = $this->request('server/proxy.php');
$this->assertContains('<name>faultCode</name>', $page);
$this->assertRegexp('#<int>10(5|3)</int>#', $page);
}
}

View File

@@ -0,0 +1,37 @@
<?php
include_once __DIR__ . '/LocalFileTestCase.php';
class DebuggerTest extends PhpXmlRpc_LocalFileTestCase
{
public function setUp()
{
$this->args = argParser::getArgs();
$this->baseUrl = $this->args['LOCALSERVER'] . str_replace( '/demo/server/server.php', '/debugger/', $this->args['URI'] );
$this->coverageScriptUrl = 'http://' . $this->args['LOCALSERVER'] . '/' . str_replace( '/demo/server/server.php', 'tests/phpunit_coverage.php', $this->args['URI'] );
}
public function testIndex()
{
$page = $this->request('index.php');
}
public function testController()
{
$page = $this->request('controller.php');
}
/**
* @todo test:
* - list methods
* - describe a method
* - execute a method
* - wrap a method
*/
public function testAction()
{
$page = $this->request('action.php');
}
}

View File

@@ -0,0 +1,23 @@
<?php
include_once __DIR__ . '/LocalFileTestCase.php';
/**
* Tests for php files in the 'extras' directory
*/
class ExtraTest extends PhpXmlRpc_LocalFileTestCase
{
public function setUp()
{
$this->args = argParser::getArgs();
$this->baseUrl = $this->args['LOCALSERVER'] . str_replace( '/demo/server/server.php', '/tests/', $this->args['URI'] );
$this->coverageScriptUrl = 'http://' . $this->args['LOCALSERVER'] . '/' . str_replace( '/demo/server/server.php', 'tests/phpunit_coverage.php', $this->args['URI'] );
}
public function testVerifyCompat()
{
$page = $this->request('verify_compat.php');
}
}

View File

@@ -0,0 +1,80 @@
<?php
include_once __DIR__ . '/parse_args.php';
abstract class PhpXmlRpc_LocalFileTestCase extends PHPUnit_Framework_TestCase
{
public $args = array();
protected $baseUrl;
protected $testId;
/** @var boolean $collectCodeCoverageInformation */
protected $collectCodeCoverageInformation;
protected $coverageScriptUrl;
public function run(PHPUnit_Framework_TestResult $result = NULL)
{
$this->testId = get_class($this) . '__' . $this->getName();
if ($result === NULL) {
$result = $this->createResult();
}
$this->collectCodeCoverageInformation = $result->getCollectCodeCoverageInformation();
parent::run($result);
if ($this->collectCodeCoverageInformation) {
$coverage = new PHPUnit_Extensions_SeleniumCommon_RemoteCoverage(
$this->coverageScriptUrl,
$this->testId
);
$result->getCodeCoverage()->append(
$coverage->get(), $this
);
}
// do not call this before to give the time to the Listeners to run
//$this->getStrategy()->endOfTest($this->session);
return $result;
}
protected function request($file, $method = 'GET', $payload = '', $emptyPageOk = false)
{
$url = $this->baseUrl . $file;
$ch = curl_init($url);
curl_setopt_array($ch, array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FAILONERROR => true
));
if ($method == 'POST')
{
curl_setopt_array($ch, array(
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $payload
));
}
if ($this->collectCodeCoverageInformation)
{
curl_setopt($ch, CURLOPT_COOKIE, 'PHPUNIT_SELENIUM_TEST_ID=true');
}
if ($this->args['DEBUG'] > 0) {
curl_setopt($ch, CURLOPT_VERBOSE, 1);
}
$page = curl_exec($ch);
curl_close($ch);
$this->assertNotFalse($page);
if (!$emptyPageOk) {
$this->assertNotEquals('', $page);
}
$this->assertNotContains('Fatal error', $page);
$this->assertNotContains('Notice:', $page);
return $page;
}
}

View File

@@ -0,0 +1,311 @@
<?php
/**
* Benchmarking suite for the PHP-XMLRPC lib.
*
* @author Gaetano Giunta
* @copyright (c) 2005-2015 G. Giunta
* @license code licensed under the BSD License: see file license.txt
*
* @todo add a test for response ok in call testing
* @todo add support for --help option to give users the list of supported parameters
**/
use PhpXmlRpc\PhpXmlRpc;
use PhpXmlRpc\Value;
use PhpXmlRpc\Request;
use PhpXmlRpc\Client;
use PhpXmlRpc\Response;
use PhpXmlRpc\Encoder;
include_once __DIR__ . '/../vendor/autoload.php';
include __DIR__ . '/parse_args.php';
$args = argParser::getArgs();
function begin_test($test_name, $test_case)
{
global $test_results;
if (!isset($test_results[$test_name])) {
$test_results[$test_name] = array();
}
$test_results[$test_name][$test_case] = array();
$test_results[$test_name][$test_case]['time'] = microtime(true);
}
function end_test($test_name, $test_case, $test_result)
{
global $test_results;
$end = microtime(true);
if (!isset($test_results[$test_name][$test_case])) {
trigger_error('ending test that was not started');
}
$test_results[$test_name][$test_case]['time'] = $end - $test_results[$test_name][$test_case]['time'];
$test_results[$test_name][$test_case]['result'] = $test_result;
echo '.';
flush();
@ob_flush();
}
// Set up PHP structures to be used in many tests
$data1 = array(1, 1.0, 'hello world', true, '20051021T23:43:00', -1, 11.0, '~!@#$%^&*()_+|', false, '20051021T23:43:00');
$data2 = array('zero' => $data1, 'one' => $data1, 'two' => $data1, 'three' => $data1, 'four' => $data1, 'five' => $data1, 'six' => $data1, 'seven' => $data1, 'eight' => $data1, 'nine' => $data1);
$data = array($data2, $data2, $data2, $data2, $data2, $data2, $data2, $data2, $data2, $data2);
$keys = array('zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine');
// Begin execution
$test_results = array();
$is_web = isset($_SERVER['REQUEST_METHOD']);
$xd = extension_loaded('xdebug') && ini_get('xdebug.profiler_enable');
if ($xd) {
$num_tests = 1;
} else {
$num_tests = 10;
}
$title = 'XML-RPC Benchmark Tests';
if ($is_web) {
echo "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"en\" xml:lang=\"en\">\n<head>\n<title>$title</title>\n</head>\n<body>\n<h1>$title</h1>\n<pre>\n";
} else {
echo "$title\n\n";
}
if ($is_web) {
echo "<h3>Using lib version: " . PhpXmlRpc::$xmlrpcVersion . " on PHP version: " . phpversion() . "</h3>\n";
if ($xd) {
echo "<h4>XDEBUG profiling enabled: skipping remote tests. Trace file is: " . htmlspecialchars(xdebug_get_profiler_filename()) . "</h4>\n";
}
flush();
ob_flush();
} else {
echo "Using lib version: " . PhpXmlRpc::$xmlrpcVersion . " on PHP version: " . phpversion() . "\n";
if ($xd) {
echo "XDEBUG profiling enabled: skipping remote tests\nTrace file is: " . xdebug_get_profiler_filename() . "\n";
}
}
// test 'manual style' data encoding vs. 'automatic style' encoding
begin_test('Data encoding (large array)', 'manual encoding');
for ($i = 0; $i < $num_tests; $i++) {
$vals = array();
for ($j = 0; $j < 10; $j++) {
$valarray = array();
foreach ($data[$j] as $key => $val) {
$values = array();
$values[] = new Value($val[0], 'int');
$values[] = new Value($val[1], 'double');
$values[] = new Value($val[2], 'string');
$values[] = new Value($val[3], 'boolean');
$values[] = new Value($val[4], 'dateTime.iso8601');
$values[] = new Value($val[5], 'int');
$values[] = new Value($val[6], 'double');
$values[] = new Value($val[7], 'string');
$values[] = new Value($val[8], 'boolean');
$values[] = new Value($val[9], 'dateTime.iso8601');
$valarray[$key] = new Value($values, 'array');
}
$vals[] = new Value($valarray, 'struct');
}
$value = new Value($vals, 'array');
$out = $value->serialize();
}
end_test('Data encoding (large array)', 'manual encoding', $out);
begin_test('Data encoding (large array)', 'automatic encoding');
$encoder = new Encoder();
for ($i = 0; $i < $num_tests; $i++) {
$value = $encoder->encode($data, array('auto_dates'));
$out = $value->serialize();
}
end_test('Data encoding (large array)', 'automatic encoding', $out);
if (function_exists('xmlrpc_set_type')) {
begin_test('Data encoding (large array)', 'xmlrpc-epi encoding');
for ($i = 0; $i < $num_tests; $i++) {
for ($j = 0; $j < 10; $j++) {
foreach ($keys as $k) {
xmlrpc_set_type($data[$j][$k][4], 'datetime');
xmlrpc_set_type($data[$j][$k][8], 'datetime');
}
}
$out = xmlrpc_encode($data);
}
end_test('Data encoding (large array)', 'xmlrpc-epi encoding', $out);
}
// test 'old style' data decoding vs. 'automatic style' decoding
$dummy = new Request('');
$out = new Response($value);
$in = '<?xml version="1.0" ?>' . "\n" . $out->serialize();
begin_test('Data decoding (large array)', 'manual decoding');
for ($i = 0; $i < $num_tests; $i++) {
$response = $dummy->ParseResponse($in, true);
$value = $response->value();
$result = array();
foreach($value as $val1) {
$out = array();
foreach($val1 as $name => $val) {
$out[$name] = array();
foreach($val as $data) {
$out[$name][] = $data->scalarval();
}
}
$result[] = $out;
}
}
end_test('Data decoding (large array)', 'manual decoding', $result);
begin_test('Data decoding (large array)', 'manual decoding deprecated');
for ($i = 0; $i < $num_tests; $i++) {
$response = $dummy->ParseResponse($in, true);
$value = $response->value();
$result = array();
$l = $value->arraysize();
for ($k = 0; $k < $l; $k++) {
$val1 = $value->arraymem($k);
$out = array();
while (list($name, $val) = $val1->structeach()) {
$out[$name] = array();
$m = $val->arraysize();
for ($j = 0; $j < $m; $j++) {
$data = $val->arraymem($j);
$out[$name][] = $data->scalarval();
}
} // while
$result[] = $out;
}
}
end_test('Data decoding (large array)', 'manual decoding deprecated', $result);
begin_test('Data decoding (large array)', 'automatic decoding');
for ($i = 0; $i < $num_tests; $i++) {
$response = $dummy->ParseResponse($in, true, 'phpvals');
$value = $response->value();
}
end_test('Data decoding (large array)', 'automatic decoding', $value);
if (function_exists('xmlrpc_decode')) {
begin_test('Data decoding (large array)', 'xmlrpc-epi decoding');
for ($i = 0; $i < $num_tests; $i++) {
$response = $dummy->ParseResponse($in, true, 'xml');
$value = xmlrpc_decode($response->value());
}
end_test('Data decoding (large array)', 'xmlrpc-epi decoding', $value);
}
if (!$xd) {
/// test multicall vs. many calls vs. keep-alives
$encoder = new Encoder();
$value = $encoder->encode($data1, array('auto_dates'));
$req = new Request('interopEchoTests.echoValue', array($value));
$reqs = array();
for ($i = 0; $i < 25; $i++) {
$reqs[] = $req;
}
$server = explode(':', $args['LOCALSERVER']);
if (count($server) > 1) {
$srv = $server[1] . '://' . $server[0] . $args['URI'];
$c = new Client($args['URI'], $server[0], $server[1]);
} else {
$srv = $args['LOCALSERVER'] . $args['URI'];
$c = new Client($args['URI'], $args['LOCALSERVER']);
}
// do not interfere with http compression
$c->accepted_compression = array();
//$c->debug=true;
$testName = "Repeated send (small array) to $srv";
if (function_exists('gzinflate')) {
$c->accepted_compression = null;
}
begin_test($testName, 'http 10');
$response = array();
for ($i = 0; $i < 25; $i++) {
$resp = $c->send($req);
$response[] = $resp->value();
}
end_test($testName, 'http 10', $response);
if (function_exists('curl_init')) {
begin_test($testName, 'http 11 w. keep-alive');
$response = array();
for ($i = 0; $i < 25; $i++) {
$resp = $c->send($req, 10, 'http11');
$response[] = $resp->value();
}
end_test($testName, 'http 11 w. keep-alive', $response);
$c->keepalive = false;
begin_test($testName, 'http 11');
$response = array();
for ($i = 0; $i < 25; $i++) {
$resp = $c->send($req, 10, 'http11');
$response[] = $resp->value();
}
end_test($testName, 'http 11', $response);
}
begin_test($testName, 'multicall');
$response = $c->send($reqs);
foreach ($response as $key => & $val) {
$val = $val->value();
}
end_test($testName, 'multicall', $response);
if (function_exists('gzinflate')) {
$c->accepted_compression = array('gzip');
$c->request_compression = 'gzip';
begin_test($testName, 'http 10 w. compression');
$response = array();
for ($i = 0; $i < 25; $i++) {
$resp = $c->send($req);
$response[] = $resp->value();
}
end_test($testName, 'http 10 w. compression', $response);
if (function_exists('curl_init')) {
begin_test($testName, 'http 11 w. keep-alive and compression');
$response = array();
for ($i = 0; $i < 25; $i++) {
$resp = $c->send($req, 10, 'http11');
$response[] = $resp->value();
}
end_test($testName, 'http 11 w. keep-alive and compression', $response);
$c->keepalive = false;
begin_test($testName, 'http 11 w. compression');
$response = array();
for ($i = 0; $i < 25; $i++) {
$resp = $c->send($req, 10, 'http11');
$response[] = $resp->value();
}
end_test($testName, 'http 11 w. compression', $response);
}
begin_test($testName, 'multicall w. compression');
$response = $c->send($reqs);
foreach ($response as $key => & $val) {
$val = $val->value();
}
end_test($testName, 'multicall w. compression', $response);
}
} // end of 'if no xdebug profiling'
echo "\n";
foreach ($test_results as $test => $results) {
echo "\nTEST: $test\n";
foreach ($results as $case => $data) {
echo " $case: {$data['time']} secs - Output data CRC: " . crc32(serialize($data['result'])) . "\n";
}
}
if ($is_web) {
echo "\n</pre>\n</body>\n</html>\n";
}

View File

@@ -0,0 +1,68 @@
# Configuration file for Apache running on Travis.
# PHP setup in FCGI mode
<VirtualHost *:80>
DocumentRoot %TRAVIS_BUILD_DIR%
ErrorLog "%TRAVIS_BUILD_DIR%/apache_error.log"
CustomLog "%TRAVIS_BUILD_DIR%/apache_access.log" combined
<Directory "%TRAVIS_BUILD_DIR%">
Options FollowSymLinks MultiViews ExecCGI
AllowOverride All
Order deny,allow
Allow from all
</Directory>
# Wire up Apache to use Travis CI's php-fpm.
<IfModule mod_fastcgi.c>
AddHandler php5-fcgi .php
Action php5-fcgi /php5-fcgi
Alias /php5-fcgi /usr/lib/cgi-bin/php5-fcgi
FastCgiExternalServer /usr/lib/cgi-bin/php5-fcgi -host 127.0.0.1:9000 -pass-header Authorization
</IfModule>
</VirtualHost>
<IfModule mod_ssl.c>
<VirtualHost _default_:443>
DocumentRoot %TRAVIS_BUILD_DIR%
ErrorLog "%TRAVIS_BUILD_DIR%/apache_error.log"
CustomLog "%TRAVIS_BUILD_DIR%/apache_access.log" combined
<Directory "%TRAVIS_BUILD_DIR%">
Options FollowSymLinks MultiViews ExecCGI
AllowOverride All
Order deny,allow
Allow from all
</Directory>
# Wire up Apache to use Travis CI's php-fpm.
<IfModule mod_fastcgi.c>
AddHandler php5-fcgi .php
Action php5-fcgi /php5-fcgi
Alias /php5-fcgi /usr/lib/cgi-bin/php5-fcgi
#FastCgiExternalServer /usr/lib/cgi-bin/php5-fcgi -host 127.0.0.1:9000 -pass-header Authorization
</IfModule>
SSLEngine on
# This cert is bundled by default in Ubuntu
SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
<FilesMatch "\.(cgi|shtml|phtml|php)$">
SSLOptions +StdEnvVars
</FilesMatch>
BrowserMatch "MSIE [2-6]" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown
</VirtualHost>
</IfModule>

View File

@@ -0,0 +1,74 @@
# Configuration file for Apache running on Travis.
# HHVM setup in FCGI mode
<VirtualHost *:80>
DocumentRoot %TRAVIS_BUILD_DIR%
ErrorLog "%TRAVIS_BUILD_DIR%/apache_error.log"
CustomLog "%TRAVIS_BUILD_DIR%/apache_access.log" combined
<Directory "%TRAVIS_BUILD_DIR%">
Options FollowSymLinks MultiViews ExecCGI
AllowOverride All
Order deny,allow
Allow from all
</Directory>
# Configure Apache for HHVM FastCGI.
# See https://github.com/facebook/hhvm/wiki/fastcgi
<IfModule mod_fastcgi.c>
<FilesMatch \.php$>
SetHandler hhvm-php-extension
</FilesMatch>
Alias /hhvm /hhvm
Action hhvm-php-extension /hhvm virtual
FastCgiExternalServer /hhvm -host 127.0.0.1:9000 -pass-header Authorization -idle-timeout 300
</IfModule>
</VirtualHost>
<IfModule mod_ssl.c>
<VirtualHost _default_:443>
DocumentRoot %TRAVIS_BUILD_DIR%
ErrorLog "%TRAVIS_BUILD_DIR%/apache_error.log"
CustomLog "%TRAVIS_BUILD_DIR%/apache_access.log" combined
<Directory "%TRAVIS_BUILD_DIR%">
Options FollowSymLinks MultiViews ExecCGI
AllowOverride All
Order deny,allow
Allow from all
</Directory>
# Configure Apache for HHVM FastCGI.
# See https://github.com/facebook/hhvm/wiki/fastcgi
<IfModule mod_fastcgi.c>
<FilesMatch \.php$>
SetHandler hhvm-php-extension
</FilesMatch>
Alias /hhvm /hhvm
Action hhvm-php-extension /hhvm virtual
#FastCgiExternalServer /hhvm -host 127.0.0.1:9000 -pass-header Authorization -idle-timeout 300
</IfModule>
SSLEngine on
# This cert is bundled by default in Ubuntu
SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
<FilesMatch "\.(cgi|shtml|phtml|php)$">
SSLOptions +StdEnvVars
</FilesMatch>
BrowserMatch "MSIE [2-6]" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown
</VirtualHost>
</IfModule>

View File

@@ -0,0 +1 @@
listen-address 127.0.0.1:8080

View File

@@ -0,0 +1,11 @@
#!/bin/sh
# set up Apache for php-fpm
# @see https://github.com/travis-ci/travis-ci.github.com/blob/master/docs/user/languages/php.md#apache--php
sudo a2enmod rewrite actions fastcgi alias ssl
# configure apache virtual hosts
sudo cp -f tests/ci/travis/apache_vhost /etc/apache2/sites-available/default
sudo sed -e "s?%TRAVIS_BUILD_DIR%?$(pwd)?g" --in-place /etc/apache2/sites-available/default
sudo service apache2 restart

View File

@@ -0,0 +1,11 @@
#!/bin/sh
# set up Apache for hhvm-fcgi
# @see https://github.com/travis-ci/travis-ci.github.com/blob/master/docs/user/languages/php.md#apache--php
sudo a2enmod rewrite actions fastcgi alias ssl
# configure apache virtual hosts
sudo cp -f tests/ci/travis/apache_vhost_hhvm /etc/apache2/sites-available/default
sudo sed -e "s?%TRAVIS_BUILD_DIR%?$(pwd)?g" --in-place /etc/apache2/sites-available/default
sudo service apache2 restart

View File

@@ -0,0 +1,4 @@
#!/bin/sh
# start HHVM
hhvm -m daemon -vServer.Type=fastcgi -vServer.Port=9000 -vServer.FixPathInfo=true

View File

@@ -0,0 +1,11 @@
#!/bin/sh
# enable php-fpm
sudo cp ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.conf.default ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.conf
# work around travis issue #3385
if [ "$TRAVIS_PHP_VERSION" = "7.0" -a -n "$(ls -A ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.d)" ]; then
sudo cp ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.d/www.conf.default ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.d/www.conf
fi
echo "cgi.fix_pathinfo = 1" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
echo "always_populate_raw_post_data = -1" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
~/.phpenv/versions/$(phpenv version-name)/sbin/php-fpm

View File

@@ -0,0 +1,6 @@
#!/bin/sh
# configure privoxy
sudo cp -f tests/ci/travis/privoxy /etc/privoxy/config
sudo service privoxy restart

View File

@@ -0,0 +1,124 @@
<?php
/**
* Common parameter parsing for benchmark and tests scripts.
*
* @param integer DEBUG
* @param string LOCALSERVER
* @param string URI
* @param string HTTPSSERVER
* @param string HTTPSSURI
* @param string PROXY
* @param string NOPROXY
* @param bool HTTPSIGNOREPEER
* @param int HTTPSVERIFYHOST
* @param int SSLVERSION
*
* @copyright (C) 2007-2015 G. Giunta
* @license code licensed under the BSD License: see file license.txt
**/
class argParser
{
public static function getArgs()
{
global $argv;
$args = array(
'DEBUG' => 0,
'LOCALSERVER' => 'localhost',
'HTTPSSERVER' => 'gggeek.ssl.altervista.org',
'HTTPSURI' => '/sw/xmlrpc/demo/server/server.php',
'HTTPSIGNOREPEER' => false,
'HTTPSVERIFYHOST' => 2,
'SSLVERSION' => 0,
'PROXYSERVER' => null,
'NOPROXY' => false,
'LOCALPATH' => __DIR__,
);
// check for command line vs web page input params
if (!isset($_SERVER['REQUEST_METHOD'])) {
if (isset($argv)) {
foreach ($argv as $param) {
$param = explode('=', $param);
if (count($param) > 1) {
$pname = strtoupper(ltrim($param[0], '-'));
$$pname = $param[1];
}
}
}
} else {
// NB: we might as well consider using $_GET stuff later on...
extract($_GET);
extract($_POST);
}
if (isset($DEBUG)) {
$args['DEBUG'] = intval($DEBUG);
}
if (isset($LOCALSERVER)) {
$args['LOCALSERVER'] = $LOCALSERVER;
} else {
if (isset($HTTP_HOST)) {
$args['LOCALSERVER'] = $HTTP_HOST;
} elseif (isset($_SERVER['HTTP_HOST'])) {
$args['LOCALSERVER'] = $_SERVER['HTTP_HOST'];
}
}
if (isset($HTTPSSERVER)) {
$args['HTTPSSERVER'] = $HTTPSSERVER;
}
if (isset($HTTPSURI)) {
$args['HTTPSURI'] = $HTTPSURI;
}
if (isset($HTTPSIGNOREPEER)) {
$args['HTTPSIGNOREPEER'] = (bool)$HTTPSIGNOREPEER;
}
if (isset($HTTPSVERIFYHOST)) {
$args['HTTPSVERIFYHOST'] = (int)$HTTPSVERIFYHOST;
}
if (isset($SSLVERSION)) {
$args['SSLVERSION'] = (int)$SSLVERSION;
}
if (isset($PROXY)) {
$arr = explode(':', $PROXY);
$args['PROXYSERVER'] = $arr[0];
if (count($arr) > 1) {
$args['PROXYPORT'] = $arr[1];
} else {
$args['PROXYPORT'] = 8080;
}
}
// used to silence testsuite warnings about proxy code not being tested
if (isset($NOPROXY)) {
$args['NOPROXY'] = true;
}
if (!isset($URI)) {
// GUESTIMATE the url of local demo server
// play nice to php 3 and 4-5 in retrieving URL of server.php
/// @todo filter out query string from REQUEST_URI
if (isset($REQUEST_URI)) {
$URI = str_replace('/tests/testsuite.php', '/demo/server/server.php', $REQUEST_URI);
$URI = str_replace('/testsuite.php', '/server.php', $URI);
$URI = str_replace('/tests/benchmark.php', '/demo/server/server.php', $URI);
$URI = str_replace('/benchmark.php', '/server.php', $URI);
} elseif (isset($_SERVER['PHP_SELF']) && isset($_SERVER['REQUEST_METHOD'])) {
$URI = str_replace('/tests/testsuite.php', '/demo/server/server.php', $_SERVER['PHP_SELF']);
$URI = str_replace('/testsuite.php', '/server.php', $URI);
$URI = str_replace('/tests/benchmark.php', '/demo/server/server.php', $URI);
$URI = str_replace('/benchmark.php', '/server.php', $URI);
} else {
$URI = '/demo/server/server.php';
}
}
if ($URI[0] != '/') {
$URI = '/' . $URI;
}
$args['URI'] = $URI;
if (isset($LOCALPATH)) {
$args['LOCALPATH'] = $LOCALPATH;
}
return $args;
}
}

View File

@@ -0,0 +1,16 @@
<?php
/**
* Used to serve back the server-side code coverage results to phpunit-selenium
*
* @copyright (C) 2007-2015 G. Giunta
* @license code licensed under the BSD License: see file license.txt
**/
$coverageFile = realpath(__DIR__ . "/../vendor/phpunit/phpunit-selenium/PHPUnit/Extensions/SeleniumCommon/phpunit_coverage.php");
// has to be the same value as used in server.php
$GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY'] = '/tmp/phpxmlrpc_coverage';
chdir($GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY']);
include_once $coverageFile;

View File

@@ -0,0 +1,193 @@
<?php
/**
* Verify compatibility level of current php install with php-xmlrpc lib.
*
* @author Gaetano Giunta
* @copyright (C) 2006-2015 G. Giunta
* @license code licensed under the BSD License: see file license.txt
*
* @todo add a test for php output buffering?
*/
function phpxmlrpc_verify_compat($mode = 'client')
{
$tests = array();
if ($mode == 'server') {
// test for php version
$ver = phpversion();
$tests['php_version'] = array();
$tests['php_version']['description'] = 'PHP version found: ' . $ver . ".\n\n";
if (version_compare($ver, '5.3.0') < 0) {
$tests['php_version']['status'] = 0;
$tests['php_version']['description'] .= 'This version of PHP is not compatible with this release of the PHP XMLRPC library. Please upgrade to php 5.1.0 or later';
} else {
$tests['php_version']['status'] = 2;
$tests['php_version']['description'] .= 'This version of PHP is fully compatible with the PHP XMLRPC library';
}
// test for zlib
$tests['zlib'] = array();
if (!function_exists('gzinflate')) {
$tests['zlib']['status'] = 0;
$tests['zlib']['description'] = "The zlib extension is not enabled.\n\nYou will not be able to receive compressed requests or send compressed responses, unless using the cURL library (for 'HTTPS' and 'HTTP 1.1' connections)";
} else {
$tests['zlib']['status'] = 2;
$tests['zlib']['description'] = "The zlib extension is enabled.\n\nYou will be able to receive compressed requests and send compressed responses for the 'HTTP' protocol";
}
// test for dispaly of php errors in xml reponse
if (ini_get('display_errors')) {
if (intval(ini_get('error_reporting')) && E_NOTICE) {
$tests['display_errors']['status'] = 1;
$tests['display_errors']['description'] = "Error reporting level includes E_NOTICE errors, and display_errors is set to ON.\n\nAny error, warning or notice raised while executing php code exposed as xmlrpc method will result in an invalid xmlrpc response";
} else {
$tests['display_errors']['status'] = 1;
$tests['display_errors']['description'] = "display_errors is set to ON.\n\nAny error raised while executing php code exposed as xmlrpc method will result in an invalid xmlrpc response";
}
}
} else {
// test for php version
$ver = phpversion();
$tests['php_version'] = array();
$tests['php_version']['description'] = 'PHP version found: ' . $ver . ".\n\n";
if (version_compare($ver, '5.3.0') < 0) {
$tests['php_version']['status'] = 0;
$tests['php_version']['description'] .= 'This version of PHP is not compatible with the PHP XMLRPC library. Please upgrade to 5.1.0 or later';
} else {
$tests['php_version']['status'] = 2;
$tests['php_version']['description'] .= 'This version of PHP is fully compatible with the PHP XMLRPC library';
}
// test for zlib
$tests['zlib'] = array();
if (!function_exists('gzinflate')) {
$tests['zlib']['status'] = 0;
$tests['zlib']['description'] = "The zlib extension is not enabled.\n\nYou will not be able to send compressed requests or receive compressed responses, unless using the cURL library (for 'HTTPS' and 'HTTP 1.1' connections)";
} else {
$tests['zlib']['status'] = 2;
$tests['zlib']['description'] = "The zlib extension is enabled.\n\nYou will be able to send compressed requests and receive compressed responses for the 'HTTP' protocol";
}
// test for CURL
$tests['curl'] = array();
if (!extension_loaded('curl')) {
$tests['curl']['status'] = 0;
$tests['curl']['description'] = "The cURL extension is not enabled.\n\nYou will not be able to send and receive messages using 'HTTPS' and 'HTTP 1.1' protocols";
} else {
$info = curl_version();
$tests['curl']['status'] = 2;
$tests['curl']['description'] = "The cURL extension is enabled.\n\nYou will be able to send and receive messages using 'HTTPS' and 'HTTP 1.1' protocols";
if (version_compare($ver, '4.3.8') < 0) {
$tests['curl']['status'] = 1;
$tests['curl']['description'] .= ".\nPlease note that the current cURL install does not support keep-alives";
}
if (!((is_string($info) && strpos($info, 'zlib') !== null) || isset($info['libz_version']))) {
$tests['curl']['status'] = 1;
$tests['curl']['description'] .= ".\nPlease note that the current cURL install does not support compressed messages";
}
if (!((is_string($info) && strpos($info, 'OpenSSL') !== null) || isset($info['ssl_version']))) {
$tests['curl']['status'] = 1;
$tests['curl']['description'] .= ".\nPlease note that the current cURL install does not support HTTPS connections";
}
}
}
return $tests;
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>PHP XMLRPC compatibility assessment</title>
<style type="text/css">
body, html {
background-color: white;
font-family: Arial, Verdana, Geneva, sans-serif;
font-size: small;
}
table {
border: 1px solid gray;
padding: 0;
}
thead {
background-color: silver;
color: black;
}
td {
margin: 0;
padding: 0.5em;
}
tbody td {
border-top: 1px solid gray;
}
.res0 {
background-color: red;
color: black;
border-right: 1px solid gray;
}
.res1 {
background-color: yellow;
color: black;
border-right: 1px solid gray;
}
.res2 {
background-color: green;
color: black;
border-right: 1px solid gray;
}
.result {
white-space: pre;
}
</style>
</head>
<body>
<h1>PHPXMLRPC compatibility assessment with the current PHP install</h1>
<h4>For phpxmlrpc version 4.0 or later</h4>
<h3>Server usage</h3>
<table cellspacing="0">
<thead>
<tr>
<td>Test</td>
<td>Result</td>
</tr>
</thead>
<tbody>
<?php
$res = phpxmlrpc_verify_compat('server');
foreach ($res as $test => $result) {
echo '<tr><td class="res' . $result['status'] . '">' . htmlspecialchars($test) . '</td><td class="result">' . htmlspecialchars($result['description']) . "</td></tr>\n";
}
?>
</tbody>
</table>
<h3>Client usage</h3>
<table cellspacing="0">
<thead>
<tr>
<td>Test</td>
<td>Result</td>
</tr>
</thead>
<tbody>
<?php
$res = phpxmlrpc_verify_compat('client');
foreach ($res as $test => $result) {
echo '<tr><td class="res' . $result['status'] . '">' . htmlspecialchars($test) . '</td><td class="result">' . htmlspecialchars($result['description']) . "</td></tr>\n";
}
?>
</tbody>
</table>
</body>
</html>