\n";
foreach ($this->params as $p) {
$this->payload .= "\n" . $p->serialize($charsetEncoding) .
@@ -94,6 +101,8 @@ class Request
/**
* Add a parameter to the list of parameters to be used upon method invocation.
*
+ * Checks that $params is actually a Value object and not a plain php value.
+ *
* @param Value $param
*
* @return boolean false on failure
@@ -134,12 +143,11 @@ class Request
/**
* Given an open file handle, read all data available and parse it as an xmlrpc response.
+ *
* NB: the file handle is not closed by this function.
- * NNB: might have trouble in rare cases to work on network streams, as we
- * check for a read of 0 bytes instead of feof($fp).
- * But since checking for feof(null) returns false, we would risk an
- * infinite loop in that case, because we cannot trust the caller
- * to give us a valid pointer to an open file...
+ * NNB: might have trouble in rare cases to work on network streams, as we check for a read of 0 bytes instead of
+ * feof($fp). But since checking for feof(null) returns false, we would risk an infinite loop in that case,
+ * because we cannot trust the caller to give us a valid pointer to an open file...
*
* @param resource $fp stream pointer
*
@@ -159,17 +167,20 @@ class Request
/**
* Parse the xmlrpc response contained in the string $data and return a Response object.
*
- * @param string $data the xmlrpc response, eventually including http headers
- * @param bool $headersProcessed when true prevents parsing HTTP headers for interpretation of content-encoding and consequent decoding
- * @param string $returnType decides return type, i.e. content of response->value(). Either 'xmlrpcvals', 'xml' or 'phpvals'
+ * When $this->debug has been set to a value greater than 0, will echo debug messages to screen while decoding.
+ *
+ * @param string $data the xmlrpc response, possibly including http headers
+ * @param bool $headersProcessed when true prevents parsing HTTP headers for interpretation of content-encoding and
+ * consequent decoding
+ * @param string $returnType decides return type, i.e. content of response->value(). Either 'xmlrpcvals', 'xml' or
+ * 'phpvals'
*
* @return Response
*/
public function parseResponse($data = '', $headersProcessed = false, $returnType = 'xmlrpcvals')
{
if ($this->debug) {
- // by maHo, replaced htmlspecialchars with htmlentities
- $this->debugMessage("---GOT---\n$data\n---END---");
+ Logger::instance()->debugMessage("---GOT---\n$data\n---END---");
}
$this->httpResponse = array('raw_data' => $data, 'headers' => array(), 'cookies' => array());
@@ -194,16 +205,6 @@ class Request
}
}
- if ($this->debug) {
- $start = strpos($data, '', $start);
- $comments = substr($data, $start, $end - $start);
- $this->debugMessage("---SERVER DEBUG INFO (DECODED) ---\n\t" . str_replace("\n", "\n\t", base64_decode($comments))) . "\n---END---\n";
- }
- }
-
// be tolerant of extra whitespace in response body
$data = trim($data);
@@ -216,6 +217,20 @@ class Request
$data = substr($data, 0, $pos + 17);
}
+ // try to 'guestimate' the character encoding of the received response
+ $respEncoding = XMLParser::guessEncoding(@$this->httpResponse['headers']['content-type'], $data);
+
+ if ($this->debug) {
+ $start = strpos($data, '', $start);
+ $comments = substr($data, $start, $end - $start);
+ Logger::instance()->debugMessage("---SERVER DEBUG INFO (DECODED) ---\n\t" .
+ str_replace("\n", "\n\t", base64_decode($comments)) . "\n---END---", $respEncoding);
+ }
+ }
+
// if user wants back raw xml, give it to him
if ($returnType == 'xml') {
$r = new Response($data, 0, '', 'xml');
@@ -226,20 +241,27 @@ class Request
return $r;
}
- // try to 'guestimate' the character encoding of the received response
- $resp_encoding = Encoder::guess_encoding(@$this->httpResponse['headers']['content-type'], $data);
+ if ($respEncoding != '') {
- // if response charset encoding is not known / supported, try to use
- // the default encoding and parse the xml anyway, but log a warning...
- if (!in_array($resp_encoding, array('UTF-8', 'ISO-8859-1', 'US-ASCII'))) {
- // the following code might be better for mb_string enabled installs, but
+ // Since parsing will fail if charset is not specified in the xml prologue,
+ // the encoding is not UTF8 and there are non-ascii chars in the text, we try to work round that...
+ // The following code might be better for mb_string enabled installs, but
// makes the lib about 200% slower...
- //if (!is_valid_charset($resp_encoding, array('UTF-8', 'ISO-8859-1', 'US-ASCII')))
-
- error_log('XML-RPC: ' . __METHOD__ . ': invalid charset encoding of received response: ' . $resp_encoding);
- $resp_encoding = PhpXmlRpc::$xmlrpc_defencoding;
+ //if (!is_valid_charset($respEncoding, array('UTF-8')))
+ if (!in_array($respEncoding, array('UTF-8', 'US-ASCII')) && !XMLParser::hasEncoding($data)) {
+ if ($respEncoding == 'ISO-8859-1') {
+ $data = utf8_encode($data);
+ } else {
+ if (extension_loaded('mbstring')) {
+ $data = mb_convert_encoding($data, 'UTF-8', $respEncoding);
+ } else {
+ error_log('XML-RPC: ' . __METHOD__ . ': invalid charset encoding of received response: ' . $respEncoding);
+ }
+ }
+ }
}
- $parser = xml_parser_create($resp_encoding);
+
+ $parser = xml_parser_create();
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true);
// G. Giunta 2005/02/13: PHP internally uses ISO-8859-1, so we have to tell
// the xml parser to give us back data in the expected charset.
@@ -306,9 +328,9 @@ class Request
$r = new Response(0, PhpXmlRpc::$xmlrpcerr['invalid_return'],
PhpXmlRpc::$xmlrpcstr['invalid_return']);
} else {
- if ($this->debug) {
- $this->debugMessage(
- "---PARSED---\n".var_export($xmlRpcParser->_xh['value'], true)."\n---END---", false
+ if ($this->debug > 1) {
+ Logger::instance()->debugMessage(
+ "---PARSED---\n".var_export($xmlRpcParser->_xh['value'], true)."\n---END---"
);
}
@@ -316,11 +338,10 @@ class Request
$v = &$xmlRpcParser->_xh['value'];
if ($xmlRpcParser->_xh['isf']) {
- /// @todo we should test here if server sent an int and a string,
- /// and/or coerce them into such...
+ /// @todo we should test here if server sent an int and a string, and/or coerce them into such...
if ($returnType == 'xmlrpcvals') {
- $errNo_v = $v->structmem('faultCode');
- $errStr_v = $v->structmem('faultString');
+ $errNo_v = $v['faultCode'];
+ $errStr_v = $v['faultString'];
$errNo = $errNo_v->scalarval();
$errStr = $errStr_v->scalarval();
} else {
@@ -347,21 +368,22 @@ class Request
}
/**
- * Echoes a debug message, taking care of escaping it when not in console mode
+ * Kept the old name even if Request class was renamed, for compatibility.
*
- * @param string $message
- * @param bool $encodeEntities when false, escapes using htmlspecialchars instead of htmlentities
+ * @return string
*/
- protected function debugMessage($message, $encodeEntities = true)
+ public function kindOf()
{
- if (PHP_SAPI != 'cli') {
- if ($encodeEntities)
- print "\n".htmlentities($message)."\n
";
- else
- print "\n".htmlspecialchars($message)."\n
";
- }
- else {
- print "\n$message\n";
- }
+ return 'msg';
+ }
+
+ /**
+ * Enables/disables the echoing to screen of the xmlrpc responses received.
+ *
+ * @param integer $in values 0, 1, 2 are supported
+ */
+ public function setDebug($in)
+ {
+ $this->debug = $in;
}
}