namespace PhpXmlRpc;
+use PhpXmlRpc\Helper\Logger;
+
class Client
{
/// @todo: do these need to be public?
// by default the xml parser can support these 3 charset encodings
$this->accepted_charset_encodings = array('UTF-8', 'ISO-8859-1', 'US-ASCII');
+ // Add all charsets which mbstring can handle, but remove junk not found in IANA registry at
+ // in http://www.iana.org/assignments/character-sets/character-sets.xhtml
+ // NB: this is disabled to avoid making all the requests sent huge... mbstring supports more than 80 charsets!
+ /*if (function_exists('mb_list_encodings')) {
+
+ $encodings = array_diff(mb_list_encodings(), array('pass', 'auto', 'wchar', 'BASE64', 'UUENCODE', 'ASCII',
+ 'HTML-ENTITIES', 'Quoted-Printable', '7bit','8bit', 'byte2be', 'byte2le', 'byte4be', 'byte4le'));
+ $this->accepted_charset_encodings = array_unique(array_merge($this->accepted_charset_encodings, $encodings));
+ }*/
+
// initialize user_agent string
$this->user_agent = PhpXmlRpc::$xmlrpcName . ' ' . PhpXmlRpc::$xmlrpcVersion;
}
* @param integer $timeout Connection timeout, in seconds, If unspecified, a platform specific timeout will apply
* @param string $method if left unspecified, the http protocol chosen during creation of the object will be used
*
- * @return Response
+ * @return Response|Response[]
*/
public function send($req, $timeout = 0, $method = '')
{
}
if (is_array($req)) {
- // $msg is an array of Requests
+ // $req is an array of Requests
$r = $this->multicall($req, $timeout, $method);
return $r;
}
// where req is a Request
- $req->debug = $this->debug;
+ $req->setDebug($this->debug);
if ($method == 'https') {
$r = $this->sendPayloadHTTPS(
$this->proxyport,
$this->proxy_user,
$this->proxy_pass,
- $this->proxy_authtype
+ $this->proxy_authtype,
+ $method
);
}
* @param string $proxyUsername
* @param string $proxyPassword
* @param int $proxyAuthType
+ * @param string $method
* @return Response
*/
protected function sendPayloadHTTP10($req, $server, $port, $timeout = 0,
$username = '', $password = '', $authType = 1, $proxyHost = '',
- $proxyPort = 0, $proxyUsername = '', $proxyPassword = '', $proxyAuthType = 1)
+ $proxyPort = 0, $proxyUsername = '', $proxyPassword = '', $proxyAuthType = 1,
+ $method='http')
{
if ($port == 0) {
- $port = 80;
+ $port = ( $method === "https" ) ? 443 : 80;
}
// Only create the payload if it was not created previously
}
$connectServer = $proxyHost;
$connectPort = $proxyPort;
+ $transport = "tcp";
$uri = 'http://' . $server . ':' . $port . $this->path;
if ($proxyUsername != '') {
if ($proxyAuthType != 1) {
} else {
$connectServer = $server;
$connectPort = $port;
+ /// @todo if supporting https, we should support all its current options as well: peer name verification etc...
+ $transport = ( $method === "https" ) ? "tls" : "tcp";
$uri = $this->path;
}
$payload;
if ($this->debug > 1) {
- $this->debugMessage("---SENDING---\n$op\n---END---");
+ Logger::instance()->debugMessage("---SENDING---\n$op\n---END---");
}
if ($timeout > 0) {
- $fp = @fsockopen($connectServer, $connectPort, $this->errno, $this->errstr, $timeout);
+ $fp = @stream_socket_client("$transport://$connectServer:$connectPort", $this->errno, $this->errstr, $timeout);
} else {
- $fp = @fsockopen($connectServer, $connectPort, $this->errno, $this->errstr);
+ $fp = @stream_socket_client("$transport://$connectServer:$connectPort", $this->errno, $this->errstr);
}
if ($fp) {
- if ($timeout > 0 && function_exists('stream_set_timeout')) {
+ if ($timeout > 0) {
stream_set_timeout($fp, $timeout);
}
} else {
* Requires curl to be built into PHP
* NB: CURL versions before 7.11.10 cannot use proxy to talk to https servers!
*
- * @param Request $msg
+ * @param Request $req
* @param string $server
* @param int $port
* @param int $timeout
* @param int $sslVersion
* @return Response
*/
- protected function sendPayloadCURL($msg, $server, $port, $timeout = 0, $username = '',
+ protected function sendPayloadCURL($req, $server, $port, $timeout = 0, $username = '',
$password = '', $authType = 1, $cert = '', $certPass = '', $caCert = '', $caCertDir = '',
$proxyHost = '', $proxyPort = 0, $proxyUsername = '', $proxyPassword = '', $proxyAuthType = 1, $method = 'https',
$keepAlive = false, $key = '', $keyPass = '', $sslVersion = 0)
}
// Only create the payload if it was not created previously
- if (empty($msg->payload)) {
- $msg->createPayload($this->request_charset_encoding);
+ if (empty($req->payload)) {
+ $req->createPayload($this->request_charset_encoding);
}
// Deflate request body and set appropriate request headers
- $payload = $msg->payload;
+ $payload = $req->payload;
if (function_exists('gzdeflate') && ($this->request_compression == 'gzip' || $this->request_compression == 'deflate')) {
if ($this->request_compression == 'gzip') {
$a = @gzencode($payload);
}
if ($this->debug > 1) {
- $this->debugMessage("---SENDING---\n$payload\n---END---");
- // let the client see this now in case http times out...
- flush();
+ Logger::instance()->debugMessage("---SENDING---\n$payload\n---END---");
}
if (!$keepAlive || !$this->xmlrpc_curl_handle) {
}
// results into variable
- curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
- if ($this->debug) {
- curl_setopt($curl, CURLOPT_VERBOSE, 1);
+ if ($this->debug > 1) {
+ curl_setopt($curl, CURLOPT_VERBOSE, true);
+ /// @todo allow callers to redirect curlopt_stderr to some stream which can be buffered
}
curl_setopt($curl, CURLOPT_USERAGENT, $this->user_agent);
// required for XMLRPC: post the data
}
}
// extra headers
- $headers = array('Content-Type: ' . $msg->content_type, 'Accept-Charset: ' . implode(',', $this->accepted_charset_encodings));
+ $headers = array('Content-Type: ' . $req->content_type, 'Accept-Charset: ' . implode(',', $this->accepted_charset_encodings));
// if no keepalive is wanted, let the server know it in advance
if (!$keepAlive) {
$headers[] = 'Connection: close';
$message .= $name . ': ' . $val . "\n";
}
$message .= "---END---";
- $this->debugMessage($message);
+ Logger::instance()->debugMessage($message);
}
if (!$result) {
if (!$keepAlive) {
curl_close($curl);
}
- $resp = $msg->parseResponse($result, true, $this->return_type);
+ $resp = $req->parseResponse($result, true, $this->return_type);
// if we got back a 302, we can not reuse the curl handle for later calls
if ($resp->faultCode() == PhpXmlRpc::$xmlrpcerr['http_error'] && $keepAlive) {
curl_close($curl);
if ($this->return_type == 'xml') {
return $rets;
} elseif ($this->return_type == 'phpvals') {
- ///@todo test this code branch...
+ /// @todo test this code branch...
$rets = $result->value();
if (!is_array($rets)) {
return false; // bad return type from system.multicall
if ($rets->kindOf() != 'array') {
return false; // bad return type from system.multicall
}
- $numRets = $rets->arraysize();
+ $numRets = $rets->count();
if ($numRets != count($reqs)) {
return false; // wrong number of return values.
}
$response = array();
- for ($i = 0; $i < $numRets; $i++) {
- $val = $rets->arraymem($i);
+ foreach($rets as $val) {
switch ($val->kindOf()) {
case 'array':
- if ($val->arraysize() != 1) {
+ if ($val->count() != 1) {
return false; // Bad value
}
// Normal return value
- $response[$i] = new Response($val->arraymem(0));
+ $response[] = new Response($val[0]);
break;
case 'struct':
- $code = $val->structmem('faultCode');
+ $code = $val['faultCode'];
if ($code->kindOf() != 'scalar' || $code->scalartyp() != 'int') {
return false;
}
- $str = $val->structmem('faultString');
+ $str = $val['faultString'];
if ($str->kindOf() != 'scalar' || $str->scalartyp() != 'string') {
return false;
}
- $response[$i] = new Response(0, $code->scalarval(), $str->scalarval());
+ $response[] = new Response(0, $code->scalarval(), $str->scalarval());
break;
default:
return false;
return $response;
}
}
-
- /**
- * 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 "<PRE>\n".htmlentities($message)."\n</PRE>";
- } else {
- print "\n$message\n";
- }
- // let the client see this now in case http times out...
- flush();
- }
}