.s3.amazonaws.com").
*
* @param string $bucket Bucket name to check.
*
* @return bool
*/
public static function isBucketDnsCompatible($bucket)
{
$bucketLen = strlen($bucket);
return ($bucketLen >= 3 && $bucketLen <= 63) &&
// Cannot look like an IP address
!filter_var($bucket, FILTER_VALIDATE_IP) &&
preg_match('/^[a-z0-9]([a-z0-9\-\.]*[a-z0-9])?$/', $bucket);
}
public function createPresignedRequest(CommandInterface $command, $expires)
{
$command = clone $command;
$command->getHandlerList()->remove('signer');
/** @var \Aws\Signature\SignatureInterface $signer */
$signer = call_user_func(
$this->getSignatureProvider(),
$this->getConfig('signature_version'),
$this->getConfig('signing_name'),
$this->getConfig('signing_region')
);
return $signer->presign(
\Aws\serialize($command),
$this->getCredentials()->wait(),
$expires
);
}
public function getObjectUrl($bucket, $key)
{
$command = $this->getCommand('GetObject', [
'Bucket' => $bucket,
'Key' => $key
]);
return (string) \Aws\serialize($command)->getUri();
}
/**
* Raw URL encode a key and allow for '/' characters
*
* @param string $key Key to encode
*
* @return string Returns the encoded key
*/
public static function encodeKey($key)
{
return str_replace('%2F', '/', rawurlencode($key));
}
/**
* Provides a middleware that removes the need to specify LocationConstraint on CreateBucket.
*
* @return \Closure
*/
private function getLocationConstraintMiddleware()
{
$region = $this->getRegion();
return static function (callable $handler) use ($region) {
return function (Command $command, $request = null) use ($handler, $region) {
if ($command->getName() === 'CreateBucket') {
$locationConstraint = isset($command['CreateBucketConfiguration']['LocationConstraint'])
? $command['CreateBucketConfiguration']['LocationConstraint']
: null;
if ($locationConstraint === 'us-east-1') {
unset($command['CreateBucketConfiguration']);
} elseif ('us-east-1' !== $region && empty($locationConstraint)) {
$command['CreateBucketConfiguration'] = ['LocationConstraint' => $region];
}
}
return $handler($command, $request);
};
};
}
/**
* Provides a middleware that supports the `SaveAs` parameter.
*
* @return \Closure
*/
private function getSaveAsParameter()
{
return static function (callable $handler) {
return function (Command $command, $request = null) use ($handler) {
if ($command->getName() === 'GetObject' && isset($command['SaveAs'])) {
$command['@http']['sink'] = $command['SaveAs'];
unset($command['SaveAs']);
}
return $handler($command, $request);
};
};
}
/**
* Provides a middleware that disables content decoding on HeadObject
* commands.
*
* @return \Closure
*/
private function getHeadObjectMiddleware()
{
return static function (callable $handler) {
return function (
CommandInterface $command,
RequestInterface $request = null
) use ($handler) {
if ($command->getName() === 'HeadObject'
&& !isset($command['@http']['decode_content'])
) {
$command['@http']['decode_content'] = false;
}
return $handler($command, $request);
};
};
}
/**
* Provides a middleware that autopopulates the EncodingType parameter on
* ListObjects commands.
*
* @return \Closure
*/
private function getEncodingTypeMiddleware()
{
return static function (callable $handler) {
return function (Command $command, $request = null) use ($handler) {
$autoSet = false;
if ($command->getName() === 'ListObjects'
&& empty($command['EncodingType'])
) {
$command['EncodingType'] = 'url';
$autoSet = true;
}
return $handler($command, $request)
->then(function (ResultInterface $result) use ($autoSet) {
if ($result['EncodingType'] === 'url' && $autoSet) {
static $topLevel = [
'Delimiter',
'Marker',
'NextMarker',
'Prefix',
];
static $nested = [
['Contents', 'Key'],
['CommonPrefixes', 'Prefix'],
];
foreach ($topLevel as $key) {
if (isset($result[$key])) {
$result[$key] = urldecode($result[$key]);
}
}
foreach ($nested as $steps) {
if (isset($result[$steps[0]])) {
foreach ($result[$steps[0]] as $key => $part) {
if (isset($part[$steps[1]])) {
$result[$steps[0]][$key][$steps[1]]
= urldecode($part[$steps[1]]);
}
}
}
}
}
return $result;
});
};
};
}
/** @internal */
public static function _applyRetryConfig($value, $_, HandlerList $list)
{
if (!$value) {
return;
}
$decider = RetryMiddleware::createDefaultDecider($value);
$decider = function ($retries, $command, $request, $result, $error) use ($decider, $value) {
$maxRetries = null !== $command['@retries']
? $command['@retries']
: $value;
if ($decider($retries, $command, $request, $result, $error)) {
return true;
}
if ($error instanceof AwsException
&& $retries < $maxRetries
) {
if ($error->getResponse()
&& $error->getResponse()->getStatusCode() >= 400
) {
return strpos(
$error->getResponse()->getBody(),
'Your socket connection to the server'
) !== false;
}
if ($error->getPrevious() instanceof RequestException) {
// All commands except CompleteMultipartUpload are
// idempotent and may be retried without worry if a
// networking error has occurred.
return $command->getName() !== 'CompleteMultipartUpload';
}
}
return false;
};
$delay = [RetryMiddleware::class, 'exponentialDelay'];
$list->appendSign(Middleware::retry($decider, $delay), 'retry');
}
/** @internal */
public static function _applyApiProvider($value, array &$args, HandlerList $list)
{
ClientResolver::_apply_api_provider($value, $args, $list);
$args['parser'] = new GetBucketLocationParser(
new AmbiguousSuccessParser(
new RetryableMalformedResponseParser(
$args['parser'],
$args['exception_class']
),
$args['error_parser'],
$args['exception_class']
)
);
}
/**
* @internal
* @codeCoverageIgnore
*/
public static function applyDocFilters(array $api, array $docs)
{
$b64 = 'This value will be base64 encoded on your behalf.
';
$opt = 'This value will be computed for you it is not supplied.
';
// Add the SourceFile parameter.
$docs['shapes']['SourceFile']['base'] = 'The path to a file on disk to use instead of the Body parameter.';
$api['shapes']['SourceFile'] = ['type' => 'string'];
$api['shapes']['PutObjectRequest']['members']['SourceFile'] = ['shape' => 'SourceFile'];
$api['shapes']['UploadPartRequest']['members']['SourceFile'] = ['shape' => 'SourceFile'];
// Add the ContentSHA256 parameter.
$docs['shapes']['ContentSHA256']['base'] = 'A SHA256 hash of the body content of the request.';
$api['shapes']['ContentSHA256'] = ['type' => 'string'];
$api['shapes']['PutObjectRequest']['members']['ContentSHA256'] = ['shape' => 'ContentSHA256'];
$api['shapes']['UploadPartRequest']['members']['ContentSHA256'] = ['shape' => 'ContentSHA256'];
unset($api['shapes']['PutObjectRequest']['members']['ContentMD5']);
unset($api['shapes']['UploadPartRequest']['members']['ContentMD5']);
$docs['shapes']['ContentSHA256']['append'] = $opt;
// Add the SaveAs parameter.
$docs['shapes']['SaveAs']['base'] = 'The path to a file on disk to save the object data.';
$api['shapes']['SaveAs'] = ['type' => 'string'];
$api['shapes']['GetObjectRequest']['members']['SaveAs'] = ['shape' => 'SaveAs'];
// Several SSECustomerKey documentation updates.
$docs['shapes']['SSECustomerKey']['append'] = $b64;
$docs['shapes']['CopySourceSSECustomerKey']['append'] = $b64;
$docs['shapes']['SSECustomerKeyMd5']['append'] = $opt;
// Add the ObjectURL to various output shapes and documentation.
$docs['shapes']['ObjectURL']['base'] = 'The URI of the created object.';
$api['shapes']['ObjectURL'] = ['type' => 'string'];
$api['shapes']['PutObjectOutput']['members']['ObjectURL'] = ['shape' => 'ObjectURL'];
$api['shapes']['CopyObjectOutput']['members']['ObjectURL'] = ['shape' => 'ObjectURL'];
$api['shapes']['CompleteMultipartUploadOutput']['members']['ObjectURL'] = ['shape' => 'ObjectURL'];
// Fix references to Location Constraint.
unset($api['shapes']['CreateBucketRequest']['payload']);
$api['shapes']['BucketLocationConstraint']['enum'] = [
"ap-northeast-1",
"ap-southeast-2",
"ap-southeast-1",
"cn-north-1",
"eu-central-1",
"eu-west-1",
"us-east-1",
"us-west-1",
"us-west-2",
"sa-east-1",
];
// Add a note that the ContentMD5 is optional.
$docs['shapes']['ContentMD5']['append'] = 'The value will be computed on '
. 'your behalf.
';
return [
new Service($api, ApiProvider::defaultProvider()),
new DocModel($docs)
];
}
}