Apparently, the system.multicall implementation is broken, as - when no error occurs - it returns a plain array of results, whereas it should return an array of one-element arrays containing the result of each method.

As per the spec (emphasis added) The result will either be a one-item array containing the result value (this mirrors the use of
in ), or a struct of the form found inside the standard element.

The same problem is present in each and every version since Drupal 4.5 when multicall was introduced in xmlrpcs.inc, including the latest HEAD, and can be double checked using the XML-RPC reference multicall test from http://xmlrpc-c.sourceforge.net/hacks/test_multicall.py

The attached patch fixes the problem. Strictly equivalent patches can be applied to each version since 4.5 included.

Comments

fgm’s picture

Status: Active » Needs review

Forgot to set status.

fgm’s picture

Version: 6.14 » 7.x-dev
StatusFileSize
new516 bytes

And here is the version for today's HEAD.

dries’s picture

How about some tests? #639608: Provide assertXmlrpc() function to inspect and verify XML-RPC messages might be a requirement, or at least, could help make testing a lot easier.

Status: Needs review » Needs work

The last submitted patch failed testing.

fgm’s picture

Of course, this means we also had the matching error in our client so that both worked together (but not with third party implementations). So the client and simpletest also need to be fixed, which is less simple than the server side. Time to look again at Dries' suggestion for assertXml(), it seems.

FWIW, the default ruby implementation has a specific implementation for multicall (multicall calls multicall2, call gen_multicall, which unwraps the 1-element array from the result) as opposed to standard calls. We might want to do something similar.

fgm’s picture

Status: Needs work » Needs review
StatusFileSize
new1.4 KB

A better patch, covering both client and server. Works with both Drupal and non-Drupal implementations.

dries’s picture

+++ includes/xmlrpc.inc	16 Dec 2009 15:44:09 -0000
@@ -475,8 +475,22 @@ function _xmlrpc() {
+  // Message must be OK, but each individual call needn't be

This is somewhat fuzzy. Care to provide a better comment? Looks good, and it pretty easy to understand, but let's come up with a nicely written comment. Should be RTBC.

fgm’s picture

StatusFileSize
new1.71 KB

How about this one ? Maybe too verbose ?

fgm’s picture

Title: Incorrection multicall implementation » Incorrect multicall implementation
StatusFileSize
new1.4 KB

Resubmitting to trigger test bot, which appears to remain stuck.

fgm’s picture

StatusFileSize
new1.71 KB

Oops, wrong patch :-(

sun’s picture

+++ includes/xmlrpc.inc	16 Dec 2009 22:10:19 -0000
@@ -475,8 +475,29 @@ function _xmlrpc() {
+  // To arrive here, the message must be OK

What means "OK" ?

+++ includes/xmlrpc.inc	16 Dec 2009 22:10:19 -0000
@@ -475,8 +475,29 @@ function _xmlrpc() {
+  /**
+   * However, since this is a multicall, each individual method call
+   * performed on the server side may have caused an error, while not
+   * preventing subsequent methods and the overall multicall from
+   * succeeding. Therefore we store the individual error for each
+   * method within the multicall result.
+   */

Wrong comment style. We do not use multi-line comments within function bodies; always use inline comments here.

In addition, this comment reads a bit lengthy - just clarifying what the expected result for multicalls (and difference to single methods) is should be sufficient.

+++ includes/xmlrpc.inc	16 Dec 2009 22:10:19 -0000
@@ -475,8 +475,29 @@ function _xmlrpc() {
+      if (array_keys($result) == array(0)) {
+        $ret[] = $result[0];
+      }
+      else {
+        $ret[] = xmlrpc_error($result['faultCode'], $result['faultString']);
+      }

What is happening here?

Also, we should not abbreviate $ret[urn]

fgm’s picture

StatusFileSize
new2.59 KB

Moved the main comment in the function phpdoc and rewritten. How about this version ?

Status: Needs review » Needs work

The last submitted patch failed testing.

Status: Needs work » Needs review

fgm requested that failed test be re-tested.

fgm’s picture

(failed test is FileDeleteTest, which is AFAIK unrelated with XMLRPC)

dries’s picture

Status: Needs review » Reviewed & tested by the community

This looks valid to me. Let's see if there are any final reviewers.

sun’s picture

Status: Reviewed & tested by the community » Needs review

Looks indeed much better now.

+++ includes/xmlrpc.inc	19 Dec 2009 08:52:15 -0000
@@ -430,13 +430,16 @@ function xmlrpc_base64_get_xml($xmlrpc_b
+     Either the return value of the method on success, or FALSE.
+ *   If FALSE is returned, see xmlrpc_errno() and xmlrpc_error_msg().

Should not wrap early, but at 80 chars instead.

+++ includes/xmlrpc.inc	19 Dec 2009 08:52:15 -0000
@@ -430,13 +430,16 @@ function xmlrpc_base64_get_xml($xmlrpc_b
+     Either the return value of the method on success, or FALSE.

Missing leading ' * '.

+++ includes/xmlrpc.inc	19 Dec 2009 08:52:15 -0000
@@ -430,13 +430,16 @@ function xmlrpc_base64_get_xml($xmlrpc_b
+ *   For a non-multicall request:
+ *     The result just as if this had been a local function call.
+ *   For a multicall request:
+ *     An array of results. Each result will either be a one-element array
+ *     containing the result returned by the method called, or an xmlrpc_error
+ *     object if the call failed.

Use a Doxygen list here instead? See http://drupal.org/node/1354 for proper formatting of lists.

This review is powered by Dreditor.

fgm’s picture

StatusFileSize
new2.59 KB

How about this version, then ?

Regarding the 80-column folding, I had looked for it previously but it does not currently appear on http://drupal.org/node/1354, which led me to wrap early at a more significant place, as you noticed.

This which may be a documentation bug, since we have similar recommendations

Status: Needs review » Needs work

The last submitted patch, , failed testing.

dave reid’s picture

Status: Needs work » Needs review

My bad.

Re-test of from comment #2403644 was requested by @user.

Status: Needs review » Needs work

The last submitted patch, , failed testing.

Status: Needs work » Needs review

Re-test of from comment #2403644 was requested by @user.

Status: Needs review » Needs work

The last submitted patch, , failed testing.

Status: Needs work » Needs review

Re-test of from comment #2403644 was requested by @user.

sun’s picture

Status: Needs review » Reviewed & tested by the community

This can be backported to D6.

dries’s picture

Version: 7.x-dev » 6.x-dev
Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs backport to D6

Committed to CVS HEAD. Changing version and status.

fgm’s picture

Status: Needs work » Needs review
StatusFileSize
new3.87 KB

Here is a D6 version.

Here too, server side tested with the multicall client from http://xmlrpc-c.sourceforge.net/hacks/test_multicall.py

fgm’s picture

StatusFileSize
new3.87 KB

Grrr... missing space.

fgm’s picture

StatusFileSize
new2.86 KB

And an almost identical patch for D5. Server also tested with the python client.

fgm’s picture

StatusFileSize
new4.98 KB

And of course, while I was at it, the D47 version, with a few fixes which had appeared in the meantime. Luckily, the API change on xmlrpc_error() was not needed to apply the fix.

Also tested with the multicall.py client too.

We could go probably on, since this version dates back to 4.5...

dries’s picture

Status: Needs review » Reviewed & tested by the community

Reviewed the D6 version. Looks great.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, xmlrpc47_32.patch, failed testing.

cyberwolf’s picture

Subscribing.

fgm’s picture

Issue summary: View changes
Status: Needs work » Needs review
StatusFileSize
new3.46 KB

Rerolled D6 patch.

fgm’s picture

Status: Needs review » Reviewed & tested by the community

Resetting to RTBC now that it is rerolled, as Dries had set it in #33.

Status: Reviewed & tested by the community » Closed (outdated)

Automatically closed because Drupal 6 is no longer supported. If the issue verifiably applies to later versions, please reopen with details and update the version.