diff --git a/webservice/xmlrpc/lib.php b/webservice/xmlrpc/lib.php index a4eb5bbfe6c..06c499d5599 100644 --- a/webservice/xmlrpc/lib.php +++ b/webservice/xmlrpc/lib.php @@ -73,16 +73,7 @@ class webservice_xmlrpc_client { $this->serverurl->param('wstoken', $this->token); } - // Set output options. - $outputoptions = array( - 'encoding' => 'utf-8', - 'escaping' => 'markup', - ); - - // Encode the request. - // See MDL-53962 - needed for backwards compatibility on <= 3.0 - $params = array_values($params); - $request = xmlrpc_encode_request($functionname, $params, $outputoptions); + $request = $this->encode_request($functionname, $params); // Set the headers. $headers = array( @@ -103,4 +94,24 @@ class webservice_xmlrpc_client { return $result; } + + /** + * Generates XML for a method request. + * + * @param string $functionname Name of the method to call. + * @param mixed $params Method parameters compatible with the method signature. + * @return string + */ + protected function encode_request($functionname, $params) { + + $outputoptions = array( + 'encoding' => 'utf-8', + 'escaping' => 'markup', + ); + + // See MDL-53962 - needed for backwards compatibility on <= 3.0. + $params = array_values($params); + + return xmlrpc_encode_request($functionname, $params, $outputoptions); + } } diff --git a/webservice/xmlrpc/tests/lib_test.php b/webservice/xmlrpc/tests/lib_test.php index 8adc4384f5d..6a7c7fe3428 100644 --- a/webservice/xmlrpc/tests/lib_test.php +++ b/webservice/xmlrpc/tests/lib_test.php @@ -88,6 +88,27 @@ class webservice_xmlrpc_test extends advanced_testcase { $this->expectException('moodle_exception'); $client->call('testfunction'); } + + /** + * Test the XML-RPC request encoding. + */ + public function test_encode_request() { + + $client = new webservice_xmlrpc_client_mock('/webservice/xmlrpc/server.php', 'anytoken'); + + // Encode the request with the proper encoding and escaping options. + $xml = $client->encode_request('do_it', ['foo' => 'ŠČŘŽÝÁÍÉ']); + + // Assert that decoding with explicit encoding will work. This appeared + // to fail if the markup escaping was not set. + $this->assertEquals(['ŠČŘŽÝÁÍÉ'], xmlrpc_decode($xml, 'UTF-8')); + + // Our experiments show that even with default/implicit encoding, + // requests encoded with markup escaping set are also decoded + // correctly. This is known to be used in some servers so we test it + // here, too. + $this->assertEquals(['ŠČŘŽÝÁÍÉ'], xmlrpc_decode($xml)); + } } /** @@ -137,4 +158,15 @@ class webservice_xmlrpc_client_mock extends webservice_xmlrpc_client { return $result; } + + /** + * Allows to test the request encoding. + * + * @param string $functionname Name of the method to call. + * @param mixed $params Method parameters compatible with the method signature. + * @return string + */ + public function encode_request($functionname, $params) { + return parent::encode_request($functionname, $params); + } }