diff options
author | Andrew Dolgov <[email protected]> | 2022-11-23 21:14:33 +0300 |
---|---|---|
committer | Andrew Dolgov <[email protected]> | 2022-11-23 21:14:33 +0300 |
commit | 0c8af4992cb0f7589dcafaad65ada12753c64594 (patch) | |
tree | 18e83d068c3e7dd2499331de977782b382279396 /vendor/aws/aws-sdk-php/src/IdempotencyTokenMiddleware.php |
initial
Diffstat (limited to 'vendor/aws/aws-sdk-php/src/IdempotencyTokenMiddleware.php')
-rw-r--r-- | vendor/aws/aws-sdk-php/src/IdempotencyTokenMiddleware.php | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/vendor/aws/aws-sdk-php/src/IdempotencyTokenMiddleware.php b/vendor/aws/aws-sdk-php/src/IdempotencyTokenMiddleware.php new file mode 100644 index 0000000..dd0de42 --- /dev/null +++ b/vendor/aws/aws-sdk-php/src/IdempotencyTokenMiddleware.php @@ -0,0 +1,118 @@ +<?php +namespace Aws; + +use Aws\Api\Service; +use Psr\Http\Message\RequestInterface; + +/** + * @internal Middleware that auto fills parameters with `idempotencyToken` trait + */ +class IdempotencyTokenMiddleware +{ + /** @var Service */ + private $service; + /** @var string */ + private $bytesGenerator; + /** @var callable */ + private $nextHandler; + + /** + * Creates a middleware that populates operation parameter + * with trait 'idempotencyToken' enabled with a random UUIDv4 + * + * One of following functions needs to be available + * in order to generate random bytes used for UUID + * (SDK will attempt to utilize function in following order): + * - random_bytes (requires PHP 7.0 or above) + * - openssl_random_pseudo_bytes (requires 'openssl' module enabled) + * - mcrypt_create_iv (requires 'mcrypt' module enabled) + * + * You may also supply a custom bytes generator as an optional second + * parameter. + * + * @param \Aws\Api\Service $service + * @param callable|null $bytesGenerator + * + * @return callable + */ + public static function wrap( + Service $service, + callable $bytesGenerator = null + ) { + return function (callable $handler) use ($service, $bytesGenerator) { + return new self($handler, $service, $bytesGenerator); + }; + } + + public function __construct( + callable $nextHandler, + Service $service, + callable $bytesGenerator = null + ) { + $this->bytesGenerator = $bytesGenerator + ?: $this->findCompatibleRandomSource(); + $this->service = $service; + $this->nextHandler = $nextHandler; + } + + public function __invoke( + CommandInterface $command, + RequestInterface $request = null + ) { + $handler = $this->nextHandler; + if ($this->bytesGenerator) { + $operation = $this->service->getOperation($command->getName()); + $members = $operation->getInput()->getMembers(); + foreach ($members as $member => $value) { + if ($value['idempotencyToken']) { + $bytes = call_user_func($this->bytesGenerator, 16); + // populating UUIDv4 only when the parameter is not set + $command[$member] = $command[$member] + ?: $this->getUuidV4($bytes); + // only one member could have the trait enabled + break; + } + } + } + return $handler($command, $request); + } + + /** + * This function generates a random UUID v4 string, + * which is used as auto filled token value. + * + * @param string $bytes 16 bytes of pseudo-random bytes + * @return string + * More information about UUID v4, see: + * https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_.28random.29 + * https://tools.ietf.org/html/rfc4122#page-14 + */ + private static function getUuidV4($bytes) + { + // set version to 0100 + $bytes[6] = chr(ord($bytes[6]) & 0x0f | 0x40); + // set bits 6-7 to 10 + $bytes[8] = chr(ord($bytes[8]) & 0x3f | 0x80); + return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($bytes), 4)); + } + + /** + * This function decides the PHP function used in generating random bytes. + * + * @return callable|null + */ + private function findCompatibleRandomSource() + { + if (function_exists('random_bytes')) { + return 'random_bytes'; + } + + if (function_exists('openssl_random_pseudo_bytes')) { + return 'openssl_random_pseudo_bytes'; + } + + if (function_exists('mcrypt_create_iv')) { + return 'mcrypt_create_iv'; + } + } +} |