make Client more strict in case of unsupported options and more verbose in case of...
authorgggeek <giunta.gaetano@gmail.com>
Wed, 8 Feb 2023 12:57:58 +0000 (12:57 +0000)
committergggeek <giunta.gaetano@gmail.com>
Wed, 8 Feb 2023 12:57:58 +0000 (12:57 +0000)
NEWS.md
debugger/action.php
doc/manual/phpxmlrpc_manual.adoc
src/Client.php
src/PhpXmlRpc.php

diff --git a/NEWS.md b/NEWS.md
index e0ba37d..6a8f707 100644 (file)
--- a/NEWS.md
+++ b/NEWS.md
@@ -62,6 +62,9 @@
 
 * fixed: made sure all debug output goes through the logger at response parsing time (there was one printf call left)
 
+* fixed: `Client::send` will now return an error Response when it is requested to use an auth method that it does not
+  support, instead of logging an error message and continuing with another auth schema. The returned error code is 20
+
 * fixed: when calling `Client::multicall()` with `$client->return_type = 'xml'`, the code would be always falling back to
   non-multicall requests
 
@@ -94,6 +97,8 @@
 
 * new: method `PhpXmlRpc::setLogger()`, to simplify injecting a custom logger into all classes of the library in one step
 
+* improved: the Client is more verbose in logging issues when trying to compress a Request for sending
+
 * improved: the `Logger` class now sports methods adhering to Psr\Log\LoggerInterface
 
 * improved: limit the size of incoming data which will be used in error responses and logged error messages, making
index 7b6534e..cc87075 100644 (file)
@@ -570,7 +570,7 @@ if ($action) {
     </ol>
     <?php
     if (!extension_loaded('curl')) {
-        echo "<p class=\"evidence\">You will need to enable the CURL extension to use the HTTPS, HTTP 1.1 and HTTP/2 transports</p>\n";
+        echo "<p class=\"evidence\">You will need to enable the cURL extension to use the HTTPS, HTTP 1.1 and HTTP/2 transports</p>\n";
     }
     ?>
 
index 76c8c78..bd99da5 100644 (file)
@@ -945,7 +945,7 @@ Standard errors returned by the library include:
     response to a request, but no response body follows the HTTP headers.
 
 `7` No SSL support compiled in:: This error is generated by the client when trying to send a request with HTTPS and the
-    CURL extension is not available to PHP.
+    cURL extension is not available to PHP.
 
 `8` CURL error:: This error is generated by the client when trying to send a request with HTTPS and the HTTPS
     communication fails.
index 1113e92..f45c6a2 100644 (file)
@@ -905,20 +905,28 @@ class Client
 
         // Deflate request body and set appropriate request headers
         $encodingHdr = '';
-        if (function_exists('gzdeflate') && ($opts['request_compression'] == 'gzip' || $opts['request_compression'] == 'deflate')) {
-            if ($opts['request_compression'] == 'gzip') {
+        if ($opts['request_compression'] == 'gzip' || $opts['request_compression'] == 'deflate') {
+            if ($opts['request_compression'] == 'gzip' && function_exists('gzencode')) {
                 $a = @gzencode($payload);
                 if ($a) {
                     $payload = $a;
                     $encodingHdr = "Content-Encoding: gzip\r\n";
+                } else {
+                    $this->getLogger()->warning('XML-RPC: ' . __METHOD__ . ': gzencode failure in compressing request');
                 }
-            } else {
+            } else if (function_exists('gzcompress')) {
                 $a = @gzcompress($payload);
                 if ($a) {
                     $payload = $a;
                     $encodingHdr = "Content-Encoding: deflate\r\n";
+                } else {
+                    $this->getLogger()->warning('XML-RPC: ' . __METHOD__ . ': gzcompress failure in compressing request');
                 }
+            } else {
+                $this->getLogger()->warning('XML-RPC: ' . __METHOD__ . ': desired request compression method is unsupported by this PHP install');
             }
+        } else {
+            $this->getLogger()->warning('XML-RPC: ' . __METHOD__ . ': desired request compression method is unsupported');
         }
 
         // thanks to Grant Rauscher
@@ -926,8 +934,9 @@ class Client
         if ($opts['username'] != '') {
             $credentials = 'Authorization: Basic ' . base64_encode($opts['username'] . ':' . $opts['password']) . "\r\n";
             if ($opts['authtype'] != 1) {
-                /// @todo make this a proper error, i.e. return a failure
                 $this->getLogger()->error('XML-RPC: ' . __METHOD__ . ': warning. Only Basic auth is supported with HTTP 1.0');
+                return new static::$responseClass(0, PhpXmlRpc::$xmlrpcerr['unsupported_option'],
+                    PhpXmlRpc::$xmlrpcerr['unsupported_option'] . ': only Basic auth is supported with HTTP 1.0');
             }
         }
 
@@ -952,8 +961,9 @@ class Client
             $uri = 'http://' . $server . ':' . $port . $path;
             if ($opts['proxy_user'] != '') {
                 if ($opts['proxy_authtype'] != 1) {
-                    /// @todo make this a proper error, i.e. return a failure
                     $this->getLogger()->error('XML-RPC: ' . __METHOD__ . ': warning. Only Basic auth to proxy is supported with HTTP 1.0');
+                    return new static::$responseClass(0, PhpXmlRpc::$xmlrpcerr['unsupported_option'],
+                        PhpXmlRpc::$xmlrpcerr['unsupported_option'] . ': only Basic auth to proxy is supported with HTTP 1.0');
                 }
                 $proxyCredentials = 'Proxy-Authorization: Basic ' . base64_encode($opts['proxy_user'] . ':' .
                     $opts['proxy_pass']) . "\r\n";
@@ -1166,6 +1176,8 @@ class Client
      * @param string $path
      * @param array $opts the keys/values match self::getOptions
      * @return \CurlHandle|resource|false
+     *
+     * @todo allow this method to either throw or return a Response, so that we can pass back to caller more info on errors
      */
     protected function createCURLHandle($req, $method, $server, $port, $path, $opts)
     {
@@ -1185,21 +1197,28 @@ class Client
 
         // Deflate request body and set appropriate request headers
         $encodingHdr = '';
-        /// @todo test for existence of proper function, in case of polyfills
-        if (function_exists('gzdeflate') && ($opts['request_compression'] == 'gzip' || $opts['request_compression'] == 'deflate')) {
-            if ($opts['request_compression'] == 'gzip') {
+        if (($opts['request_compression'] == 'gzip' || $opts['request_compression'] == 'deflate')) {
+            if ($opts['request_compression'] == 'gzip' && function_exists('gzencode')) {
                 $a = @gzencode($payload);
                 if ($a) {
                     $payload = $a;
                     $encodingHdr = 'Content-Encoding: gzip';
+                } else {
+                    $this->getLogger()->warning('XML-RPC: ' . __METHOD__ . ': gzencode failure in compressing request');
                 }
-            } else {
+            } else if (function_exists('gzcompress')) {
                 $a = @gzcompress($payload);
                 if ($a) {
                     $payload = $a;
                     $encodingHdr = 'Content-Encoding: deflate';
+                } else {
+                    $this->getLogger()->warning('XML-RPC: ' . __METHOD__ . ': gzcompress failure in compressing request');
                 }
+            } else {
+                $this->getLogger()->warning('XML-RPC: ' . __METHOD__ . ': desired request compression method is unsupported by this PHP install');
             }
+        } else {
+            $this->getLogger()->warning('XML-RPC: ' . __METHOD__ . ': desired request compression method is unsupported');
         }
 
         if (!$opts['keepalive'] || !$this->xmlrpc_curl_handle) {
@@ -1287,8 +1306,9 @@ class Client
                 if (defined('CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE')) {
                     curl_setopt($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
                 } else {
-                    /// @todo make this a proper error, i.e. return a failure
                     $this->getLogger()->error('XML-RPC: ' . __METHOD__ . ': warning. HTTP2 is not supported by the current PHP/curl install');
+                    curl_close($curl);
+                    return false;
                 }
                 break;
             case 'h2':
@@ -1301,8 +1321,9 @@ class Client
             if (defined('CURLOPT_HTTPAUTH')) {
                 curl_setopt($curl, CURLOPT_HTTPAUTH, $opts['authtype']);
             } elseif ($opts['authtype'] != 1) {
-                /// @todo make this a proper error, i.e. return a failure
                 $this->getLogger()->error('XML-RPC: ' . __METHOD__ . ': warning. Only Basic auth is supported by the current PHP/curl install');
+                curl_close($curl);
+                return false;
             }
         }
 
@@ -1351,8 +1372,9 @@ class Client
                 if (defined('CURLOPT_PROXYAUTH')) {
                     curl_setopt($curl, CURLOPT_PROXYAUTH, $opts['proxy_authtype']);
                 } elseif ($opts['proxy_authtype'] != 1) {
-                    /// @todo make this a proper error, i.e. return a failure
                     $this->getLogger()->error('XML-RPC: ' . __METHOD__ . ': warning. Only Basic auth to proxy is supported by the current PHP/curl install');
+                    curl_close($curl);
+                    return false;
                 }
             }
         }
index fea0b12..4e8cd47 100644 (file)
@@ -36,6 +36,7 @@ class PhpXmlRpc
         'multicall_noparams' => 13, // client
         'multicall_notarray' => 14, // client
         'no_http2' => 19, // client
+        'unsupported_option' => 20, // client
         // the following 3 are meant to give greater insight than 'invalid_return'. They use the same code for BC,
         // but you can override their value in your own code
         'invalid_xml' => 2, // client
@@ -74,6 +75,7 @@ class PhpXmlRpc
         'multicall_noparams' => 'Missing params',
         'multicall_notarray' => 'params is not an array',
         'no_http2' => 'No HTTP/2 support compiled in',
+        'unsupported_option' => 'Some client option is not supported with the transport method currently in use',
         // the following 3 are meant to give greater insight than 'invalid_return'. They use the same string for BC,
         // but you can override their value in your own code
         'invalid_xml' => 'Invalid response payload (you can use the setDebug method to allow analysis of the response)',