From 9ff27b2483717ec728dda6a9045d2146e85bde86 Mon Sep 17 00:00:00 2001 From: gggeek Date: Tue, 24 Mar 2015 13:51:49 +0000 Subject: [PATCH] Refactoring ongoing: move http headers parsing away from response into http class; CamelCase everything; move proxy server and demo server to new api --- demo/server/proxy.php | 40 ++++---- demo/server/server.php | 2 +- lib/xmlrpc.inc | 5 +- src/Helper/Charset.php | 4 +- src/Helper/Http.php | 205 +++++++++++++++++++++++++++++++++++++++- src/Request.php | 208 ++--------------------------------------- src/Response.php | 37 ++++---- src/Server.php | 2 +- src/Value.php | 17 ++-- 9 files changed, 263 insertions(+), 257 deletions(-) diff --git a/demo/server/proxy.php b/demo/server/proxy.php index 64ad459..4f860de 100644 --- a/demo/server/proxy.php +++ b/demo/server/proxy.php @@ -8,28 +8,30 @@ * @copyright (C) 2006-2015 G. Giunta * @license code licensed under the BSD License: see file license.txt */ -include_once __DIR__ . "/../../vendor/autoload.php"; -include_once __DIR__ . "/../../lib/xmlrpc.inc"; -include_once __DIR__ . "/../../lib/xmlrpcs.inc"; +include_once __DIR__ . "/../../src/Autoloader.php"; +PhpXmlRpc\Autoloader::register(); /** * Forward an xmlrpc request to another server, and return to client the response received. * - * @param xmlrpcmsg $m (see method docs below for a description of the expected parameters) + * @param PhpXmlRpc\Request $req (see method docs below for a description of the expected parameters) * - * @return xmlrpcresp + * @return PhpXmlRpc\Response */ -function forward_request($m) +function forward_request($req) { + $encoder = new \PhpXmlRpc\Encoder(); + // create client $timeout = 0; - $url = php_xmlrpc_decode($m->getParam(0)); - $c = new PhpXmlRpc\Client($url); - if ($m->getNumParams() > 3) { + $url = $encoder->decode($req->getParam(0)); + $client = new PhpXmlRpc\Client($url); + + if ($req->getNumParams() > 3) { // we have to set some options onto the client. // Note that if we do not untaint the received values, warnings might be generated... - $options = php_xmlrpc_decode($m->getParam(3)); + $options = $encoder->decode($req->getParam(3)); foreach ($options as $key => $val) { switch ($key) { case 'Cookie': @@ -37,13 +39,13 @@ function forward_request($m) case 'Credentials': break; case 'RequestCompression': - $c->setRequestCompression($val); + $client->setRequestCompression($val); break; case 'SSLVerifyHost': - $c->setSSLVerifyHost($val); + $client->setSSLVerifyHost($val); break; case 'SSLVerifyPeer': - $c->setSSLVerifyPeer($val); + $client->setSSLVerifyPeer($val); break; case 'Timeout': $timeout = (integer)$val; @@ -56,17 +58,17 @@ function forward_request($m) /// @todo find a way to forward client info (such as IP) to server, either /// - as xml comments in the payload, or /// - using std http header conventions, such as X-forwarded-for... - $method = php_xmlrpc_decode($m->getParam(1)); - $pars = $m->getParam(2); - $m = new PhpXmlRpc\Request($method); + $reqethod = $encoder->decode($req->getParam(1)); + $pars = $req->getParam(2); + $req = new PhpXmlRpc\Request($reqethod); for ($i = 0; $i < $pars->arraySize(); $i++) { - $m->addParam($pars->arraymem($i)); + $req->addParam($pars->arraymem($i)); } // add debug info into response we give back to caller - xmlrpc_debugmsg("Sending to server $url the payload: " . $m->serialize()); + PhpXmlRpc\Server::xmlrpc_debugmsg("Sending to server $url the payload: " . $req->serialize()); - return $c->send($m, $timeout); + return $client->send($req, $timeout); } // run the server diff --git a/demo/server/server.php b/demo/server/server.php index eefaa38..03bbab5 100644 --- a/demo/server/server.php +++ b/demo/server/server.php @@ -141,7 +141,7 @@ $findstate3_sig = wrap_php_function(array('xmlrpc_server_methods_container', 'fi $findstate5_sig = wrap_php_function('xmlrpc_server_methods_container::findstate'); -$obj = new PhpXmlRpc\Server_methods_container(); +$obj = new xmlrpc_server_methods_container(); $findstate4_sig = wrap_php_function(array($obj, 'findstate')); $addtwo_sig = array(array($xmlrpcInt, $xmlrpcInt, $xmlrpcInt)); diff --git a/lib/xmlrpc.inc b/lib/xmlrpc.inc index 51b175d..01323fe 100644 --- a/lib/xmlrpc.inc +++ b/lib/xmlrpc.inc @@ -143,9 +143,10 @@ class xmlrpc_client extends PhpXmlRpc\Client /* Expose as global functions the ones which are now class methods */ +/// Wrong speling, but we are adamant on backwards compatibility! function xmlrpc_encode_entitites($data, $srcEncoding='', $destEncoding='') { - return PhpXmlRpc\Helper\Charset::instance()->encode_entitites($data, $srcEncoding, $destEncoding); + return PhpXmlRpc\Helper\Charset::instance()->encodeEntitites($data, $srcEncoding, $destEncoding); } function iso8601_encode($timeT, $utc=0) @@ -160,7 +161,7 @@ function iso8601_decode($iDate, $utc=0) function decode_chunked($buffer) { - return PhpXmlRpc\Helper\Http::decode_chunked($buffer); + return PhpXmlRpc\Helper\Http::decodeChunked($buffer); } function php_xmlrpc_decode($xmlrpcVal, $options=array()) diff --git a/src/Helper/Charset.php b/src/Helper/Charset.php index 6d5eb6a..b23b5c5 100644 --- a/src/Helper/Charset.php +++ b/src/Helper/Charset.php @@ -87,7 +87,7 @@ class Charset * * @return string */ - public function encode_entities($data, $src_encoding = '', $dest_encoding = '') + public function encodeEntities($data, $src_encoding = '', $dest_encoding = '') { if ($src_encoding == '') { // lame, but we know no better... @@ -218,7 +218,7 @@ class Charset * * @return bool */ - public function is_valid_charset($encoding, $validList) + public function isValidCharset($encoding, $validList) { if (is_string($validList)) { $validList = explode(',', $validList); diff --git a/src/Helper/Http.php b/src/Helper/Http.php index 02bfd57..09be1f3 100644 --- a/src/Helper/Http.php +++ b/src/Helper/Http.php @@ -2,10 +2,12 @@ namespace PhpXmlRpc\Helper; +use PhpXmlRpc\PhpXmlRpc; + class Http { /** - * decode a string that is encoded w/ "chunked" transfer encoding + * Decode a string that is encoded w/ "chunked" transfer encoding * as defined in rfc2068 par. 19.4.6 * code shamelessly stolen from nusoap library by Dietrich Ayala. * @@ -13,7 +15,7 @@ class Http * * @return string */ - public static function decode_chunked($buffer) + public static function decodeChunked($buffer) { // length := 0 $length = 0; @@ -57,4 +59,203 @@ class Http return $new; } + + /** + * Parses HTTP an http response headers and separates them from the body. + * + * @param string $data the http response,headers and body. It will be stripped of headers + * @param bool $headersProcessed when true, we assume that response inflating and dechunking has been already carried out + * + * @return array with keys 'headers' and 'cookies' + * @throws \Exception + */ + public function parseResponseHeaders(&$data, $headersProcessed = false, $debug=0) + { + $httpResponse = array('raw_data' => $data, 'headers'=> array(), 'cookies' => array()); + + // Support "web-proxy-tunelling" connections for https through proxies + if (preg_match('/^HTTP\/1\.[0-1] 200 Connection established/', $data)) { + // Look for CR/LF or simple LF as line separator, + // (even though it is not valid http) + $pos = strpos($data, "\r\n\r\n"); + if ($pos || is_int($pos)) { + $bd = $pos + 4; + } else { + $pos = strpos($data, "\n\n"); + if ($pos || is_int($pos)) { + $bd = $pos + 2; + } else { + // No separation between response headers and body: fault? + $bd = 0; + } + } + if ($bd) { + // this filters out all http headers from proxy. + // maybe we could take them into account, too? + $data = substr($data, $bd); + } else { + error_log('XML-RPC: ' . __METHOD__ . ': HTTPS via proxy error, tunnel connection possibly failed'); + throw new \Exception(PhpXmlRpc::$xmlrpcstr['http_error'] . ' (HTTPS via proxy error, tunnel connection possibly failed)', PhpXmlRpc::$xmlrpcerr['http_error']); + } + } + + // Strip HTTP 1.1 100 Continue header if present + while (preg_match('/^HTTP\/1\.1 1[0-9]{2} /', $data)) { + $pos = strpos($data, 'HTTP', 12); + // server sent a Continue header without any (valid) content following... + // give the client a chance to know it + if (!$pos && !is_int($pos)) { + // works fine in php 3, 4 and 5 + + break; + } + $data = substr($data, $pos); + } + if (!preg_match('/^HTTP\/[0-9.]+ 200 /', $data)) { + $errstr = substr($data, 0, strpos($data, "\n") - 1); + error_log('XML-RPC: ' . __METHOD__ . ': HTTP error, got response: ' . $errstr); + throw new \Exception(PhpXmlRpc::$xmlrpcstr['http_error'] . ' (' . $errstr . ')', PhpXmlRpc::$xmlrpcerr['http_error']); + } + + // be tolerant to usage of \n instead of \r\n to separate headers and data + // (even though it is not valid http) + $pos = strpos($data, "\r\n\r\n"); + if ($pos || is_int($pos)) { + $bd = $pos + 4; + } else { + $pos = strpos($data, "\n\n"); + if ($pos || is_int($pos)) { + $bd = $pos + 2; + } else { + // No separation between response headers and body: fault? + // we could take some action here instead of going on... + $bd = 0; + } + } + // be tolerant to line endings, and extra empty lines + $ar = preg_split("/\r?\n/", trim(substr($data, 0, $pos))); + while (list(, $line) = @each($ar)) { + // take care of multi-line headers and cookies + $arr = explode(':', $line, 2); + if (count($arr) > 1) { + $header_name = strtolower(trim($arr[0])); + /// @todo some other headers (the ones that allow a CSV list of values) + /// do allow many values to be passed using multiple header lines. + /// We should add content to $xmlrpc->_xh['headers'][$header_name] + /// instead of replacing it for those... + if ($header_name == 'set-cookie' || $header_name == 'set-cookie2') { + if ($header_name == 'set-cookie2') { + // version 2 cookies: + // there could be many cookies on one line, comma separated + $cookies = explode(',', $arr[1]); + } else { + $cookies = array($arr[1]); + } + foreach ($cookies as $cookie) { + // glue together all received cookies, using a comma to separate them + // (same as php does with getallheaders()) + if (isset($httpResponse['headers'][$header_name])) { + $httpResponse['headers'][$header_name] .= ', ' . trim($cookie); + } else { + $httpResponse['headers'][$header_name] = trim($cookie); + } + // parse cookie attributes, in case user wants to correctly honour them + // feature creep: only allow rfc-compliant cookie attributes? + // @todo support for server sending multiple time cookie with same name, but using different PATHs + $cookie = explode(';', $cookie); + foreach ($cookie as $pos => $val) { + $val = explode('=', $val, 2); + $tag = trim($val[0]); + $val = trim(@$val[1]); + /// @todo with version 1 cookies, we should strip leading and trailing " chars + if ($pos == 0) { + $cookiename = $tag; + $httpResponse['cookies'][$tag] = array(); + $httpResponse['cookies'][$cookiename]['value'] = urldecode($val); + } else { + if ($tag != 'value') { + $httpResponse['cookies'][$cookiename][$tag] = $val; + } + } + } + } + } else { + $httpResponse['headers'][$header_name] = trim($arr[1]); + } + } elseif (isset($header_name)) { + /// @todo version1 cookies might span multiple lines, thus breaking the parsing above + $httpResponse['headers'][$header_name] .= ' ' . trim($line); + } + } + + $data = substr($data, $bd); + + if ($debug && count($httpResponse['headers'])) { + $msg = ''; + foreach ($httpResponse['headers'] as $header => $value) { + $msg .= "HEADER: $header: $value\n"; + } + foreach ($httpResponse['cookies'] as $header => $value) { + $msg .= "COOKIE: $header={$value['value']}\n"; + } + $this->debugMessage($msg); + } + + // if CURL was used for the call, http headers have been processed, + // and dechunking + reinflating have been carried out + if (!$headersProcessed) { + // Decode chunked encoding sent by http 1.1 servers + if (isset($httpResponse['headers']['transfer-encoding']) && $httpResponse['headers']['transfer-encoding'] == 'chunked') { + if (!$data = Http::decodeChunked($data)) { + error_log('XML-RPC: ' . __METHOD__ . ': errors occurred when trying to rebuild the chunked data received from server'); + throw new \Exception(PhpXmlRpc::$xmlrpcstr['dechunk_fail'], PhpXmlRpc::$xmlrpcerr['dechunk_fail']); + } + } + + // Decode gzip-compressed stuff + // code shamelessly inspired from nusoap library by Dietrich Ayala + if (isset($httpResponse['headers']['content-encoding'])) { + $httpResponse['headers']['content-encoding'] = str_replace('x-', '', $httpResponse['headers']['content-encoding']); + if ($httpResponse['headers']['content-encoding'] == 'deflate' || $httpResponse['headers']['content-encoding'] == 'gzip') { + // if decoding works, use it. else assume data wasn't gzencoded + if (function_exists('gzinflate')) { + if ($httpResponse['headers']['content-encoding'] == 'deflate' && $degzdata = @gzuncompress($data)) { + $data = $degzdata; + if ($debug) { + $this->debugMessage("---INFLATED RESPONSE---[" . strlen($data) . " chars]---\n$data\n---END---"); + } + } elseif ($httpResponse['headers']['content-encoding'] == 'gzip' && $degzdata = @gzinflate(substr($data, 10))) { + $data = $degzdata; + if ($debug) { + $this->debugMessage("---INFLATED RESPONSE---[" . strlen($data) . " chars]---\n$data\n---END---"); + } + } else { + error_log('XML-RPC: ' . __METHOD__ . ': errors occurred when trying to decode the deflated data received from server'); + throw new \Exception(PhpXmlRpc::$xmlrpcstr['decompress_fail'], PhpXmlRpc::$xmlrpcerr['decompress_fail']); + } + } else { + error_log('XML-RPC: ' . __METHOD__ . ': the server sent deflated data. Your php install must have the Zlib extension compiled in to support this.'); + throw new \Exception(PhpXmlRpc::$xmlrpcstr['cannot_decompress'], PhpXmlRpc::$xmlrpcerr['cannot_decompress']); + } + } + } + } // end of 'if needed, de-chunk, re-inflate response' + + return $httpResponse; + } + + /** + * Echoes a debug message, taking care of escaping it when not in console mode + * + * @param string $message + */ + protected function debugMessage($message) + { + if (PHP_SAPI != 'cli') { + print "
\n".htmlentities($message)."\n
"; + } + else { + print "\n$message\n"; + } + } } diff --git a/src/Request.php b/src/Request.php index 77567ab..17aae84 100644 --- a/src/Request.php +++ b/src/Request.php @@ -153,201 +153,9 @@ class Request while ($data = fread($fp, 32768)) { $ipd .= $data; } - //fclose($fp); return $this->parseResponse($ipd); } - /** - * Parses HTTP headers and separates them from data. - * - * @return null|Response null on success, or a Response on error - */ - private function parseResponseHeaders(&$data, $headers_processed = false) - { - $this->httpResponse['headers'] = array(); - $this->httpResponse['cookies'] = array(); - - // Support "web-proxy-tunelling" connections for https through proxies - if (preg_match('/^HTTP\/1\.[0-1] 200 Connection established/', $data)) { - // Look for CR/LF or simple LF as line separator, - // (even though it is not valid http) - $pos = strpos($data, "\r\n\r\n"); - if ($pos || is_int($pos)) { - $bd = $pos + 4; - } else { - $pos = strpos($data, "\n\n"); - if ($pos || is_int($pos)) { - $bd = $pos + 2; - } else { - // No separation between response headers and body: fault? - $bd = 0; - } - } - if ($bd) { - // this filters out all http headers from proxy. - // maybe we could take them into account, too? - $data = substr($data, $bd); - } else { - error_log('XML-RPC: ' . __METHOD__ . ': HTTPS via proxy error, tunnel connection possibly failed'); - $r = new Response(0, PhpXmlRpc::$xmlrpcerr['http_error'], PhpXmlRpc::$xmlrpcstr['http_error'] . ' (HTTPS via proxy error, tunnel connection possibly failed)'); - - return $r; - } - } - - // Strip HTTP 1.1 100 Continue header if present - while (preg_match('/^HTTP\/1\.1 1[0-9]{2} /', $data)) { - $pos = strpos($data, 'HTTP', 12); - // server sent a Continue header without any (valid) content following... - // give the client a chance to know it - if (!$pos && !is_int($pos)) { - // works fine in php 3, 4 and 5 - - break; - } - $data = substr($data, $pos); - } - if (!preg_match('/^HTTP\/[0-9.]+ 200 /', $data)) { - $errstr = substr($data, 0, strpos($data, "\n") - 1); - error_log('XML-RPC: ' . __METHOD__ . ': HTTP error, got response: ' . $errstr); - $r = new Response(0, PhpXmlRpc::$xmlrpcerr['http_error'], PhpXmlRpc::$xmlrpcstr['http_error'] . ' (' . $errstr . ')'); - - return $r; - } - - // be tolerant to usage of \n instead of \r\n to separate headers and data - // (even though it is not valid http) - $pos = strpos($data, "\r\n\r\n"); - if ($pos || is_int($pos)) { - $bd = $pos + 4; - } else { - $pos = strpos($data, "\n\n"); - if ($pos || is_int($pos)) { - $bd = $pos + 2; - } else { - // No separation between response headers and body: fault? - // we could take some action here instead of going on... - $bd = 0; - } - } - // be tolerant to line endings, and extra empty lines - $ar = preg_split("/\r?\n/", trim(substr($data, 0, $pos))); - while (list(, $line) = @each($ar)) { - // take care of multi-line headers and cookies - $arr = explode(':', $line, 2); - if (count($arr) > 1) { - $header_name = strtolower(trim($arr[0])); - /// @todo some other headers (the ones that allow a CSV list of values) - /// do allow many values to be passed using multiple header lines. - /// We should add content to $xmlrpc->_xh['headers'][$header_name] - /// instead of replacing it for those... - if ($header_name == 'set-cookie' || $header_name == 'set-cookie2') { - if ($header_name == 'set-cookie2') { - // version 2 cookies: - // there could be many cookies on one line, comma separated - $cookies = explode(',', $arr[1]); - } else { - $cookies = array($arr[1]); - } - foreach ($cookies as $cookie) { - // glue together all received cookies, using a comma to separate them - // (same as php does with getallheaders()) - if (isset($this->httpResponse['headers'][$header_name])) { - $this->httpResponse['headers'][$header_name] .= ', ' . trim($cookie); - } else { - $this->httpResponse['headers'][$header_name] = trim($cookie); - } - // parse cookie attributes, in case user wants to correctly honour them - // feature creep: only allow rfc-compliant cookie attributes? - // @todo support for server sending multiple time cookie with same name, but using different PATHs - $cookie = explode(';', $cookie); - foreach ($cookie as $pos => $val) { - $val = explode('=', $val, 2); - $tag = trim($val[0]); - $val = trim(@$val[1]); - /// @todo with version 1 cookies, we should strip leading and trailing " chars - if ($pos == 0) { - $cookiename = $tag; - $this->httpResponse['cookies'][$tag] = array(); - $this->httpResponse['cookies'][$cookiename]['value'] = urldecode($val); - } else { - if ($tag != 'value') { - $this->httpResponse['cookies'][$cookiename][$tag] = $val; - } - } - } - } - } else { - $this->httpResponse['headers'][$header_name] = trim($arr[1]); - } - } elseif (isset($header_name)) { - /// @todo version1 cookies might span multiple lines, thus breaking the parsing above - $this->httpResponse['headers'][$header_name] .= ' ' . trim($line); - } - } - - $data = substr($data, $bd); - - if ($this->debug && count($this->httpResponse['headers'])) { - $msg = ''; - foreach ($this->httpResponse['headers'] as $header => $value) { - $msg .= "HEADER: $header: $value\n"; - } - foreach ($this->httpResponse['cookies'] as $header => $value) { - $msg .= "COOKIE: $header={$value['value']}\n"; - } - $this->debugMessage($msg); - } - - // if CURL was used for the call, http headers have been processed, - // and dechunking + reinflating have been carried out - if (!$headers_processed) { - // Decode chunked encoding sent by http 1.1 servers - if (isset($this->httpResponse['headers']['transfer-encoding']) && $this->httpResponse['headers']['transfer-encoding'] == 'chunked') { - if (!$data = Http::decode_chunked($data)) { - error_log('XML-RPC: ' . __METHOD__ . ': errors occurred when trying to rebuild the chunked data received from server'); - $r = new Response(0, PhpXmlRpc::$xmlrpcerr['dechunk_fail'], PhpXmlRpc::$xmlrpcstr['dechunk_fail']); - - return $r; - } - } - - // Decode gzip-compressed stuff - // code shamelessly inspired from nusoap library by Dietrich Ayala - if (isset($this->httpResponse['headers']['content-encoding'])) { - $this->httpResponse['headers']['content-encoding'] = str_replace('x-', '', $this->httpResponse['headers']['content-encoding']); - if ($this->httpResponse['headers']['content-encoding'] == 'deflate' || $this->httpResponse['headers']['content-encoding'] == 'gzip') { - // if decoding works, use it. else assume data wasn't gzencoded - if (function_exists('gzinflate')) { - if ($this->httpResponse['headers']['content-encoding'] == 'deflate' && $degzdata = @gzuncompress($data)) { - $data = $degzdata; - if ($this->debug) { - $this->debugMessage("---INFLATED RESPONSE---[" . strlen($data) . " chars]---\n$data\n---END---"); - } - } elseif ($this->httpResponse['headers']['content-encoding'] == 'gzip' && $degzdata = @gzinflate(substr($data, 10))) { - $data = $degzdata; - if ($this->debug) { - $this->debugMessage("---INFLATED RESPONSE---[" . strlen($data) . " chars]---\n$data\n---END---"); - } - } else { - error_log('XML-RPC: ' . __METHOD__ . ': errors occurred when trying to decode the deflated data received from server'); - $r = new Response(0, PhpXmlRpc::$xmlrpcerr['decompress_fail'], PhpXmlRpc::$xmlrpcstr['decompress_fail']); - - return $r; - } - } else { - error_log('XML-RPC: ' . __METHOD__ . ': the server sent deflated data. Your php install must have the Zlib extension compiled in to support this.'); - $r = new Response(0, PhpXmlRpc::$xmlrpcerr['cannot_decompress'], PhpXmlRpc::$xmlrpcstr['cannot_decompress']); - - return $r; - } - } - } - } // end of 'if needed, de-chunk, re-inflate response' - - return; - } - /** * Parse the xmlrpc response contained in the string $data and return a Response object. * @@ -364,22 +172,20 @@ class Request $this->debugMessage("---GOT---\n$data\n---END---"); } - $this->httpResponse = array(); - $this->httpResponse['raw_data'] = $data; - $this->httpResponse['headers'] = array(); - $this->httpResponse['cookies'] = array(); + $this->httpResponse = array('raw_data' => $data, 'headers' => array(), 'cookies' => array()); if ($data == '') { error_log('XML-RPC: ' . __METHOD__ . ': no response received from server.'); - $r = new Response(0, PhpXmlRpc::$xmlrpcerr['no_data'], PhpXmlRpc::$xmlrpcstr['no_data']); - - return $r; + return new Response(0, PhpXmlRpc::$xmlrpcerr['no_data'], PhpXmlRpc::$xmlrpcstr['no_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) { + $httpParser = new Http(); + try { + $this->httpResponse = $httpParser->parseResponseHeaders($data, $headers_processed, $this->debug); + } catch(\Exception $e) { + $r = new Response(0, $e->getCode(), $e->getMessage()); // failed processing of HTTP response headers // save into response obj the full payload received, for debugging $r->raw_data = $data; diff --git a/src/Response.php b/src/Response.php index efadfb5..54e8db4 100644 --- a/src/Response.php +++ b/src/Response.php @@ -8,7 +8,7 @@ class Response { /// @todo: do these need to be public? public $val = 0; - public $valtyp; + public $valType; public $errno = 0; public $errstr = ''; public $payload; @@ -19,25 +19,25 @@ class Response /** * @param mixed $val either an xmlrpcval obj, a php value or the xml serialization of an xmlrpcval (a string) - * @param integer $fcode set it to anything but 0 to create an error response - * @param string $fstr the error string, in case of an error response - * @param string $valtyp either 'xmlrpcvals', 'phpvals' or 'xml' + * @param integer $fCode set it to anything but 0 to create an error response + * @param string $fString the error string, in case of an error response + * @param string $valType either 'xmlrpcvals', 'phpvals' or 'xml' * - * @todo add check that $val / $fcode / $fstr is of correct type??? + * @todo add check that $val / $fCode / $fString is of correct type??? * NB: as of now we do not do it, since it might be either an xmlrpcval or a plain * php val, or a complete xml chunk, depending on usage of Client::send() inside which creator is called... */ - public function __construct($val, $fcode = 0, $fstr = '', $valtyp = '') + public function __construct($val, $fCode = 0, $fString = '', $valType = '') { - if ($fcode != 0) { + if ($fCode != 0) { // error response - $this->errno = $fcode; - $this->errstr = $fstr; - //$this->errstr = htmlspecialchars($fstr); // XXX: encoding probably shouldn't be done here; fix later. + $this->errno = $fCode; + $this->errstr = $fString; + //$this->errstr = htmlspecialchars($fString); // XXX: encoding probably shouldn't be done here; fix later. } else { // successful response $this->val = $val; - if ($valtyp == '') { + if ($valType == '') { // user did not declare type of response value: try to guess it if (is_object($this->val) && is_a($this->val, 'PhpXmlRpc\Value')) { $this->valtyp = 'xmlrpcvals'; @@ -48,7 +48,7 @@ class Response } } else { // user declares type of resp value: believe him - $this->valtyp = $valtyp; + $this->valtyp = $valType; } } } @@ -102,14 +102,14 @@ class Response /** * Returns xml representation of the response. XML prologue not included. * - * @param string $charset_encoding the charset to be used for serialization. if null, US-ASCII is assumed + * @param string $charsetEncoding the charset to be used for serialization. if null, US-ASCII is assumed * * @return string the xml representation of the response */ - public function serialize($charset_encoding = '') + public function serialize($charsetEncoding = '') { - if ($charset_encoding != '') { - $this->content_type = 'text/xml; charset=' . $charset_encoding; + if ($charsetEncoding != '') { + $this->content_type = 'text/xml; charset=' . $charsetEncoding; } else { $this->content_type = 'text/xml'; } @@ -121,11 +121,10 @@ class Response if ($this->errno) { // G. Giunta 2005/2/13: let non-ASCII response messages be tolerated by clients // by xml-encoding non ascii chars - $charsetEncoder = $result .= "\n" . "\nfaultCode\n" . $this->errno . "\n\n\nfaultString\n" . - Charset::instance()->encode_entities($this->errstr, PhpXmlRpc::$xmlrpc_internalencoding, $charset_encoding) . "\n\n" . + Charset::instance()->encodeEntities($this->errstr, PhpXmlRpc::$xmlrpc_internalencoding, $charsetEncoding) . "\n\n" . "\n\n"; } else { if (!is_object($this->val) || !is_a($this->val, 'PhpXmlRpc\Value')) { @@ -139,7 +138,7 @@ class Response } } else { $result .= "\n\n" . - $this->val->serialize($charset_encoding) . + $this->val->serialize($charsetEncoding) . "\n"; } } diff --git a/src/Server.php b/src/Server.php index 7d345aa..3a8f558 100644 --- a/src/Server.php +++ b/src/Server.php @@ -160,7 +160,7 @@ class Server $out .= "\n"; } if (static::$_xmlrpc_debuginfo != '') { - $out .= "\n"; + $out .= "\n"; // NB: a better solution MIGHT be to use CDATA, but we need to insert it // into return payload AFTER the beginning tag //$out .= "', ']_]_>', static::$_xmlrpc_debuginfo) . "\n]]>\n"; diff --git a/src/Value.php b/src/Value.php index 0f39a67..b9d34fe 100644 --- a/src/Value.php +++ b/src/Value.php @@ -42,8 +42,8 @@ class Value */ public function __construct($val = -1, $type = '') { - /// @todo: optimization creep - do not call addXX, do it all inline. - /// downside: booleans will not be coerced anymore + // optimization creep - do not call addXX, do it all inline. + // downside: booleans will not be coerced anymore if ($val !== -1 || $type != '') { // optimization creep: inlined all work done by constructor switch ($type) { @@ -73,7 +73,8 @@ class Value default: error_log("XML-RPC: " . __METHOD__ . ": not a known type ($type)"); } - /*if($type=='') + /* was: + if($type=='') { $type='string'; } @@ -107,7 +108,7 @@ class Value $typeof = static::$xmlrpcTypes[$type]; } - if ($typeof != 1) { + if ($typeof !== 1) { error_log("XML-RPC: " . __METHOD__ . ": not a scalar type ($type)"); return 0; @@ -135,10 +136,6 @@ class Value return 0; case 2: // we're adding a scalar value to an array here - //$ar=$this->me['array']; - //$ar[]=new Value($val, $type); - //$this->me['array']=$ar; - // Faster (?) avoid all the costly array-copy-by-val done here... $this->me['array'][] = new Value($val, $type); return 1; @@ -249,7 +246,7 @@ class Value case static::$xmlrpcString: // G. Giunta 2005/2/13: do NOT use htmlentities, since // it will produce named html entities, which are invalid xml - $rs .= "<${typ}>" . Charset::instance()->encode_entities($val, PhpXmlRpc::$xmlrpc_internalencoding, $charset_encoding) . ""; + $rs .= "<${typ}>" . Charset::instance()->encodeEntities($val, PhpXmlRpc::$xmlrpc_internalencoding, $charset_encoding) . ""; break; case static::$xmlrpcInt: case static::$xmlrpcI4: @@ -297,7 +294,7 @@ class Value } $charsetEncoder = Charset::instance(); foreach ($val as $key2 => $val2) { - $rs .= '' . $charsetEncoder->encode_entities($key2, PhpXmlRpc::$xmlrpc_internalencoding, $charset_encoding) . "\n"; + $rs .= '' . $charsetEncoder->encodeEntities($key2, PhpXmlRpc::$xmlrpc_internalencoding, $charset_encoding) . "\n"; //$rs.=$this->serializeval($val2); $rs .= $val2->serialize($charset_encoding); $rs .= "\n"; -- 2.43.0