For the life of me I can't get this module to work.

Services - 6.x-2.4
Deploy - Latest dev
Drupal - 6.19

Followed the installation instructions, filling in the holes with the out-of-date documentation with instructions from the issue queue and comments on docs pages. I get as far as running the batch "Deploy now" operation, but the log result is always the same:

Module	Description	Result	Message
login	Remote user login	Error	Parse error. Not well formed

I set up logging on the http request to see what the source server was requesting, and what the target server was responding, and it looks like the source server doesn't bother to include the session ID in any of its requests.

Here are the first two request/response pairs from the source server (with sensitive bits redacted).

POST /services/xmlrpc HTTP/1.0 Host: staging.example.com User-Agent: Drupal (+http://drupal.org/) Content-Length: 106 Content-Type: text/xml <?xml version="1.0"?> <methodCall> <methodName>system.connect</methodName> <params> </params></methodCall>

The first call, system.connect, works great and and target successfully returns a session id:

<?xml version="1.0"?> <methodResponse> <params> <param> <value><struct> <member><name>sessid</name><value><string>aeccbf72f106b1c60aecf3eebe2ac5f0</string></value></member> <member><name>user</name><value><struct> <member><name>uid</name><value><int>0</int></value></member> <member><name>hostname</name><value><string>12.34.56.78</string></value></member> <member><name>roles</name><value><struct> <member><name>1</name><value><string>anonymous user</string></value></member> </struct></value></member> <member><name>session</name><value><string></string></value></member> <member><name>cache</name><value><int>0</int></value></member> <member><name>og_groups</name><value><array><data> </data></array></value></member> </struct></value></member> </struct></value> </param> </params> </methodResponse>

However, the sessid member is omitted completed in the next request by the target server. Presumably the empty param at the beginning of the params element should be populated with the sessid, or the sessid should go in the header somewhere:

POST /services/xmlrpc HTTP/1.0 Host: staging.example.com User-Agent: Drupal (+http://drupal.org/) Content-Length: 268 Content-Type: text/xml <?xml version="1.0"?> <methodCall> <methodName>user.login</methodName> 
<params> 
<param><value><string></string></value></param> 
<param><value><string>admin</string></value></param>
<param><value><string>password</string></value></param> </params>
</methodCall>

And the predictable response from the target server:

<?xml version="1.0"?> <methodResponse> <params> <param> <value><string>Invalid sessid.</string></value> </param> </params> </methodResponse>

So, beyond the sessid being omitted completely from the login request, the error message "Parse error. Not well formed" doesn't make sense either, since we can plainly see that the response is valid xml.

I'm guessing this is some kind of mis-matched version issue, but I don't see any guidelines for which version of Services to use with which version of deploy.

Comments

aaronbauman’s picture

Title: What am I missing here? » attempt to fix simple errors before failing by trim()'ing response before parsing
Category: support » feature

After a little digging, the "Parse error. Not well formed" message seems to be coming from xmlrpc_message_parse() in (core) includes/xmlrpc.inc, and it seems this boils down to a whitespace issue.

Adding a simple trim($xmlrpc_message->message); before parsing did the trick...
Seems to me that many of the reported "issues" in the queue are due to such whitespace issues, and quite a few headaches could be resolved if a simple trim() this were incorporated into either Deploy or Services or Drupal core somewhere between message receipt and message parsing...

Any idea on the feasibility of this?

bmartinP4’s picture

Can you tell me where exactly you added the above trim line. I'd be happy to add it myself at this point just to stop the headaches. As specific as possible would be helpful.

aaronbauman’s picture

Anywhere before xml_parse() should be fine.
Here's a patch I used (against Drupal 6.19 -- 6.20 should be similar).

--- includes/xmlrpc.inc (saved version)
+++ includes/xmlrpc.inc (working copy)
@@ -163,6 +163,7 @@
   // Set XML parser callback functions
   xml_set_element_handler($xmlrpc_message->_parser, 'xmlrpc_message_tag_open', 'xmlrpc_message_tag_close');
   xml_set_character_data_handler($xmlrpc_message->_parser, 'xmlrpc_message_cdata');
+  $xmlrpc_message->message = trim($xmlrpc_message->message);
   xmlrpc_message_set($xmlrpc_message);
   if (!xml_parse($xmlrpc_message->_parser, $xmlrpc_message->message)) {
     return FALSE;
bmartinP4’s picture

To which file did you add the code? The problem I've been having is finding out where the xml_parse() function is. I'm assuming in the Services files, but I'm prepared to admit that I'm probably an idiot. :) Thanks for your help so far.

aaronbauman’s picture

drupalroot/includes/xmlrpc.inc
where "drupalroot" is the root directory of your drupal install.

yes - this is a core hack and should never be used by anyone unless they want to kill kittens.

bmartinP4’s picture

Added the line. Still getting the parse error. Kittens die in vain.

chrisnovak’s picture

The patch that aaronbauman posted fixed the issue for me- there was one space showing up in the front of the XML returned by the each of the XMLRPC methods called, here is the one for system.connect:

 <?xml version="1.0"?>

<methodResponse>
[nice looking xml here...]
</methodResponse>

xml_get_error_code( ) returns: 17
xml_error_string( 17 ) returns: XML or text declaration not at start of entity

I am not a fan of kittens, but I still don't want to kill any. Is there a way around this needless slaughter?