diff --git a/mnet/lib.php b/mnet/lib.php
index 6e27a0ab954..c6c8209d021 100644
--- a/mnet/lib.php
+++ b/mnet/lib.php
@@ -56,7 +56,10 @@ function mnet_get_public_key($uri, $application=null) {
$application = $DB->get_record('mnet_application', array('name'=>'moodle'));
}
- $rq = xmlrpc_encode_request('system/keyswap', array($CFG->wwwroot, $mnet->public_key, $application->name), array("encoding" => "utf-8"));
+ $rq = xmlrpc_encode_request('system/keyswap', array($CFG->wwwroot, $mnet->public_key, $application->name), array(
+ 'encoding' => 'utf-8',
+ 'escaping' => 'markup',
+ ));
$ch = curl_init($uri . $application->xmlrpc_server_url);
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
diff --git a/webservice/xmlrpc/lib.php b/webservice/xmlrpc/lib.php
index 6d4820002ea..7f5e288e3ad 100644
--- a/webservice/xmlrpc/lib.php
+++ b/webservice/xmlrpc/lib.php
@@ -14,7 +14,6 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see .
-
/**
* Moodle XML-RPC library
*
@@ -23,11 +22,11 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
+defined('MOODLE_INTERNAL') || die();
+
/**
* Moodle XML-RPC client
*
- * It has been implemented for unit testing purpose (all protocols have similar client)
- *
* @package webservice_xmlrpc
* @copyright 2010 Jerome Mouneyrac
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
@@ -73,15 +72,7 @@ class webservice_xmlrpc_client {
$this->serverurl->param('wstoken', $this->token);
}
- // Set output options.
- $outputoptions = array(
- 'encoding' => 'utf-8'
- );
-
- // 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(
@@ -102,4 +93,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);
+ }
}