mirror of
https://github.com/awslabs/aws-crt-php.git
synced 2026-08-18 18:13:09 +00:00
Restored FFI to working order (#28)
* Restored FFI to working order * Disabled incompatible tests, fixed string conversion * Use extension_loaded instead of checking PHP version * Added better checks for FFI * Do not build FFI deps if no FFI is present
This commit is contained in:
@@ -13,6 +13,6 @@ abstract class Signing extends NativeResource {
|
||||
function($result, $error_code) use ($on_complete) {
|
||||
$signing_result = SigningResult::fromNative($result);
|
||||
$on_complete($signing_result, $error_code);
|
||||
});
|
||||
}, null);
|
||||
}
|
||||
}
|
||||
+25
-2
@@ -24,6 +24,14 @@ final class CRT {
|
||||
if (is_null(self::$impl)) {
|
||||
// Figure out what backends are/should be available
|
||||
$backends = ['Extension'];
|
||||
if (extension_loaded('ffi')) {
|
||||
$backends = ['Extension', 'FFI'];
|
||||
if (getenv('AWS_CRT_PHP_EXTENSION')) {
|
||||
$backends = ['Extension'];
|
||||
} else if (getenv('AWS_CRT_PHP_FFI')) {
|
||||
$backends = ['FFI'];
|
||||
}
|
||||
}
|
||||
|
||||
// Try to load each backend, give up if none succeed
|
||||
$exceptions = [];
|
||||
@@ -31,6 +39,7 @@ final class CRT {
|
||||
try {
|
||||
$backend = 'AWS\\CRT\\Internal\\' . $backend;
|
||||
self::$impl = new $backend();
|
||||
break;
|
||||
} catch (RuntimeException $rex) {
|
||||
array_push($exceptions, $rex);
|
||||
}
|
||||
@@ -67,6 +76,20 @@ final class CRT {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool true if using PHP FFI (PHP 7.4+)
|
||||
*/
|
||||
public static function isFFI() {
|
||||
return self::isLoaded() && strstr(get_class(self::$impl), 'FFI');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool true if using PHP Extension awscrt
|
||||
*/
|
||||
public static function isExtension() {
|
||||
return self::isLoaded() && strstr(get_class(self::$impl), 'Extension');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return integer last error code reported within the CRT
|
||||
*/
|
||||
@@ -319,7 +342,7 @@ final class CRT {
|
||||
$signing_result, $http_message);
|
||||
}
|
||||
|
||||
function sign_request_aws($signable, $signing_config, $on_complete) {
|
||||
return self::$impl->aws_crt_sign_request_aws($signable, $signing_config, $on_complete);
|
||||
function sign_request_aws($signable, $signing_config, $on_complete, $user_data) {
|
||||
return self::$impl->aws_crt_sign_request_aws($signable, $signing_config, $on_complete, $user_data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
namespace AWS\CRT\Internal;
|
||||
|
||||
use Exception;
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* Forwards calls on to libaws-crt-ffi via FFI
|
||||
*/
|
||||
final class FFI {
|
||||
private static $ffi = null;
|
||||
private static $refcount = 0;
|
||||
|
||||
function __construct() {
|
||||
if (is_null(self::$ffi)) {
|
||||
try {
|
||||
$shlib_ext = 'so';
|
||||
$uname_s = php_uname('s');
|
||||
if ($uname_s == 'Darwin') {
|
||||
$shlib_ext = 'dylib';
|
||||
} else if ($uname_s == 'WINNT') {
|
||||
$shlib_ext = 'dll';
|
||||
}
|
||||
self::$ffi = \FFI::cdef(
|
||||
file_get_contents(__DIR__ . "/../../../api.h"),
|
||||
__DIR__ . "/../../../libaws-crt-ffi." . $shlib_ext);
|
||||
self::init();
|
||||
} catch (Exception $e) {
|
||||
throw new RuntimeException('Exception while initializing CRT via FFI', 0, $e);
|
||||
}
|
||||
}
|
||||
++self::$refcount;
|
||||
}
|
||||
|
||||
function __destruct() {
|
||||
if (--self::$refcount == 0) {
|
||||
self::clean_up();
|
||||
self::$ffi = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Forwards any call made on this object to the FFI function of the
|
||||
* same name with the supplied arguments. Argument type hinting and checking
|
||||
* occurs at the CRT wrapper.
|
||||
*/
|
||||
function __call(string $name, $args) {
|
||||
// Expand strings to (string, length)
|
||||
$ffi_args =[];
|
||||
foreach ($args as $arg) {
|
||||
if (is_string($arg)) {
|
||||
$len = strlen($arg);
|
||||
if ($len > 0) {
|
||||
$uint8_t = \FFI::type('uint8_t');
|
||||
$uint8_array = \FFI::arrayType($uint8_t, [$len]);
|
||||
$buf = \FFI::new($uint8_array);
|
||||
\FFI::memcpy($buf, $arg, $len);
|
||||
$ffi_args [] = $buf;
|
||||
$ffi_args [] = $len;
|
||||
} else {
|
||||
$ffi_args [] = null;
|
||||
$ffi_args [] = 0;
|
||||
}
|
||||
} else if (is_resource($arg)) {
|
||||
throw new RuntimeException("Resource types are not supported for FFI");
|
||||
} else {
|
||||
$ffi_args []= $arg;
|
||||
}
|
||||
}
|
||||
return call_user_func_array([self::$ffi, $name], $ffi_args);
|
||||
}
|
||||
|
||||
private static function init() {
|
||||
return self::$ffi->aws_crt_init();
|
||||
}
|
||||
|
||||
private static function clean_up() {
|
||||
return self::$ffi->aws_crt_clean_up();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user