mirror of
https://github.com/moodle/moodle.git
synced 2025-08-11 11:56:40 +02:00
MDL-60594 xmlrpc: wrapper for buggy xmlrpc_decode
This commit is contained in:
parent
5fdb912a82
commit
6d353a7918
2 changed files with 65 additions and 1 deletions
|
@ -89,7 +89,7 @@ class webservice_xmlrpc_client {
|
||||||
$response = download_file_content($this->serverurl->out(false), $headers, $request);
|
$response = download_file_content($this->serverurl->out(false), $headers, $request);
|
||||||
|
|
||||||
// Decode the response.
|
// Decode the response.
|
||||||
$result = xmlrpc_decode($response);
|
$result = $this->decode_response($response);
|
||||||
if (is_array($result) && xmlrpc_is_fault($result)) {
|
if (is_array($result) && xmlrpc_is_fault($result)) {
|
||||||
throw new Exception($result['faultString'], $result['faultCode']);
|
throw new Exception($result['faultString'], $result['faultCode']);
|
||||||
}
|
}
|
||||||
|
@ -116,4 +116,23 @@ class webservice_xmlrpc_client {
|
||||||
|
|
||||||
return xmlrpc_encode_request($functionname, $params, $outputoptions);
|
return xmlrpc_encode_request($functionname, $params, $outputoptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses and decodes the response XML
|
||||||
|
*
|
||||||
|
* @param string $response
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function decode_response($response) {
|
||||||
|
// XMLRPC server in Moodle encodes response using function xmlrpc_encode_request() with method==null
|
||||||
|
// see {@link webservice_xmlrpc_server::prepare_response()} . We should use xmlrpc_decode_request() for decoding too.
|
||||||
|
$method = null;
|
||||||
|
$encoding = null;
|
||||||
|
if (preg_match('/^<\?xml version="1.0" encoding="([^"]*)"\?>/', $response, $matches)) {
|
||||||
|
// Sometimes xmlrpc_decode_request() fails to recognise encoding, let's help it.
|
||||||
|
$encoding = $matches[1];
|
||||||
|
}
|
||||||
|
$r = xmlrpc_decode_request($response, $method, $encoding);
|
||||||
|
return $r;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,12 +103,47 @@ class webservice_xmlrpc_test extends advanced_testcase {
|
||||||
// to fail if the markup escaping was not set.
|
// to fail if the markup escaping was not set.
|
||||||
$this->assertEquals(['<bar>ŠČŘŽÝÁÍÉ</bar>'], xmlrpc_decode($xml, 'UTF-8'));
|
$this->assertEquals(['<bar>ŠČŘŽÝÁÍÉ</bar>'], xmlrpc_decode($xml, 'UTF-8'));
|
||||||
|
|
||||||
|
// Decoding also works with our wrapper method.
|
||||||
|
$this->assertEquals(['<bar>ŠČŘŽÝÁÍÉ</bar>'], $client->decode_response($xml));
|
||||||
|
|
||||||
// Our experiments show that even with default/implicit encoding,
|
// Our experiments show that even with default/implicit encoding,
|
||||||
// requests encoded with markup escaping set are also decoded
|
// requests encoded with markup escaping set are also decoded
|
||||||
// correctly. This is known to be used in some servers so we test it
|
// correctly. This is known to be used in some servers so we test it
|
||||||
// here, too.
|
// here, too.
|
||||||
|
// However, this does not work for all strings, see next test.
|
||||||
$this->assertEquals(['<bar>ŠČŘŽÝÁÍÉ</bar>'], xmlrpc_decode($xml));
|
$this->assertEquals(['<bar>ŠČŘŽÝÁÍÉ</bar>'], xmlrpc_decode($xml));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test the XML-RPC response decoding
|
||||||
|
*/
|
||||||
|
public function test_decode_response() {
|
||||||
|
$client = new webservice_xmlrpc_client_mock('/webservice/xmlrpc/server.php', 'anytoken');
|
||||||
|
|
||||||
|
$teststring = '<bar>Recherche thématique:Villes & Développement durable</bar>';
|
||||||
|
|
||||||
|
// Encode the string with the proper encoding and escaping options. Assert that decoding will work.
|
||||||
|
$xml = $client->encode_request('do_it', [$teststring]);
|
||||||
|
$this->assertEquals([$teststring], $client->decode_response($xml));
|
||||||
|
// For this particular string bare decoding function does not work.
|
||||||
|
// It can't really be explained why it works for the string 'ŠČŘŽÝÁÍÉ' in the previous test but not this one.
|
||||||
|
// Symbol é comes as chr(233) . It looks like '<bar>Recherche th<74>matique:Villes & D<>veloppement durable</bar>'.
|
||||||
|
$this->assertEquals([preg_replace('/é/', chr(233), $teststring)], xmlrpc_decode($xml));
|
||||||
|
|
||||||
|
// Encode the string without any options (default encoding "iso-8859-1" is used). Assert that decoding will work.
|
||||||
|
$xml = xmlrpc_encode_request('do_it', [$teststring]);
|
||||||
|
$this->assertEquals([$teststring], $client->decode_response($xml));
|
||||||
|
$this->assertEquals([$teststring], xmlrpc_decode($xml));
|
||||||
|
|
||||||
|
// Another example of the string where bare xmlrpc_decode() does not work but our wrapper does.
|
||||||
|
$teststring = 'Formación Docente';
|
||||||
|
|
||||||
|
$xml = $client->encode_request('do_it', [$teststring]);
|
||||||
|
$this->assertEquals([$teststring], $client->decode_response($xml));
|
||||||
|
// Bare decoding function xmlrpc_decode() does not work.
|
||||||
|
// Symbol ó comes as chr(243), it looks like 'Formaci<63>n Docente'.
|
||||||
|
$this->assertEquals([preg_replace('/ó/', chr(243), $teststring)], xmlrpc_decode($xml));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -169,4 +204,14 @@ class webservice_xmlrpc_client_mock extends webservice_xmlrpc_client {
|
||||||
public function encode_request($functionname, $params) {
|
public function encode_request($functionname, $params) {
|
||||||
return parent::encode_request($functionname, $params);
|
return parent::encode_request($functionname, $params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows to test the response decoding.
|
||||||
|
*
|
||||||
|
* @param string $response
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function decode_response($response) {
|
||||||
|
return parent::decode_response($response);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue