CodeIgniter Forums

Full Version: XMLRPC - Root element missing
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I'm trying to convert some procedural code for handling xmlrpc requests into codeigniter, but when following the example on how to properly setup an xmlrpc server within codeigniter the client responds with an error saying that the Root element is missing from the request.

The procedural code is as follows:


PHP Code:
$xmlrpc_server xmlrpc_server_create();
xmlrpc_server_register_method($xmlrpc_server"reportuser",
 
                         "reportuser");

function 
reportuser($method_name$params$app_data)
{
 
 global $db;

 
 $req        $params[0];

 
 $regionName = (string)$req['regionName'];
 
 $abuserID = (string)$req['abuserID'];
 
 $catagory = (int)$req['catagory'];
 
 $checkflags = (int)$req['checkflags'];
 
 $details = (string)$req['details'];
 
 $objectID = (string)$req["objectID"];
 
 $postion = (string)$req['postion'];
 
 $reportType = (int)$req['reportType'];
 
 $screenshotID = (string)$req['screenshotID'];
 
 $Summary = (string)$req['Summary'];
 
 $reporter = (string)$req['reporter'];

 
$query $db->prepare("INSERT INTO reports VALUES (NULL, NOW(), '$regionName', '$abuserID', $catagory$checkflags, '$details', '$objectID', '$postion', $reportType, '$screenshotID', '$Summary', '$reporter')");
$result $query->execute();

 
 $response_xml xmlrpc_encode(array(
 
   'success'      => $result,
 
   'errorMessage' => get_error_message($result)
 
 ));

 
 print $response_xml;
}

$request_xml file_get_contents("php://input");

xmlrpc_server_call_method($xmlrpc_server$request_xml'');
xmlrpc_server_destroy($xmlrpc_server); 


My attempt at conversion into codeigniter:


PHP Code:
public function index()
 
   {

 
       $this->load->library('xmlrpc');
 
       $this->load->library('xmlrpcs');

 
       $config['functions']['reportuser'] =  array('function' => 'Report.reportuser');
 
       $config['object'] = $this;
 
       $config['xss_clean'] = FALSE;

 
       $this->xmlrpcs->initialize($config);
 
       $this->xmlrpcs->serve();

 
   }

 
   public function reportuser($request)
 
   {
 
       $this->load->library('xmlrpc');

 
       $zsite $this->load->database('grid'TRUE);
 
       $parameters $request->output_parameters();


 
       $data $parameters;
 
       $zsite->query("INSERT INTO TEST VALUES ('$data')");     

        $params 
$parameters[0];


 
       $regionName = (string)$params['regionName'];
 
       $abuserID = (string)$params['abuserID'];
 
       $category = (int)$params['catagory'];
 
       $checkflags = (int)$params['checkflags'];
 
       $details = (string)$params['details'];
 
       $objectID = (string)$params["objectID"];
 
       $position = (string)$params['postion'];
 
       $reportType = (int)$params['reportType'];
 
       $screenshotID = (string)$params['screenshotID'];
 
       $Summary = (string)$params['Summary'];
 
       $reporter = (string)$params['reporter'];

 
       $result $zsite->query("INSERT INTO reports VALUES (NULL, NOW(), '$regionName', '$abuserID', '$category', '$checkflags', '$details', '$objectID', '$position', '$reportType', '$screenshotID', '$Summary', '$reporter')");

 
       $response = array(
 
                       array(
 
                             'success'      => $result,
 
                             'errorMessage' => get_error_message($result),
 
               'struct'));
 
       return $this->xmlrpc->send_response($response);

 
   

The exact error this is giving me on the client end: Method reportuser, params System.Collections.Hashtable. Exception System.Xml.XmlException: Root element is missing.


I assume the implementation of xmlrpc within codeigniter is not standard and may block requests that are not properly formed or may be susceptible to xml injection and thus the request is failing, but I don't actually know. I also have no example of the request itself available due to the client being closed source. Can this be done using the bultin xmlrpc library or will I need to implement the xmlrpc server differently? Do I just have an error in the code perhaps?
Might be a bit old, but this might help ... https://github.com/jedi-academy/example-xmlrpc
Maybe I have gone code-blind lately, but that example seems to be an almost exact copy of the code a wrote. Is there anything I missed or screwed up that I am just not seeing?
In your XMLRPC client, turn debugging on to see more of what is being returned, in its raw state... $this->xmlrpc->set_debug(true);

Somewhere, something accessing some of your data is finding malformed XML. One likely cause is a blank line at the beginning of the response, usually caused by using closing PHP tags in included code server-side.

The CodeIgniter implementation is homegrown, but has worked successfully across platforms and programming languages (i.e. PHP or Java client with PHP or Java server). We built our own because the library built-in to PHP is flagged as "experimental".
I tried turning the debug on, but there is no additional information given on the client end as to the error. Unfortunately I have no way of seeing the actual xml being sent in. Is there perhaps a way to create an xmlrpc server based on the original php version or would I need to write my own library?
I have now written this:


PHP Code:
public function reportuser($request)
    {
        
        
$zsite $this->load->database('grid'TRUE);
        
        
        
$xmlrpc_server xmlrpc_server_create();
        
        
xmlrpc_server_register_method($xmlrpc_server"reportuser",
 
                             "processreport");
                             
 
                              
        $request_xml 
file_get_contents("php://input");
        
        
$zsite->query("INSERT INTO TEST_PARAMS VALUES ('$request_xml')");    
        
        
xmlrpc_server_call_method($xmlrpc_server$request_xml'');
        
xmlrpc_server_destroy($xmlrpc_server);
        
    }
    
    function 
processreport($method_name$params$app_data)
    {
        
$req        $params[0];
        
        
$regionName = (string)$req['regionName'];
        
$abuserID = (string)$req['abuserID'];
        
$category = (int)$req['catagory'];
        
$checkflags = (int)$req['checkflags'];
        
$details = (string)$req['details'];
        
$objectID = (string)$req["objectID"];
        
$position = (string)$req['postion'];
        
$reportType = (int)$req['reportType'];
        
$screenshotID = (string)$req['screenshotID'];
        
$Summary = (string)$req['Summary'];
        
$reporter = (string)$req['reporter'];
        
        
$result $zsite->query("INSERT INTO reports VALUES (NULL, NOW(), '$regionName', '$abuserID', '$category', '$checkflags', '$details', '$objectID', '$position', '$reportType', '$screenshotID', '$Summary', '$reporter')");
        
        
$response_xml xmlrpc_encode(array(
        
'success'      => $result,
        
'errorMessage' => get_error_message($result)
        ));

        print 
$response_xml;
        
        
    } 

The entry in the TEST_PARAMS db actually seems to paste the xml, but the error on the client is the same regardless. I'm sure that is progress, but I cannot interpret what exactly it means for the ci implementation of xmlrpc.

Code:
<?xml version="1.0" encoding="us-ascii"?><methodCall><methodName>reportuser</methodName><params><param><value><struct><member><name>objectID</name><value><string>00000000-0000-0000-0000-000000000000</string></value></member><member><name>checkflags</name><value><i4>0</i4></value></member><member><name>catagory</name><value><i4>31</i4></value></member><member><name>postion</name><value><string>&lt;128, 128, 21.83269&gt;</string></value></member><member><name>reporter</name><value><string>25f196a0-8dcd-4b9a-9191-4207bc9e9d95</string></value></member><member><name>abuserID</name><value><string>ae0a4aa1-20c4-478d-8e12-77839fc706f9</string></value></member><member><name>reportType</name><value><i4>3</i4></value></member><member><name>regionName</name><value><string /></value></member><member><name>details</name><value><string>V5.1.7.55786

Abuser name: test test
Abuser location: test
TEST</string></value></member><member><name>Summary</name><value><string> |Test Island|  [Age]  {test test}  "TEST"</string></value></member><member><name>screenshotID</name><value><string>2a86a4d0-d2ea-3999-6480-dd82a793a8bc</string></value></member></struct></value></param></params></methodCall>

Code:
[USER REPORTS]: Unable to connect to user reports server https://localhost/Report/reportuser/. Method reportuser, params System.Collections.Hashtable. Exception System.Xml.XmlException: Root element is missing.
 at System.Xml.XmlTextReaderImpl.Throw (System.Exception e) [0x00027] in <ced3fc41915941499fefff29c0824046>:0
 at System.Xml.XmlTextReaderImpl.ThrowWithoutLineInfo (System.String res) [0x00017] in <ced3fc41915941499fefff29c0824046>:0
 at System.Xml.XmlTextReaderImpl.ParseDocumentContent () [0x0035d] in <ced3fc41915941499fefff29c0824046>:0
 at System.Xml.XmlTextReaderImpl.Read () [0x0008c] in <ced3fc41915941499fefff29c0824046>:0
 at System.Xml.XmlTextReader.Read () [0x00000] in <ced3fc41915941499fefff29c0824046>:0
 at Nwc.XmlRpc.XmlRpcResponseDeserializer.Deserialize (System.IO.TextReader xmlData) [0x00098] in <97406e23762445718593faf816975602>:0
 at Nwc.XmlRpc.XmlRpcRequest.Send (System.String url, System.Int32 timeout) [0x000a1] in <97406e23762445718593faf816975602>:0
 at UserReports.UserReportsModule.GenericXMLRPCRequest (System.Collections.Hashtable ReqParams, System.String method, System.String server) [0x00018] in <3c9e8f6a8b4741ca9d52f111ddd00deb>:0
I am still lost as to why it would give me the same error on basically the same implementation as the procedural code I initially received.
I have made some progress. It seems that the encoding of the request is sent in us-ascii and thus the client gets a response fault code 104 malformed. I assume this is because the encoding is not utf-8, though why said response comes back in utf-16 is a bit weird itself. Checking the library I found references to utf-8 so the ci library must be expecting or accepting only utf-8 perhaps? I cannot actually change the encoding on the client, so is there a way to accept us-ascii or does this hint at another issue?
Could you send an HTTP header with the request to the server ("accept-charset: utf-8") to force the issue?
Unfortunately the client is closed source so I cannot edit how it sends the request Sad