$credentials='Authorization: Basic ' . base64_encode($username . ':' . $password) . "\r\n";\r
if ($authtype != 1)\r
{\r
- error_log('XML-RPC: xmlrpc_client::send: warning. Only Basic auth is supported with HTTP 1.0');\r
+ error_log('XML-RPC: '.__METHOD__.': warning. Only Basic auth is supported with HTTP 1.0');\r
}\r
}\r
\r
{\r
if ($proxyauthtype != 1)\r
{\r
- error_log('XML-RPC: xmlrpc_client::send: warning. Only Basic auth to proxy is supported with HTTP 1.0');\r
+ error_log('XML-RPC: '.__METHOD__.': warning. Only Basic auth to proxy is supported with HTTP 1.0');\r
}\r
$proxy_credentials = 'Proxy-Authorization: Basic ' . base64_encode($proxyusername.':'.$proxypassword) . "\r\n";\r
}\r
}\r
else if ($authtype != 1)\r
{\r
- error_log('XML-RPC: xmlrpc_client::send: warning. Only Basic auth is supported by the current PHP/curl install');\r
+ error_log('XML-RPC: '.__METHOD__.': warning. Only Basic auth is supported by the current PHP/curl install');\r
}\r
}\r
\r
}\r
else if ($proxyauthtype != 1)\r
{\r
- error_log('XML-RPC: xmlrpc_client::send: warning. Only Basic auth to proxy is supported by the current PHP/curl install');\r
+ error_log('XML-RPC: '.__METHOD__.': warning. Only Basic auth to proxy is supported by the current PHP/curl install');\r
}\r
}\r
}\r
curl_setopt($curl, CURLOPT_COOKIE, substr($cookieheader, 0, -2));\r
}\r
\r
- foreach ($this->extracurlopts as $opt => $val)\r
- {\r
- curl_setopt($curl, $opt, $val);\r
- }\r
+ foreach ($this->extracurlopts as $opt => $val)\r
+ {\r
+ curl_setopt($curl, $opt, $val);\r
+ }\r
\r
$result = curl_exec($curl);\r
\r
}\r
else\r
{\r
- error_log('XML-RPC: xmlrpcmsg::parseResponse: HTTPS via proxy error, tunnel connection possibly failed');\r
+ error_log('XML-RPC: '.__METHOD__.': HTTPS via proxy error, tunnel connection possibly failed');\r
$r=new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['http_error'], $GLOBALS['xmlrpcstr']['http_error']. ' (HTTPS via proxy error, tunnel connection possibly failed)');\r
return $r;\r
}\r
if(!preg_match('/^HTTP\/[0-9.]+ 200 /', $data))\r
{\r
$errstr= substr($data, 0, strpos($data, "\n")-1);\r
- error_log('XML-RPC: xmlrpcmsg::parseResponse: HTTP error, got response: ' .$errstr);\r
+ error_log('XML-RPC: '.__METHOD__.': HTTP error, got response: ' .$errstr);\r
$r=new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['http_error'], $GLOBALS['xmlrpcstr']['http_error']. ' (' . $errstr . ')');\r
return $r;\r
}\r
{\r
if(!$data = decode_chunked($data))\r
{\r
- error_log('XML-RPC: xmlrpcmsg::parseResponse: errors occurred when trying to rebuild the chunked data received from server');\r
+ error_log('XML-RPC: '.__METHOD__.': errors occurred when trying to rebuild the chunked data received from server');\r
$r = new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['dechunk_fail'], $GLOBALS['xmlrpcstr']['dechunk_fail']);\r
return $r;\r
}\r
}\r
else\r
{\r
- error_log('XML-RPC: xmlrpcmsg::parseResponse: errors occurred when trying to decode the deflated data received from server');\r
+ error_log('XML-RPC: '.__METHOD__.': errors occurred when trying to decode the deflated data received from server');\r
$r = new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['decompress_fail'], $GLOBALS['xmlrpcstr']['decompress_fail']);\r
return $r;\r
}\r
}\r
else\r
{\r
- error_log('XML-RPC: xmlrpcmsg::parseResponse: the server sent deflated data. Your php install must have the Zlib extension compiled in to support this.');\r
+ error_log('XML-RPC: '.__METHOD__.': the server sent deflated data. Your php install must have the Zlib extension compiled in to support this.');\r
$r = new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['cannot_decompress'], $GLOBALS['xmlrpcstr']['cannot_decompress']);\r
return $r;\r
}\r
}\r
} // end of 'if needed, de-chunk, re-inflate response'\r
\r
- // real stupid hack to avoid PHP 4 complaining about returning NULL by ref\r
+ // real stupid hack to avoid PHP complaining about returning NULL by ref\r
$r = null;\r
$r =& $r;\r
return $r;\r
\r
if($data == '')\r
{\r
- error_log('XML-RPC: xmlrpcmsg::parseResponse: no response received from server.');\r
+ error_log('XML-RPC: '.__METHOD__.': no response received from server.');\r
$r = new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['no_data'], $GLOBALS['xmlrpcstr']['no_data']);\r
return $r;\r
}\r
\r
// be tolerant of junk after methodResponse (e.g. javascript ads automatically inserted by free hosts)\r
// idea from Luca Mariano <luca.mariano@email.it> originally in PEARified version of the lib\r
- $bd = false;\r
- // Poor man's version of strrpos for php 4...\r
- $pos = strpos($data, '</methodResponse>');\r
- while($pos || is_int($pos))\r
- {\r
- $bd = $pos+17;\r
- $pos = strpos($data, '</methodResponse>', $bd);\r
- }\r
- if($bd)\r
+ $pos = strrpos($data, '</methodResponse>');\r
+ if($pos !== false)\r
{\r
- $data = substr($data, 0, $bd);\r
+ $data = substr($data, 0, $pos+17);\r
}\r
\r
// if user wants back raw xml, give it to him\r
// makes the lib about 200% slower...\r
//if (!is_valid_charset($resp_encoding, array('UTF-8', 'ISO-8859-1', 'US-ASCII')))\r
{\r
- error_log('XML-RPC: xmlrpcmsg::parseResponse: invalid charset encoding of received response: '.$resp_encoding);\r
+ error_log('XML-RPC: '.__METHOD__.': invalid charset encoding of received response: '.$resp_encoding);\r
$resp_encoding = $GLOBALS['xmlrpc_defencoding'];\r
}\r
$parser = xml_parser_create($resp_encoding);\r
$this->me['struct']=$val;\r
break;\r
default:\r
- error_log("XML-RPC: xmlrpcval::xmlrpcval: not a known type ($type)");\r
+ error_log("XML-RPC: ".__METHOD__.": not a known type ($type)");\r
}\r
/*if($type=='')\r
{\r
$typeof=@$GLOBALS['xmlrpcTypes'][$type];\r
if($typeof!=1)\r
{\r
- error_log("XML-RPC: xmlrpcval::addScalar: not a scalar type ($type)");\r
+ error_log("XML-RPC: ".__METHOD__.": not a scalar type ($type)");\r
return 0;\r
}\r
\r
switch($this->mytype)\r
{\r
case 1:\r
- error_log('XML-RPC: xmlrpcval::addScalar: scalar xmlrpcval can have only one value');\r
+ error_log('XML-RPC: '.__METHOD__.': scalar xmlrpcval can have only one value');\r
return 0;\r
case 3:\r
- error_log('XML-RPC: xmlrpcval::addScalar: cannot add anonymous scalar to struct xmlrpcval');\r
+ error_log('XML-RPC: '.__METHOD__.': cannot add anonymous scalar to struct xmlrpcval');\r
return 0;\r
case 2:\r
// we're adding a scalar value to an array here\r
}\r
else\r
{\r
- error_log('XML-RPC: xmlrpcval::addArray: already initialized as a [' . $this->kindOf() . ']');\r
+ error_log('XML-RPC: '.__METHOD__.': already initialized as a [' . $this->kindOf() . ']');\r
return 0;\r
}\r
}\r
}\r
else\r
{\r
- error_log('XML-RPC: xmlrpcval::addStruct: already initialized as a [' . $this->kindOf() . ']');\r
+ error_log('XML-RPC: '.__METHOD__.': already initialized as a [' . $this->kindOf() . ']');\r
return 0;\r
}\r
}\r
break;\r
case $GLOBALS['xmlrpcDouble']:\r
// avoid using standard conversion of float to string because it is locale-dependent,\r
- // and also because the xmlrpc spec forbids exponential notation\r
- // sprintf('%F') would be most likely ok but it is only available since PHP 4.3.10 and PHP 5.0.3.\r
+ // and also because the xmlrpc spec forbids exponential notation.\r
+ // sprintf('%F') could be most likely ok but it fails eg. on 2e-14.\r
// The code below tries its best at keeping max precision while avoiding exp notation,\r
// but there is of course no limit in the number of decimal places to be used...\r
$rs.="<${typ}>".preg_replace('/\\.?0+$/','',number_format((double)$val, 128, '.', ''))."</${typ}>";\r
\r
$GLOBALS['_xmlrpcs_occurred_errors'] = '';\r
$GLOBALS['_xmlrpcs_prev_ehandler'] = '';\r
+\r
/**\r
* Error handler used to track errors that occur during server-side execution of PHP code.\r
* This allows to report back to the client whether an internal error has occurred or not\r
return;\r
\r
//if($errcode != E_NOTICE && $errcode != E_WARNING && $errcode != E_USER_NOTICE && $errcode != E_USER_WARNING)\r
- if($errcode != 2048) // do not use E_STRICT by name, since on PHP 4 it will not be defined\r
+ if($errcode != E_STRICT)\r
{\r
$GLOBALS['_xmlrpcs_occurred_errors'] = $GLOBALS['_xmlrpcs_occurred_errors'] . $errstring . "\n";\r
}\r
* valid strings are 'xmlrpcvals', 'phpvals' or 'epivals'\r
*/\r
var $functions_parameters_type='xmlrpcvals';\r
- /**\r
- * Option used for fine-tuning the encoding the php values returned from\r
- * functions registered in the dispatch map when the functions_parameters_types\r
- * member is set to 'phpvals'\r
- * @see php_xmlrpc_encode for a list of values\r
- */\r
- var $phpvals_encoding_options = array( 'auto_dates' );\r
+ /**\r
+ * Option used for fine-tuning the encoding the php values returned from\r
+ * functions registered in the dispatch map when the functions_parameters_types\r
+ * member is set to 'phpvals'\r
+ * @see php_xmlrpc_encode for a list of values\r
+ */\r
+ var $phpvals_encoding_options = array( 'auto_dates' );\r
/// controls wether the server is going to echo debugging messages back to the client as comments in response body. valid values: 0,1,2,3\r
var $debug = 1;\r
/**\r
+ * Controls behaviour of server when invoked user function throws an exception:\r
+ * 0 = catch it and return an 'internal error' xmlrpc response (default)\r
+ * 1 = catch it and return an xmlrpc response with the error corresponding to the exception\r
+ * 2 = allow the exception to float to the upper layers\r
+ */\r
+ var $exception_handling = 0;\r
+ /**\r
* When set to true, it will enable HTTP compression of the response, in case\r
* the client has declared its support for compression in the request.\r
*/\r
}\r
else\r
{\r
- error_log('XML-RPC: xmlrpc_server::service: http headers already sent before response is fully generated. Check for php warning or error messages');\r
+ error_log('XML-RPC: '.__METHOD__.': http headers already sent before response is fully generated. Check for php warning or error messages');\r
}\r
\r
print $payload;\r
}\r
if ($sigdoc)\r
{\r
- $this->dmap[$methodname]['signature_docs'] = $sigdoc;\r
+ $this->dmap[$methodname]['signature_docs'] = $sigdoc;\r
}\r
}\r
\r
*/\r
function parseRequestHeaders(&$data, &$req_encoding, &$resp_encoding, &$resp_compression)\r
{\r
- // Play nice to PHP 4.0.x: superglobals were not yet invented...\r
- if(!isset($_SERVER))\r
+ // check if $_SERVER is populated: it might have been disabled via ini file\r
+ // (this is true even when in CLI mode)\r
+ if (count($_SERVER) == 0)\r
{\r
- $_SERVER = $GLOBALS['HTTP_SERVER_VARS'];\r
+ error_log('XML-RPC: '.__METHOD__.': cannot parse request headers as $_SERVER is not populated');\r
}\r
\r
if($this->debug > 1)\r
// makes the lib about 200% slower...\r
//if (!is_valid_charset($req_encoding, array('UTF-8', 'ISO-8859-1', 'US-ASCII')))\r
{\r
- error_log('XML-RPC: xmlrpc_server::parseRequest: invalid charset encoding of received request: '.$req_encoding);\r
+ error_log('XML-RPC: '.__METHOD__.': invalid charset encoding of received request: '.$req_encoding);\r
$req_encoding = $GLOBALS['xmlrpc_defencoding'];\r
}\r
/// @BUG this will fail on PHP 5 if charset is not specified in the xml prologue,\r
else\r
{\r
xml_parser_free($parser);\r
- // small layering violation in favor of speed and memory usage:\r
- // we should allow the 'execute' method handle this, but in the\r
- // most common scenario (xmlrpcvals type server with some methods\r
- // registered as phpvals) that would mean a useless encode+decode pass\r
+ // small layering violation in favor of speed and memory usage:\r
+ // we should allow the 'execute' method handle this, but in the\r
+ // most common scenario (xmlrpcvals type server with some methods\r
+ // registered as phpvals) that would mean a useless encode+decode pass\r
if ($this->functions_parameters_type != 'xmlrpcvals' || (isset($this->dmap[$GLOBALS['_xh']['method']]['parameters_type']) && ($this->dmap[$GLOBALS['_xh']['method']]['parameters_type'] == 'phpvals')))\r
{\r
if($this->debug > 1)\r
// verify that function to be invoked is in fact callable\r
if(!is_callable($func))\r
{\r
- error_log("XML-RPC: xmlrpc_server::execute: function $func registered as method handler is not callable");\r
+ error_log("XML-RPC: ".__METHOD__.": function $func registered as method handler is not callable");\r
return new xmlrpcresp(\r
0,\r
$GLOBALS['xmlrpcerr']['server_error'],\r
{\r
$GLOBALS['_xmlrpcs_prev_ehandler'] = set_error_handler('_xmlrpcs_errorHandler');\r
}\r
- // Allow mixed-convention servers\r
- if (is_object($m))\r
+ try\r
{\r
- if($sysCall)\r
- {\r
- $r = call_user_func($func, $this, $m);\r
- }\r
- else\r
- {\r
- $r = call_user_func($func, $m);\r
- }\r
- if (!is_a($r, 'xmlrpcresp'))\r
+ // Allow mixed-convention servers\r
+ if (is_object($m))\r
{\r
- error_log("XML-RPC: xmlrpc_server::execute: function $func registered as method handler does not return an xmlrpcresp object");\r
- if (is_a($r, 'xmlrpcval'))\r
+ if($sysCall)\r
{\r
- $r = new xmlrpcresp($r);\r
+ $r = call_user_func($func, $this, $m);\r
}\r
else\r
{\r
- $r = new xmlrpcresp(\r
- 0,\r
- $GLOBALS['xmlrpcerr']['server_error'],\r
- $GLOBALS['xmlrpcstr']['server_error'] . ": function does not return xmlrpcresp object"\r
- );\r
+ $r = call_user_func($func, $m);\r
+ }\r
+ if (!is_a($r, 'xmlrpcresp'))\r
+ {\r
+ error_log("XML-RPC: ".__METHOD__.": function $func registered as method handler does not return an xmlrpcresp object");\r
+ if (is_a($r, 'xmlrpcval'))\r
+ {\r
+ $r = new xmlrpcresp($r);\r
+ }\r
+ else\r
+ {\r
+ $r = new xmlrpcresp(\r
+ 0,\r
+ $GLOBALS['xmlrpcerr']['server_error'],\r
+ $GLOBALS['xmlrpcstr']['server_error'] . ": function does not return xmlrpcresp object"\r
+ );\r
+ }\r
}\r
- }\r
- }\r
- else\r
- {\r
- // call a 'plain php' function\r
- if($sysCall)\r
- {\r
- array_unshift($params, $this);\r
- $r = call_user_func_array($func, $params);\r
}\r
else\r
{\r
- // 3rd API convention for method-handling functions: EPI-style\r
- if ($this->functions_parameters_type == 'epivals')\r
+ // call a 'plain php' function\r
+ if($sysCall)\r
+ {\r
+ array_unshift($params, $this);\r
+ $r = call_user_func_array($func, $params);\r
+ }\r
+ else\r
{\r
- $r = call_user_func_array($func, array($methName, $params, $this->user_data));\r
- // mimic EPI behaviour: if we get an array that looks like an error, make it\r
- // an eror response\r
- if (is_array($r) && array_key_exists('faultCode', $r) && array_key_exists('faultString', $r))\r
+ // 3rd API convention for method-handling functions: EPI-style\r
+ if ($this->functions_parameters_type == 'epivals')\r
{\r
- $r = new xmlrpcresp(0, (integer)$r['faultCode'], (string)$r['faultString']);\r
+ $r = call_user_func_array($func, array($methName, $params, $this->user_data));\r
+ // mimic EPI behaviour: if we get an array that looks like an error, make it\r
+ // an eror response\r
+ if (is_array($r) && array_key_exists('faultCode', $r) && array_key_exists('faultString', $r))\r
+ {\r
+ $r = new xmlrpcresp(0, (integer)$r['faultCode'], (string)$r['faultString']);\r
+ }\r
+ else\r
+ {\r
+ // functions using EPI api should NOT return resp objects,\r
+ // so make sure we encode the return type correctly\r
+ $r = new xmlrpcresp(php_xmlrpc_encode($r, array('extension_api')));\r
+ }\r
}\r
else\r
{\r
- // functions using EPI api should NOT return resp objects,\r
- // so make sure we encode the return type correctly\r
- $r = new xmlrpcresp(php_xmlrpc_encode($r, array('extension_api')));\r
+ $r = call_user_func_array($func, $params);\r
}\r
}\r
- else\r
+ // the return type can be either an xmlrpcresp object or a plain php value...\r
+ if (!is_a($r, 'xmlrpcresp'))\r
{\r
- $r = call_user_func_array($func, $params);\r
+ // what should we assume here about automatic encoding of datetimes\r
+ // and php classes instances???\r
+ $r = new xmlrpcresp(php_xmlrpc_encode($r, $this->phpvals_encoding_options));\r
}\r
}\r
- // the return type can be either an xmlrpcresp object or a plain php value...\r
- if (!is_a($r, 'xmlrpcresp'))\r
+ }\r
+ catch(Exception $e)\r
+ {\r
+ // (barring errors in the lib) an uncatched exception happened\r
+ // in the called function, we wrap it in a proper error-response\r
+ switch($this->exception_handling)\r
{\r
- // what should we assume here about automatic encoding of datetimes\r
- // and php classes instances???\r
- $r = new xmlrpcresp(php_xmlrpc_encode($r, $this->phpvals_encoding_options));\r
+ case 2:\r
+ throw $e;\r
+ break;\r
+ case 1:\r
+ $r = new xmlrpcresp(0, $e->getCode(), $e->getMessage());\r
+ break;\r
+ default:\r
+ $r = new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['server_error'], $GLOBALS['xmlrpcstr']['server_error']);\r
}\r
}\r
if($this->debug > 2)\r