first commit -> move some files from one-api
This commit is contained in:
343
vendor/aws_v3/Aws/S3/S3EndpointMiddleware.php
vendored
Normal file
343
vendor/aws_v3/Aws/S3/S3EndpointMiddleware.php
vendored
Normal file
@@ -0,0 +1,343 @@
|
||||
<?php
|
||||
namespace Aws\S3;
|
||||
|
||||
use Aws\Arn\ArnParser;
|
||||
use Aws\Arn\ObjectLambdaAccessPointArn;
|
||||
use Aws\ClientResolver;
|
||||
use Aws\CommandInterface;
|
||||
use Aws\Endpoint\EndpointProvider;
|
||||
use Aws\Endpoint\PartitionEndpointProvider;
|
||||
use GuzzleHttp\Exception\InvalidArgumentException;
|
||||
use GuzzleHttp\Psr7\Uri;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
|
||||
/**
|
||||
* Used to update the URL used for S3 requests to support:
|
||||
* S3 Accelerate, S3 DualStack or Both. It will build to
|
||||
* host style paths unless specified, including for S3
|
||||
* DualStack.
|
||||
*
|
||||
* IMPORTANT: this middleware must be added after the "build" step.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class S3EndpointMiddleware
|
||||
{
|
||||
private static $exclusions = [
|
||||
'CreateBucket' => true,
|
||||
'DeleteBucket' => true,
|
||||
'ListBuckets' => true,
|
||||
];
|
||||
|
||||
const NO_PATTERN = 0;
|
||||
const DUALSTACK = 1;
|
||||
const ACCELERATE = 2;
|
||||
const ACCELERATE_DUALSTACK = 3;
|
||||
const PATH_STYLE = 4;
|
||||
const HOST_STYLE = 5;
|
||||
|
||||
/** @var bool */
|
||||
private $accelerateByDefault;
|
||||
/** @var bool */
|
||||
private $dualStackByDefault;
|
||||
/** @var bool */
|
||||
private $pathStyleByDefault;
|
||||
/** @var string */
|
||||
private $region;
|
||||
/** @var callable */
|
||||
private $endpointProvider;
|
||||
/** @var callable */
|
||||
private $nextHandler;
|
||||
/** @var string */
|
||||
private $endpoint;
|
||||
|
||||
/**
|
||||
* Create a middleware wrapper function
|
||||
*
|
||||
* @param string $region
|
||||
* @param EndpointProvider $endpointProvider
|
||||
* @param array $options
|
||||
*
|
||||
* @return callable
|
||||
*/
|
||||
public static function wrap($region, $endpointProvider, array $options)
|
||||
{
|
||||
return function (callable $handler) use ($region, $endpointProvider, $options) {
|
||||
return new self($handler, $region, $options, $endpointProvider);
|
||||
};
|
||||
}
|
||||
|
||||
public function __construct(
|
||||
callable $nextHandler,
|
||||
$region,
|
||||
array $options,
|
||||
$endpointProvider = null
|
||||
) {
|
||||
$this->pathStyleByDefault = isset($options['path_style'])
|
||||
? (bool) $options['path_style'] : false;
|
||||
$this->dualStackByDefault = isset($options['dual_stack'])
|
||||
? (bool) $options['dual_stack'] : false;
|
||||
$this->accelerateByDefault = isset($options['accelerate'])
|
||||
? (bool) $options['accelerate'] : false;
|
||||
$this->region = (string) $region;
|
||||
$this->endpoint = isset($options['endpoint'])
|
||||
? $options['endpoint'] : "";
|
||||
$this->endpointProvider = is_null($endpointProvider)
|
||||
? PartitionEndpointProvider::defaultProvider()
|
||||
: $endpointProvider;
|
||||
$this->nextHandler = $nextHandler;
|
||||
}
|
||||
|
||||
public function __invoke(CommandInterface $command, RequestInterface $request)
|
||||
{
|
||||
if (!empty($this->endpoint)) {
|
||||
$request = $this->applyEndpoint($command, $request);
|
||||
} else {
|
||||
switch ($this->endpointPatternDecider($command, $request)) {
|
||||
case self::HOST_STYLE:
|
||||
$request = $this->applyHostStyleEndpoint($command, $request);
|
||||
break;
|
||||
case self::NO_PATTERN:
|
||||
break;
|
||||
case self::PATH_STYLE:
|
||||
$request = $this->applyPathStyleEndpointCustomizations($command, $request);
|
||||
break;
|
||||
case self::DUALSTACK:
|
||||
$request = $this->applyDualStackEndpoint($command, $request);
|
||||
break;
|
||||
case self::ACCELERATE:
|
||||
$request = $this->applyAccelerateEndpoint(
|
||||
$command,
|
||||
$request,
|
||||
's3-accelerate'
|
||||
);
|
||||
break;
|
||||
case self::ACCELERATE_DUALSTACK:
|
||||
$request = $this->applyAccelerateEndpoint(
|
||||
$command,
|
||||
$request,
|
||||
's3-accelerate.dualstack'
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
$nextHandler = $this->nextHandler;
|
||||
return $nextHandler($command, $request);
|
||||
}
|
||||
|
||||
private static function isRequestHostStyleCompatible(
|
||||
CommandInterface $command,
|
||||
RequestInterface $request
|
||||
) {
|
||||
return S3Client::isBucketDnsCompatible($command['Bucket'])
|
||||
&& (
|
||||
$request->getUri()->getScheme() === 'http'
|
||||
|| strpos($command['Bucket'], '.') === false
|
||||
)
|
||||
&& filter_var($request->getUri()->getHost(), FILTER_VALIDATE_IP) === false;
|
||||
}
|
||||
|
||||
private function endpointPatternDecider(
|
||||
CommandInterface $command,
|
||||
RequestInterface $request
|
||||
) {
|
||||
$accelerate = isset($command['@use_accelerate_endpoint'])
|
||||
? $command['@use_accelerate_endpoint'] : $this->accelerateByDefault;
|
||||
$dualStack = isset($command['@use_dual_stack_endpoint'])
|
||||
? $command['@use_dual_stack_endpoint'] : $this->dualStackByDefault;
|
||||
$pathStyle = isset($command['@use_path_style_endpoint'])
|
||||
? $command['@use_path_style_endpoint'] : $this->pathStyleByDefault;
|
||||
|
||||
if ($accelerate && $dualStack) {
|
||||
// When try to enable both for operations excluded from s3-accelerate,
|
||||
// only dualstack endpoints will be enabled.
|
||||
return $this->canAccelerate($command)
|
||||
? self::ACCELERATE_DUALSTACK
|
||||
: self::DUALSTACK;
|
||||
}
|
||||
|
||||
if ($accelerate && $this->canAccelerate($command)) {
|
||||
return self::ACCELERATE;
|
||||
}
|
||||
|
||||
if ($dualStack) {
|
||||
return self::DUALSTACK;
|
||||
}
|
||||
|
||||
if (!$pathStyle
|
||||
&& self::isRequestHostStyleCompatible($command, $request)
|
||||
) {
|
||||
return self::HOST_STYLE;
|
||||
}
|
||||
|
||||
return self::PATH_STYLE;
|
||||
}
|
||||
|
||||
private function canAccelerate(CommandInterface $command)
|
||||
{
|
||||
return empty(self::$exclusions[$command->getName()])
|
||||
&& S3Client::isBucketDnsCompatible($command['Bucket']);
|
||||
}
|
||||
|
||||
private function getBucketStyleHost(CommandInterface $command, $host)
|
||||
{
|
||||
// For operations on the base host (e.g. ListBuckets)
|
||||
if (!isset($command['Bucket'])) {
|
||||
return $host;
|
||||
}
|
||||
|
||||
return "{$command['Bucket']}.{$host}";
|
||||
}
|
||||
|
||||
private function applyHostStyleEndpoint(
|
||||
CommandInterface $command,
|
||||
RequestInterface $request
|
||||
) {
|
||||
$uri = $request->getUri();
|
||||
$request = $request->withUri(
|
||||
$uri->withHost($this->getBucketStyleHost(
|
||||
$command,
|
||||
$uri->getHost()
|
||||
))
|
||||
->withPath($this->getBucketlessPath(
|
||||
$uri->getPath(),
|
||||
$command
|
||||
))
|
||||
);
|
||||
return $request;
|
||||
}
|
||||
|
||||
private function applyPathStyleEndpointCustomizations(
|
||||
CommandInterface $command,
|
||||
RequestInterface $request
|
||||
) {
|
||||
if ($command->getName() == 'WriteGetObjectResponse') {
|
||||
$dnsSuffix = $this->endpointProvider
|
||||
->getPartition($this->region, 's3')
|
||||
->getDnsSuffix();
|
||||
$fips = \Aws\is_fips_pseudo_region($this->region) ? "-fips" : "";
|
||||
$region = \Aws\strip_fips_pseudo_regions($this->region);
|
||||
$host =
|
||||
"{$command['RequestRoute']}.s3-object-lambda{$fips}.{$region}.{$dnsSuffix}";
|
||||
|
||||
$uri = $request->getUri();
|
||||
$request = $request->withUri(
|
||||
$uri->withHost($host)
|
||||
->withPath($this->getBucketlessPath(
|
||||
$uri->getPath(),
|
||||
$command
|
||||
))
|
||||
);
|
||||
}
|
||||
return $request;
|
||||
}
|
||||
|
||||
|
||||
private function applyDualStackEndpoint(
|
||||
CommandInterface $command,
|
||||
RequestInterface $request
|
||||
) {
|
||||
$request = $request->withUri(
|
||||
$request->getUri()->withHost($this->getDualStackHost())
|
||||
);
|
||||
|
||||
if (empty($command['@use_path_style_endpoint'])
|
||||
&& !$this->pathStyleByDefault
|
||||
&& self::isRequestHostStyleCompatible($command, $request)
|
||||
) {
|
||||
$request = $this->applyHostStyleEndpoint($command, $request);
|
||||
}
|
||||
return $request;
|
||||
}
|
||||
|
||||
private function getDualStackHost()
|
||||
{
|
||||
$dnsSuffix = $this->endpointProvider
|
||||
->getPartition($this->region, 's3')
|
||||
->getDnsSuffix();
|
||||
return "s3.dualstack.{$this->region}.{$dnsSuffix}";
|
||||
}
|
||||
|
||||
private function applyAccelerateEndpoint(
|
||||
CommandInterface $command,
|
||||
RequestInterface $request,
|
||||
$pattern
|
||||
) {
|
||||
$request = $request->withUri(
|
||||
$request->getUri()
|
||||
->withHost($this->getAccelerateHost($command, $pattern))
|
||||
->withPath($this->getBucketlessPath(
|
||||
$request->getUri()->getPath(),
|
||||
$command
|
||||
))
|
||||
);
|
||||
return $request;
|
||||
}
|
||||
|
||||
private function getAccelerateHost(CommandInterface $command, $pattern)
|
||||
{
|
||||
$dnsSuffix = $this->endpointProvider
|
||||
->getPartition($this->region, 's3')
|
||||
->getDnsSuffix();
|
||||
return "{$command['Bucket']}.{$pattern}.{$dnsSuffix}";
|
||||
}
|
||||
|
||||
private function getBucketlessPath($path, CommandInterface $command)
|
||||
{
|
||||
$pattern = '/^\\/' . preg_quote($command['Bucket'], '/') . '/';
|
||||
$path = preg_replace($pattern, '', $path) ?: '/';
|
||||
if (substr($path, 0 , 1) !== '/') {
|
||||
$path = '/' . $path;
|
||||
}
|
||||
return $path;
|
||||
}
|
||||
|
||||
private function applyEndpoint(
|
||||
CommandInterface $command,
|
||||
RequestInterface $request
|
||||
) {
|
||||
$dualStack = isset($command['@use_dual_stack_endpoint'])
|
||||
? $command['@use_dual_stack_endpoint'] : $this->dualStackByDefault;
|
||||
if (ArnParser::isArn($command['Bucket'])) {
|
||||
$arn = ArnParser::parse($command['Bucket']);
|
||||
$outpost = $arn->getService() == 's3-outposts';
|
||||
if ($outpost && $dualStack) {
|
||||
throw new InvalidArgumentException("Outposts + dualstack is not supported");
|
||||
}
|
||||
if ($arn instanceof ObjectLambdaAccessPointArn) {
|
||||
return $request;
|
||||
}
|
||||
}
|
||||
if ($dualStack) {
|
||||
throw new InvalidArgumentException("Custom Endpoint + Dualstack not supported");
|
||||
}
|
||||
if ($command->getName() == 'WriteGetObjectResponse') {
|
||||
$host = "{$command['RequestRoute']}.{$this->endpoint}";
|
||||
$uri = $request->getUri();
|
||||
return $request = $request->withUri(
|
||||
$uri->withHost($host)
|
||||
->withPath($this->getBucketlessPath(
|
||||
$uri->getPath(),
|
||||
$command
|
||||
))
|
||||
);
|
||||
}
|
||||
$host = ($this->pathStyleByDefault) ?
|
||||
$this->endpoint :
|
||||
$this->getBucketStyleHost(
|
||||
$command,
|
||||
$this->endpoint
|
||||
);
|
||||
$uri = $request->getUri();
|
||||
$scheme = $uri->getScheme();
|
||||
if(empty($scheme)){
|
||||
$request = $request->withUri(
|
||||
$uri->withHost($host)
|
||||
);
|
||||
} else {
|
||||
$request = $request->withUri($uri);
|
||||
}
|
||||
|
||||
return $request;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user