Implement interface ArrayAccess in the Value class
[plcapi.git] / src / Client.php
index 00195af..e46e1d5 100644 (file)
@@ -2,6 +2,8 @@
 
 namespace PhpXmlRpc;
 
+use PhpXmlRpc\Helper\Logger;
+
 class Client
 {
     /// @todo: do these need to be public?
@@ -339,7 +341,7 @@ class Client
      * @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 = '')
     {
@@ -350,7 +352,7 @@ class Client
         }
 
         if (is_array($req)) {
-            // $msg is an array of Requests
+            // $req is an array of Requests
             $r = $this->multicall($req, $timeout, $method);
 
             return $r;
@@ -361,7 +363,7 @@ class Client
         }
 
         // where req is a Request
-        $req->debug = $this->debug;
+        $req->setDebug($this->debug);
 
         if ($method == 'https') {
             $r = $this->sendPayloadHTTPS(
@@ -420,7 +422,8 @@ class Client
                 $this->proxyport,
                 $this->proxy_user,
                 $this->proxy_pass,
-                $this->proxy_authtype
+                $this->proxy_authtype,
+                $method
             );
         }
 
@@ -440,14 +443,16 @@ class Client
      * @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
@@ -496,6 +501,7 @@ class Client
             }
             $connectServer = $proxyHost;
             $connectPort = $proxyPort;
+            $transport = "tcp";
             $uri = 'http://' . $server . ':' . $port . $this->path;
             if ($proxyUsername != '') {
                 if ($proxyAuthType != 1) {
@@ -506,6 +512,8 @@ class Client
         } 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;
         }
 
@@ -551,16 +559,16 @@ class Client
             $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 {
@@ -632,7 +640,7 @@ class Client
      * 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
@@ -655,7 +663,7 @@ class Client
      * @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)
@@ -682,12 +690,12 @@ class Client
         }
 
         // 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);
@@ -707,9 +715,7 @@ class Client
         }
 
         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) {
@@ -722,10 +728,11 @@ class Client
         }
 
         // 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
@@ -749,7 +756,7 @@ class Client
             }
         }
         // 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';
@@ -848,7 +855,7 @@ class Client
                 $message .= $name . ': ' . $val . "\n";
             }
             $message .= "---END---";
-            $this->debugMessage($message);
+            Logger::instance()->debugMessage($message);
         }
 
         if (!$result) {
@@ -864,7 +871,7 @@ class Client
             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);
@@ -987,7 +994,7 @@ class Client
         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
@@ -1036,32 +1043,36 @@ class Client
             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);
+            //for ($i = 0; $i < $numRets; $i++) {
+            foreach($rets as $val) {
+                //$val = $rets->arraymem($i);
                 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->arraymem(0));
+                        $response[] = new Response($val[0]);
                         break;
                     case 'struct':
-                        $code = $val->structmem('faultCode');
+                        //$code = $val->structmem('faultCode');
+                        $code = $val['faultCode'];
                         if ($code->kindOf() != 'scalar' || $code->scalartyp() != 'int') {
                             return false;
                         }
-                        $str = $val->structmem('faultString');
+                        //$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;
@@ -1071,21 +1082,4 @@ class Client
             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();
-    }
 }