| Project: | Services |
| Version: | 7.x-3.x-dev |
| Component: | Code |
| Category: | feature request |
| Priority: | normal |
| Assigned: | Unassigned |
| Status: | postponed |
| Issue tags: | introspection, XML-RPC |
Issue Summary
I'm using Zend Framework's Zend_XmlRpc_Client. For the second time, I've run into a problem that nobody else seems to be reporting. For methods other than system.connect, I'm getting the error:
Server error. Requested method user.login signature not specified
This is thrown by core xmlrpcs.inc at l. 294. Seems that Zend_XmlRpc_Client is doing some validation by introspection which is triggering this.
Anyone else running into this can use this in your client (ZF >= 1.6.0):
Zend_XmlRpc_Client::setSkipSystemLookup(FALSE);
Below is a dump of the client introspecting all method signatures. None of the services methods seem to be responding. Wondering if this should be classed as a services bug and we should be setting signatures.
array
'system.multicall' =>
array
'faultCode' => int -32601
'faultString' => string 'Server error. Requested method system.multicall signature not specified.' (length=72)
'system.methodSignature' =>
array
0 => string 'array' (length=5)
1 => string 'string' (length=6)
'system.getCapabilities' =>
array
0 => string 'struct' (length=6)
'system.listMethods' =>
array
0 => string 'array' (length=5)
'system.methodHelp' =>
array
0 => string 'string' (length=6)
1 => string 'string' (length=6)
'comment.save' =>
array
'faultCode' => int -32601
'faultString' => string 'Server error. Requested method comment.save signature not specified.' (length=68)
'comment.loadNodeComments' =>
array
'faultCode' => int -32601
'faultString' => string 'Server error. Requested method comment.loadNodeComments signature not specified.' (length=80)
'comment.load' =>
array
'faultCode' => int -32601
'faultString' => string 'Server error. Requested method comment.load signature not specified.' (length=68)
'comment.countAll' =>
array
'faultCode' => int -32601
'faultString' => string 'Server error. Requested method comment.countAll signature not specified.' (length=72)
'comment.countNew' =>
array
'faultCode' => int -32601
'faultString' => string 'Server error. Requested method comment.countNew signature not specified.' (length=72)
'node.get' =>
array
'faultCode' => int -32601
'faultString' => string 'Server error. Requested method node.get signature not specified.' (length=64)
'node.view' =>
array
'faultCode' => int -32601
'faultString' => string 'Server error. Requested method node.view signature not specified.' (length=65)
'node.save' =>
array
'faultCode' => int -32601
'faultString' => string 'Server error. Requested method node.save signature not specified.' (length=65)
'node.delete' =>
array
'faultCode' => int -32601
'faultString' => string 'Server error. Requested method node.delete signature not specified.' (length=67)
'system.connect' =>
array
'faultCode' => int -32601
'faultString' => string 'Server error. Requested method system.connect signature not specified.' (length=70)
'system.mail' =>
array
'faultCode' => int -32601
'faultString' => string 'Server error. Requested method system.mail signature not specified.' (length=67)
'system.getVariable' =>
array
'faultCode' => int -32601
'faultString' => string 'Server error. Requested method system.getVariable signature not specified.' (length=74)
'system.setVariable' =>
array
'faultCode' => int -32601
'faultString' => string 'Server error. Requested method system.setVariable signature not specified.' (length=74)
'system.moduleExists' =>
array
'faultCode' => int -32601
'faultString' => string 'Server error. Requested method system.moduleExists signature not specified.' (length=75)
'system.getServices' =>
array
'faultCode' => int -32601
'faultString' => string 'Server error. Requested method system.getServices signature not specified.' (length=74)
'system.cacheClearAll' =>
array
'faultCode' => int -32601
'faultString' => string 'Server error. Requested method system.cacheClearAll signature not specified.' (length=76)
'system.watchdog' =>
array
'faultCode' => int -32601
'faultString' => string 'Server error. Requested method system.watchdog signature not specified.' (length=71)
'user.delete' =>
array
'faultCode' => int -32601
'faultString' => string 'Server error. Requested method user.delete signature not specified.' (length=67)
'user.get' =>
array
'faultCode' => int -32601
'faultString' => string 'Server error. Requested method user.get signature not specified.' (length=64)
'user.load' =>
array
'faultCode' => int -32601
'faultString' => string 'Server error. Requested method user.load signature not specified.' (length=65)
'user.login' =>
array
'faultCode' => int -32601
'faultString' => string 'Server error. Requested method user.login signature not specified.' (length=66)
'user.logout' =>
array
'faultCode' => int -32601
'faultString' => string 'Server error. Requested method user.logout signature not specified.' (length=67)
'user.save' =>
array
'faultCode' => int -32601
'faultString' => string 'Server error. Requested method user.save signature not specified.' (length=65)
'node_resource.create' =>
array
'faultCode' => int -32601
'faultString' => string 'Server error. Requested method node_resource.create signature not specified.' (length=76)
'node_resource.delete' =>
array
'faultCode' => int -32601
'faultString' => string 'Server error. Requested method node_resource.delete signature not specified.' (length=76)
'node_resource.retrieve' =>
array
'faultCode' => int -32601
'faultString' => string 'Server error. Requested method node_resource.retrieve signature not specified.' (length=78)
'node_resource.update' =>
array
'faultCode' => int -32601
'faultString' => string 'Server error. Requested method node_resource.update signature not specified.' (length=76)
'node_resource.index' =>
array
'faultCode' => int -32601
'faultString' => string 'Server error. Requested method node_resource.index signature not specified.' (length=75)
Comments
#1
did you try enabling "User Service" in drupal?
that helped me move past this.
Eric
#2
There are a couple of problems I identified, one in the the system core XML-RPC library implementation, and the other in the services module XML-RPC server. The bad news is that this might not be a “bug” in either. But the good news is that it’s easy to fix.
The core XML-RPC library provides two ways for servers to report their services: one allows for introspection support, the other produces half-broken support. Specifically, it supports system.listMethods for all methods, but returns “System Error” when system.methodSignature is invoked for methods from servers that don’t support it. In the latter case, the “works as designed” response from core designers might be that you shouldn't be calling introspection methods on servers that don’t support it. Unfortunately, the core XML-RPC library doesn’t let you know which ones do or don’t support introspection other than through the error. It’s definitely not in agreement with the de facto standard XML-RPC introspection protocol.
The problem in the services module is that it doesn't really have any support for XML-RPC introspection and so its XML-RPC server uses the interface into the XML-RPC library that produces broken responses when someone attempts to use introspection on it.
The good news is that the attached patch provides the necessary support in the XML-RPC server. Mind you that I really don’t know much about XML-RPC other than what I’ve learned over the last couple of hours studying this problem and I don’t have a thorough way of testing this patch, so please tread lightly.
There may be security issues that I haven’t considered. Without this patch, a limited client can only see the method names. This patch reveals the method input types, parameter names, return types and the help text for each method.
IMHO this is a core bug. The interface that produces half-broken support should instead result in “I don’t know” responses when system.methodSignature is invoked. It’s moot for this server with this patch, but here’s the issue I submitted against core:
#897142: XML-RPC introspection protocol breaks for servers that don’t provide signatures
I’ll leave this particular item marked as a bug so that the patch gets submitted and I’ll otherwise leave it to the project maintainers to decide whether or not it’s their “bug” and/or whether they otherwise want to include this patch as a feature improvement.
Please let me know how it works for you.
#3
The last submitted patch, xmlrpc_server.module.patch, failed testing.
#4
Fix format
#5
#2: xmlrpc_server.module.patch queued for re-testing.
#6
I was close, but I see that core doesn't support multiple signatures. This patch uses only the first one calculated.
#7
Note that core 7.x changes the incorrect system.methodSignature return after #897140: system.methodSignature returns incorrect and incomplete data: it now returns an array of 1 signature, as per the introspection spec, instead of returning the signature itself.
#8
Bumping version
#9
#10
There are plenty of PHP implementation of XMLRPC to look at as reference http://www.xmlrpc.com/directory/1568/implementations
Just writing this link here in order not to forget about it :) I believe our XMLRPC really needs a lot of improvements.
#11
Same problem here.
#12
+ $signatures = xmlrpc_server_method_signatures($method);
+ $callbacks[] = array(
+ $method['method'],
+ 'xmlrpc_server_call_wrapper',
+ is_array($signatures)?$signatures[0]:$signatures,
+ $method['help']
+ );
This part failed for me. I went with this instead: (apologies for styling - feel free to correct. My editor was being silly). This allows XMLRPC to revert to previous approach if applying signature (say as it does with all of the internal systems).
I suspect there's a problem with the other part to even identify the signature - it really doesn't match how data's organized from what I've read, but am not sure how to correct it.
+ $signatures = xmlrpc_server_method_signatures($method);
+ if ($signatures) {
+ $callbacks[] = array(
+ $method['method'],
+ 'xmlrpc_server_call_wrapper',
+ is_array($signatures)?$signatures[0]:$signatures,
+ $method['help']
+ );
+ } else {
+ $callbacks[$method['method']] = 'xmlrpc_server_call_wrapper';
+ }