Index: includes/common.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/common.inc,v
retrieving revision 1.1204
diff -u -p -r1.1204 common.inc
--- includes/common.inc	10 Aug 2010 01:00:42 -0000	1.1204
+++ includes/common.inc	13 Aug 2010 14:43:11 -0000
@@ -6748,15 +6748,14 @@ function entity_form_submit_build_entity
  * Performs one or more XML-RPC request(s).
  *
  * @param $url
- *   An absolute URL of the XML-RPC endpoint.
- *     Example:
- *     http://www.example.com/xmlrpc.php
- * @param ...
- *   For one request:
- *     The method name followed by a variable number of arguments to the method.
- *   For multiple requests (system.multicall):
- *     An array of call arrays. Each call array follows the pattern of the single
- *     request: method name followed by the arguments to the method.
+ *   An absolute URL of the XML-RPC endpoint, e.g.,
+ *   http://example.com/xmlrpc.php
+ * @param $args
+ *   An associative array whose keys are the methods to call and whose values
+ *   are the arguments to pass to the respective method.
+ * @param $options
+ *   (optional) An array of options to pass along to drupal_http_request().
+ *
  * @return
  *   For one request:
  *     Either the return value of the method on success, or FALSE.
@@ -6766,10 +6765,30 @@ function entity_form_submit_build_entity
  *     returned by the method called, or an xmlrpc_error object if the call
  *     failed. See xmlrpc_error().
  */
-function xmlrpc($url) {
+function xmlrpc($url, $args, $options = array()) {
   require_once DRUPAL_ROOT . '/includes/xmlrpc.inc';
-  $args = func_get_args();
-  return call_user_func_array('_xmlrpc', $args);
+
+  // @todo Backwards compatibility. Remove in D8.
+  $args_compat = func_get_args();
+  // Check for old single request syntax ($args contains method to call).
+  if (is_string($args_compat[1])) {
+    array_shift($args_compat);
+    $method = array_shift($args_compat);
+    $args = array($method => $args_compat);
+    $options = array();
+  }
+  // Check for old multicall syntax ($args is an indexed array).
+  elseif (isset($args_compat[1][0])) {
+    array_shift($args_compat);
+    $args = array();
+    foreach ($args_compat as $call_args) {
+      $method = array_shift($call_args);
+      $args[$method] = array($call_args);
+    }
+    $options = array();
+  }
+
+  return _xmlrpc($url, $args, $options);
 }
 
 /**
Index: includes/xmlrpc.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/xmlrpc.inc,v
retrieving revision 1.68
diff -u -p -r1.68 xmlrpc.inc
--- includes/xmlrpc.inc	22 Jul 2010 16:20:15 -0000	1.68
+++ includes/xmlrpc.inc	13 Aug 2010 14:50:19 -0000
@@ -528,14 +528,13 @@ function xmlrpc_base64_get_xml($xmlrpc_b
  * Performs one or more XML-RPC requests.
  *
  * @param $url
- *   The absolute URL of the XML-RPC endpoint. Example:
- *   http://www.example.com/xmlrpc.php
- * @param ...
- *   - For one request: The method name followed by a variable number of
- *     arguments to the method.
- *   - For multiple requests (system.multicall): An array of call arrays. Each
- *     call array follows the pattern of the single request: method name
- *     followed by the arguments to the method.
+ *   An absolute URL of the XML-RPC endpoint, e.g.,
+ *   http://example.com/xmlrpc.php
+ * @param $args
+ *   An associative array whose keys are the methods to call and whose values
+ *   are the arguments to pass to the respective method.
+ * @param $options
+ *   (optional) An array of options to pass along to drupal_http_request().
  *
  * @return
  *   A single response (single request) or an array of responses (multicall
@@ -544,27 +543,25 @@ function xmlrpc_base64_get_xml($xmlrpc_b
  *   is returned, see xmlrpc_errno() and xmlrpc_error_msg() to get more
  *   information.
  */
-function _xmlrpc() {
-  $args = func_get_args();
-  $url = array_shift($args);
+function _xmlrpc($url, $args, $options = array()) {
   xmlrpc_clear_error();
-  if (is_array($args[0])) {
+  if (count($args) > 1) {
     $method = 'system.multicall';
     $multicall_args = array();
-    foreach ($args[0] as $call) {
-      $multicall_args[] = array('methodName' => array_shift($call), 'params' => $call);
+    foreach ($args as $method => $call) {
+      $multicall_args[] = array('methodName' => $method, 'params' => $call);
     }
     $args = array($multicall_args);
   }
   else {
-    $method = array_shift($args);
+    $method = key($args);
+    $args = current($args);
   }
   $xmlrpc_request = xmlrpc_request($method, $args);
-  $options = array(
-    'headers' => array('Content-Type' => 'text/xml'),
-    'method' => 'POST',
-    'data' => $xmlrpc_request->xml,
-  );
+  // Required options which will replace any that are passed in.
+  $options['method'] = 'POST';
+  $options['headers']['Content-Type'] = 'text/xml';
+  $options['data'] = $xmlrpc_request->xml;
   $result = drupal_http_request($url, $options);
   if ($result->code != 200) {
     xmlrpc_error($result->code, $result->error);
Index: modules/simpletest/tests/xmlrpc.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/tests/xmlrpc.test,v
retrieving revision 1.19
diff -u -p -r1.19 xmlrpc.test
--- modules/simpletest/tests/xmlrpc.test	5 Aug 2010 23:53:38 -0000	1.19
+++ modules/simpletest/tests/xmlrpc.test	13 Aug 2010 14:48:30 -0000
@@ -29,7 +29,7 @@ class XMLRPCBasicTestCase extends Drupal
 
     // Invoke XML-RPC call to get list of methods.
     $url = url(NULL, array('absolute' => TRUE)) . 'xmlrpc.php';
-    $methods = xmlrpc($url, 'system.listMethods');
+    $methods = xmlrpc($url, array('system.listMethods' => array()));
 
     // Ensure that the minimum methods were found.
     $count = 0;
@@ -102,19 +102,19 @@ class XMLRPCValidator1IncTestCase extend
                   array('larry' => mt_rand(-100, 100)));
     shuffle($array_1);
     $l_res_1 = xmlrpc_test_arrayOfStructsTest($array_1);
-    $r_res_1 = xmlrpc($xml_url, 'validator1.arrayOfStructsTest', $array_1);
+    $r_res_1 = xmlrpc($xml_url, array('validator1.arrayOfStructsTest' => array($array_1)));
     $this->assertIdentical($l_res_1, $r_res_1, 'array of structs test: %s');
 
 
     $string_2 = 't\'&>>zf"md>yr>xlcev<h<"k&j<og"w&&>">>uai"np&s>>q\'&b<>"&&&';
     $l_res_2 = xmlrpc_test_countTheEntities($string_2);
-    $r_res_2 = xmlrpc($xml_url, 'validator1.countTheEntities', $string_2);
+    $r_res_2 = xmlrpc($xml_url, array('validator1.countTheEntities' => array($string_2)));
     $this->assertIdentical($l_res_2, $r_res_2, 'count the entities test: %s');
 
 
     $struct_3 = array('moe' => mt_rand(-100, 100), 'larry' => mt_rand(-100, 100), 'curly' => mt_rand(-100, 100), 'homer' => mt_rand(-100, 100));
     $l_res_3 = xmlrpc_test_easyStructTest($struct_3);
-    $r_res_3 = xmlrpc($xml_url, 'validator1.easyStructTest', $struct_3);
+    $r_res_3 = xmlrpc($xml_url, array('validator1.easyStructTest' => array($struct_3)));
     $this->assertIdentical($l_res_3, $r_res_3, 'easy struct test: %s');
 
 
@@ -123,7 +123,7 @@ class XMLRPCValidator1IncTestCase extend
                     'sub3' => array('foo' => 1, 'baz' => 2),
                     'sub4' => array('ss' => array('sss' => array('ssss' => 'sssss'))));
     $l_res_4 = xmlrpc_test_echoStructTest($struct_4);
-    $r_res_4 = xmlrpc($xml_url, 'validator1.echoStructTest', $struct_4);
+    $r_res_4 = xmlrpc($xml_url, array('validator1.echoStructTest' => array($struct_4)));
     $this->assertIdentical($l_res_4, $r_res_4, 'echo struct test: %s');
 
     $int_5     = mt_rand(-100, 100);
@@ -134,7 +134,7 @@ class XMLRPCValidator1IncTestCase extend
     $base64_5  = $this->randomName(100);
     $l_res_5 = xmlrpc_test_manyTypesTest($int_5, $bool_5, $string_5, $double_5, xmlrpc_date($time_5), $base64_5);
     $l_res_5[5] = $l_res_5[5]->data; /* override warpping */
-    $r_res_5 = xmlrpc($xml_url, 'validator1.manyTypesTest', $int_5, $bool_5, $string_5, $double_5, xmlrpc_date($time_5), xmlrpc_base64($base64_5));
+    $r_res_5 = xmlrpc($xml_url, array('validator1.manyTypesTest' => array($int_5, $bool_5, $string_5, $double_5, xmlrpc_date($time_5), xmlrpc_base64($base64_5))));
     /* Contains objects, objects are not equal */
     // See http://drupal.org/node/37766 why this currently fails
     $this->assertEqual($l_res_5, $r_res_5, 'many types test: %s');
@@ -147,7 +147,7 @@ class XMLRPCValidator1IncTestCase extend
     }
 
     $l_res_6 = xmlrpc_test_moderateSizeArrayCheck($array_6);
-    $r_res_6 = xmlrpc($xml_url, 'validator1.moderateSizeArrayCheck', $array_6);
+    $r_res_6 = xmlrpc($xml_url, array('validator1.moderateSizeArrayCheck' => array($array_6)));
     $this->assertIdentical($l_res_6, $r_res_6, 'moderate size array check: %s');
 
 
@@ -165,25 +165,25 @@ class XMLRPCValidator1IncTestCase extend
       }
     }
     $l_res_7 = xmlrpc_test_nestedStructTest($struct_7);
-    $r_res_7 = xmlrpc($xml_url, 'validator1.nestedStructTest', $struct_7);
+    $r_res_7 = xmlrpc($xml_url, array('validator1.nestedStructTest' => array($struct_7)));
     $this->assertIdentical($l_res_7, $r_res_7, 'nested struct test: %s');
 
 
     $int_8 = mt_rand(-100, 100);
     $l_res_8 = xmlrpc_test_simpleStructReturnTest($int_8);
-    $r_res_8 = xmlrpc($xml_url, 'validator1.simpleStructReturnTest', $int_8);
+    $r_res_8 = xmlrpc($xml_url, array('validator1.simpleStructReturnTest' => array($int_8)));
     $this->assertIdentical($l_res_8, $r_res_8, 'simple struct test: %s');
 
     /* Now test multicall */
     $x = array();
-    $x[] = array('validator1.arrayOfStructsTest',     $array_1);
-    $x[] = array('validator1.countTheEntities',       $string_2);
-    $x[] = array('validator1.easyStructTest',         $struct_3);
-    $x[] = array('validator1.echoStructTest',         $struct_4);
-    $x[] = array('validator1.manyTypesTest',          $int_5, $bool_5, $string_5, $double_5, xmlrpc_date($time_5), xmlrpc_base64($base64_5));
-    $x[] = array('validator1.moderateSizeArrayCheck', $array_6);
-    $x[] = array('validator1.nestedStructTest',       $struct_7);
-    $x[] = array('validator1.simpleStructReturnTest', $int_8);
+    $x['validator1.arrayOfStructsTest'] = array($array_1);
+    $x['validator1.countTheEntities'] = array($string_2);
+    $x['validator1.easyStructTest'] = array($struct_3);
+    $x['validator1.echoStructTest'] = array($struct_4);
+    $x['validator1.manyTypesTest'] = array($int_5, $bool_5, $string_5, $double_5, xmlrpc_date($time_5), xmlrpc_base64($base64_5));
+    $x['validator1.moderateSizeArrayCheck'] = array($array_6);
+    $x['validator1.nestedStructTest'] = array($struct_7);
+    $x['validator1.simpleStructReturnTest'] = array($int_8);
 
     $a_l_res = array($l_res_1, $l_res_2, $l_res_3, $l_res_4, $l_res_5, $l_res_6, $l_res_7, $l_res_8);
     $a_r_res = xmlrpc($xml_url, $x);
@@ -212,7 +212,7 @@ class XMLRPCMessagesTestCase extends Dru
     $sizes = array(8, 80, 160);
     foreach ($sizes as $size) {
       $xml_message_l = xmlrpc_test_message_sized_in_kb($size);
-      $xml_message_r = xmlrpc($xml_url, 'messages.messageSizedInKB', $size);
+      $xml_message_r = xmlrpc($xml_url, array('messages.messageSizedInKB', $size));
 
       $this->assertEqual($xml_message_l, $xml_message_r, t('XML-RPC messages.messageSizedInKB of %s Kb size received', array('%s' => $size)));
     }
