Display bit flags in use when calling Curl::diagnose()

This change attempts to determine which underlying constants were
bitmasked together to reach the resulting value passed to curl_setopt()
using Curl::setOpt().
This commit is contained in:
Zach Borboa
2023-05-18 05:43:42 -07:00
parent 0ea79808d6
commit a304084a61
2 changed files with 184 additions and 1 deletions
+46 -1
View File
@@ -1293,7 +1293,51 @@ class Curl extends BaseCurl
if (is_string($value)) {
echo ' ' . $value . "\n";
} elseif (is_int($value)) {
echo ' ' . $value . "\n";
echo ' ' . $value;
$bit_flag_lookups = [
'CURLOPT_HTTPAUTH' => 'CURLAUTH_',
'CURLOPT_PROTOCOLS' => 'CURLPROTO_',
'CURLOPT_PROXYAUTH' => 'CURLAUTH_',
'CURLOPT_PROXY_SSL_OPTIONS' => 'CURLSSLOPT_',
'CURLOPT_REDIR_PROTOCOLS' => 'CURLPROTO_',
'CURLOPT_SSH_AUTH_TYPES' => 'CURLSSH_AUTH_',
'CURLOPT_SSL_OPTIONS' => 'CURLSSLOPT_',
];
if (isset($this->curlOptionCodeConstants[$option])) {
$option_name = $this->curlOptionCodeConstants[$option];
if (in_array($option_name, array_keys($bit_flag_lookups))) {
$curl_const_prefix = $bit_flag_lookups[$option_name];
$constants = get_defined_constants(true);
$curl_constants = array_filter(
$constants['curl'],
function ($key) use ($curl_const_prefix) {
return strpos($key, $curl_const_prefix) !== false;
},
ARRAY_FILTER_USE_KEY
);
$bit_flags = [];
foreach ($curl_constants as $const_name => $const_value) {
// Skip attempting to detect bit flags in use that use constants with negative
// values (e.g. CURLAUTH_ANY, CURLAUTH_ANYSAFE, CURLPROTO_ALL, CURLSSH_AUTH_ANY,
// CURLSSH_AUTH_DEFAULT, etc.)
if ($value < 0) {
$bit_flags = [];
break;
} elseif ($const_value >= 0 && ($value & $const_value)) {
$bit_flags[] = $const_name;
}
}
if (count($bit_flags)) {
asort($bit_flags);
echo ' (' . implode(' | ', $bit_flags) . ')';
}
}
}
echo "\n";
} elseif (is_bool($value)) {
echo ' ' . ($value ? 'true' : 'false') . "\n";
} elseif (is_callable($value)) {
@@ -1302,6 +1346,7 @@ class Curl extends BaseCurl
echo ' ' . gettype($value) . ':' . "\n";
var_dump($value);
}
$i += 1;
}
}
+138
View File
@@ -4154,6 +4154,8 @@ class PHPCurlClassTest extends \PHPUnit\Framework\TestCase
'--- Begin PHP Curl Class diagnostic output ---',
'PHP Curl Class version: ' . Curl::VERSION,
'PHP version: ' . PHP_VERSION,
'CURLOPT_PROTOCOLS: 3 (CURLPROTO_HTTP | CURLPROTO_HTTPS)',
'CURLOPT_REDIR_PROTOCOLS: 3 (CURLPROTO_HTTP | CURLPROTO_HTTPS)',
'CURLOPT_HTTPGET: true',
'Sent an HTTP GET request ',
'Request contained no body.',
@@ -4178,6 +4180,8 @@ class PHPCurlClassTest extends \PHPUnit\Framework\TestCase
'--- Begin PHP Curl Class diagnostic output ---',
'PHP Curl Class version: ' . Curl::VERSION,
'PHP version: ' . PHP_VERSION,
'CURLOPT_PROTOCOLS: 3 (CURLPROTO_HTTP | CURLPROTO_HTTPS)',
'CURLOPT_REDIR_PROTOCOLS: 3 (CURLPROTO_HTTP | CURLPROTO_HTTPS)',
'CURLOPT_POST: true',
'Sent an HTTP POST request ',
'Request contained no body.',
@@ -4247,6 +4251,140 @@ class PHPCurlClassTest extends \PHPUnit\Framework\TestCase
}
}
public function testDiagnoseBitmaskOptions()
{
$tests = [
[
'CURLOPT_PROTOCOLS' => [
'option' => CURLOPT_PROTOCOLS,
'bitmask' => CURLPROTO_HTTP | CURLPROTO_HTTPS,
'expected' => 'CURLPROTO_HTTP | CURLPROTO_HTTPS',
],
'CURLOPT_REDIR_PROTOCOLS' => [
'option' => CURLOPT_REDIR_PROTOCOLS,
'bitmask' => CURLPROTO_HTTPS | CURLPROTO_HTTP,
'expected' => 'CURLPROTO_HTTP | CURLPROTO_HTTPS',
],
],
[
'CURLOPT_PROTOCOLS' => [
'option' => CURLOPT_PROTOCOLS,
'bitmask' => CURLPROTO_TELNET | CURLPROTO_FTPS,
'expected' => 'CURLPROTO_FTPS | CURLPROTO_TELNET',
],
'CURLOPT_REDIR_PROTOCOLS' => [
'option' => CURLOPT_REDIR_PROTOCOLS,
'bitmask' => CURLPROTO_SCP | CURLPROTO_LDAP | CURLPROTO_LDAPS,
'expected' => 'CURLPROTO_LDAP | CURLPROTO_LDAPS | CURLPROTO_SCP',
],
],
[
'CURLOPT_PROTOCOLS' => [
'option' => CURLOPT_PROTOCOLS,
'bitmask' => CURLPROTO_ALL,
],
'CURLOPT_REDIR_PROTOCOLS' => [
'option' => CURLOPT_REDIR_PROTOCOLS,
'bitmask' => CURLPROTO_ALL,
],
],
[
'CURLOPT_PROXYAUTH' => [
'option' => CURLOPT_PROXYAUTH,
'bitmask' => CURLAUTH_BASIC,
'expected' => 'CURLAUTH_BASIC',
],
],
[
'CURLOPT_PROXYAUTH' => [
'option' => CURLOPT_PROXYAUTH,
'bitmask' => CURLAUTH_DIGEST | CURLAUTH_NTLM,
'expected' => 'CURLAUTH_DIGEST | CURLAUTH_NTLM',
],
],
[
'CURLOPT_PROXYAUTH' => [
'option' => CURLOPT_PROXYAUTH,
'bitmask' => CURLAUTH_ANY,
],
],
[
'CURLOPT_PROXYAUTH' => [
'option' => CURLOPT_PROXYAUTH,
'bitmask' => CURLAUTH_ANYSAFE,
],
],
[
'CURLOPT_HTTPAUTH' => [
'option' => CURLOPT_HTTPAUTH,
'bitmask' => CURLAUTH_BASIC,
'expected' => 'CURLAUTH_BASIC',
],
],
[
'CURLOPT_HTTPAUTH' => [
'option' => CURLOPT_HTTPAUTH,
'bitmask' => CURLAUTH_DIGEST | CURLAUTH_NTLM,
'expected' => 'CURLAUTH_DIGEST | CURLAUTH_NTLM',
],
],
[
'CURLOPT_HTTPAUTH' => [
'option' => CURLOPT_HTTPAUTH,
'bitmask' => CURLAUTH_ANY,
],
],
[
'CURLOPT_HTTPAUTH' => [
'option' => CURLOPT_HTTPAUTH,
'bitmask' => CURLAUTH_ANYSAFE,
],
],
[
'CURLOPT_SSL_OPTIONS' => [
'option' => CURLOPT_SSL_OPTIONS,
'bitmask' => CURLSSLOPT_ALLOW_BEAST | CURLSSLOPT_NO_REVOKE,
'expected' => 'CURLSSLOPT_ALLOW_BEAST | CURLSSLOPT_NO_REVOKE',
],
],
[
'CURLOPT_SSH_AUTH_TYPES' => [
'option' => CURLOPT_SSH_AUTH_TYPES,
'bitmask' => CURLSSH_AUTH_KEYBOARD | CURLSSH_AUTH_PASSWORD | CURLSSH_AUTH_PUBLICKEY,
'expected' => 'CURLSSH_AUTH_KEYBOARD | CURLSSH_AUTH_PASSWORD | CURLSSH_AUTH_PUBLICKEY',
],
],
];
if (defined('CURLOPT_PROXY_SSL_OPTIONS') && defined('CURLSSLOPT_NO_PARTIALCHAIN')) {
$tests[] = [
'CURLOPT_PROXY_SSL_OPTIONS' => [
'option' => CURLOPT_PROXY_SSL_OPTIONS,
'bitmask' => CURLSSLOPT_ALLOW_BEAST | CURLSSLOPT_NO_REVOKE | CURLSSLOPT_NO_PARTIALCHAIN,
'expected' => 'CURLSSLOPT_ALLOW_BEAST | CURLSSLOPT_NO_PARTIALCHAIN | CURLSSLOPT_NO_REVOKE',
],
];
}
foreach ($tests as $test_case) {
$test = new Test();
foreach ($test_case as $option_name => $values) {
$test->curl->setOpt($values['option'], $values['bitmask']);
}
$test->server('json_response', 'GET');
$test_output = $test->curl->diagnose(true);
foreach ($test_case as $option_name => $values) {
$expected = $option_name . ': ' . $values['bitmask'];
if (isset($values['expected'])) {
$expected .= ' (' . $values['expected'] . ')';
}
$expected .= "\n";
$this->assertStringContainsString($expected, $test_output);
}
}
}
public function testDiagnoseErrorMessage()
{
$tests = [