/** * Parse the jsonrpc response contained in the string $data and return a jsonrpcresp object. * @param string $data the xmlrpc response, eventually including http headers * @param bool $headers_processed when true prevents parsing HTTP headers for interpretation of content-encoding and conseuqent decoding * @param string $return_type decides return type, i.e. content of response->value(). Either 'xmlrpcvals', 'xml' or 'phpvals' * @return jsonrpcresp * @access private */ function &parseResponse($data = '', $headers_processed = false, $return_type = 'jsonrpcvals') { if ($this->debug) { print "<PRE>---GOT---\n" . htmlentities($data) . "\n---END---\n</PRE>"; } if ($data == '') { error_log('XML-RPC: ' . __METHOD__ . ': no response received from server.'); $r = new jsonrpcresp(0, $GLOBALS['xmlrpcerr']['no_data'], $GLOBALS['xmlrpcstr']['no_data']); return $r; } $GLOBALS['_xh'] = array(); $raw_data = $data; // parse the HTTP headers of the response, if present, and separate them from data if (substr($data, 0, 4) == 'HTTP') { $r =& $this->parseResponseHeaders($data, $headers_processed); if ($r) { // parent class implementation of parseResponseHeaders returns in case // of error an object of the wrong type: recode it into correct object $rj = new jsonrpcresp(0, $r->faultCode(), $r->faultString()); $rj->raw_data = $data; return $rj; } } else { $GLOBALS['_xh']['headers'] = array(); $GLOBALS['_xh']['cookies'] = array(); } if ($this->debug) { $start = strpos($data, '/* SERVER DEBUG INFO (BASE64 ENCODED):'); if ($start !== false) { $start += strlen('/* SERVER DEBUG INFO (BASE64 ENCODED):'); $end = strpos($data, '*/', $start); $comments = substr($data, $start, $end - $start); print "<PRE>---SERVER DEBUG INFO (DECODED) ---\n\t" . htmlentities(str_replace("\n", "\n\t", base64_decode($comments))) . "\n---END---\n</PRE>"; } } // be tolerant of extra whitespace in response body $data = trim($data); // be tolerant of junk after methodResponse (e.g. javascript ads automatically inserted by free hosts) $end = strrpos($data, '}'); if ($end) { $data = substr($data, 0, $end + 1); } // if user wants back raw json, give it to him if ($return_type == 'json') { $r = new jsonrpcresp($data, 0, '', 'json'); $r->hdrs = $GLOBALS['_xh']['headers']; $r->_cookies = $GLOBALS['_xh']['cookies']; $r->raw_data = $raw_data; return $r; } // @todo shall we try to check for non-unicode json received ??? if (!jsonrpc_parse_resp($data, $return_type == 'phpvals')) { if ($this->debug) { /// @todo echo something for user? } $r = new jsonrpcresp(0, $GLOBALS['xmlrpcerr']['invalid_return'], $GLOBALS['xmlrpcstr']['invalid_return'] . ' ' . $GLOBALS['_xh']['isf_reason']); } else { $v = $GLOBALS['_xh']['value']; if ($this->debug) { print "<PRE>---PARSED---\n"; var_export($v); print "\n---END---</PRE>"; } if ($GLOBALS['_xh']['isf']) { $r = new jsonrpcresp(0, $v['faultCode'], $v['faultString']); } else { $r = new jsonrpcresp($v, 0, '', $return_type); } $r->id = $GLOBALS['_xh']['id']; } $r->hdrs = $GLOBALS['_xh']['headers']; $r->_cookies = $GLOBALS['_xh']['cookies']; $r->raw_data = $raw_data; return $r; }