allow vendord
All checks were successful
Build, Push and Deploy / build-and-push (push) Successful in 3m3s
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 16s
Build, Push and Deploy / deploy-staging (push) Successful in 32s
Build, Push and Deploy / deploy-production (push) Has been skipped
Build, Push and Deploy / cleanup (push) Successful in 1s
All checks were successful
Build, Push and Deploy / build-and-push (push) Successful in 3m3s
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 16s
Build, Push and Deploy / deploy-staging (push) Successful in 32s
Build, Push and Deploy / deploy-production (push) Has been skipped
Build, Push and Deploy / cleanup (push) Successful in 1s
This commit is contained in:
207
vendor/google/cloud-storage/src/Connection/ConnectionInterface.php
vendored
Normal file
207
vendor/google/cloud-storage/src/Connection/ConnectionInterface.php
vendored
Normal file
@@ -0,0 +1,207 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2015 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Google\Cloud\Storage\Connection;
|
||||
|
||||
/**
|
||||
* Represents a connection to
|
||||
* [Cloud Storage](https://cloud.google.com/storage/).
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
interface ConnectionInterface
|
||||
{
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function deleteAcl(array $args = []);
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function getAcl(array $args = []);
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function listAcl(array $args = []);
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function insertAcl(array $args = []);
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function patchAcl(array $args = []);
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function deleteBucket(array $args = []);
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function restoreBucket(array $args = []);
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function getBucket(array $args = []);
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function listBuckets(array $args = []);
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function insertBucket(array $args = []);
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function getBucketIamPolicy(array $args);
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function setBucketIamPolicy(array $args);
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function testBucketIamPermissions(array $args);
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function patchBucket(array $args = []);
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function deleteObject(array $args = []);
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function restoreObject(array $args = []);
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function copyObject(array $args = []);
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function rewriteObject(array $args = []);
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function moveObject(array $args = []);
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function composeObject(array $args = []);
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function getObject(array $args = []);
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function listObjects(array $args = []);
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function patchObject(array $args = []);
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function downloadObject(array $args = []);
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function insertObject(array $args = []);
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function getNotification(array $args = []);
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function deleteNotification(array $args = []);
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function insertNotification(array $args = []);
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function listNotifications(array $args = []);
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function getServiceAccount(array $args = []);
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function lockRetentionPolicy(array $args = []);
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function createHmacKey(array $args = []);
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function deleteHmacKey(array $args = []);
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function getHmacKey(array $args = []);
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function updateHmacKey(array $args = []);
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function listHmacKeys(array $args = []);
|
||||
}
|
||||
72
vendor/google/cloud-storage/src/Connection/IamBucket.php
vendored
Normal file
72
vendor/google/cloud-storage/src/Connection/IamBucket.php
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Google\Cloud\Storage\Connection;
|
||||
|
||||
use Google\Cloud\Core\Iam\IamConnectionInterface;
|
||||
|
||||
/**
|
||||
* IAM Implementation for GCS Buckets
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class IamBucket implements IamConnectionInterface
|
||||
{
|
||||
/**
|
||||
* @var ConnectionInterface
|
||||
*/
|
||||
private $connection;
|
||||
|
||||
/**
|
||||
* @param ConnectionInterface $connection
|
||||
*/
|
||||
public function __construct(ConnectionInterface $connection)
|
||||
{
|
||||
$this->connection = $connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function getPolicy(array $args)
|
||||
{
|
||||
if (isset($args['requestedPolicyVersion'])) {
|
||||
$args['optionsRequestedPolicyVersion'] = $args['requestedPolicyVersion'];
|
||||
unset($args['requestedPolicyVersion']);
|
||||
}
|
||||
|
||||
return $this->connection->getBucketIamPolicy($args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function setPolicy(array $args)
|
||||
{
|
||||
unset($args['resource']);
|
||||
return $this->connection->setBucketIamPolicy($args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function testPermissions(array $args)
|
||||
{
|
||||
unset($args['resource']);
|
||||
return $this->connection->testBucketIamPermissions($args);
|
||||
}
|
||||
}
|
||||
915
vendor/google/cloud-storage/src/Connection/Rest.php
vendored
Normal file
915
vendor/google/cloud-storage/src/Connection/Rest.php
vendored
Normal file
@@ -0,0 +1,915 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2015 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Google\Cloud\Storage\Connection;
|
||||
|
||||
use Google\Auth\GetUniverseDomainInterface;
|
||||
use Google\Cloud\Core\RequestBuilder;
|
||||
use Google\Cloud\Core\RequestWrapper;
|
||||
use Google\Cloud\Core\RestTrait;
|
||||
use Google\Cloud\Core\Retry;
|
||||
use Google\Cloud\Core\Upload\AbstractUploader;
|
||||
use Google\Cloud\Core\Upload\MultipartUploader;
|
||||
use Google\Cloud\Core\Upload\ResumableUploader;
|
||||
use Google\Cloud\Core\Upload\StreamableUploader;
|
||||
use Google\Cloud\Core\UriTrait;
|
||||
use Google\Cloud\Storage\StorageClient;
|
||||
use GuzzleHttp\Exception\RequestException;
|
||||
use GuzzleHttp\Psr7\MimeType;
|
||||
use GuzzleHttp\Psr7\Request;
|
||||
use GuzzleHttp\Psr7\Utils;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
|
||||
/**
|
||||
* Implementation of the
|
||||
* [Google Cloud Storage JSON API](https://cloud.google.com/storage/docs/json_api/).
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class Rest implements ConnectionInterface
|
||||
{
|
||||
use RestTrait {
|
||||
send as private traitSend;
|
||||
}
|
||||
use RetryTrait;
|
||||
use UriTrait;
|
||||
|
||||
/**
|
||||
* Header and value that helps us identify a transcoded obj
|
||||
* w/o making a metadata(info) call.
|
||||
*/
|
||||
private const TRANSCODED_OBJ_HEADER_KEY = 'X-Goog-Stored-Content-Encoding';
|
||||
private const TRANSCODED_OBJ_HEADER_VAL = 'gzip';
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
const BASE_URI = 'https://storage.googleapis.com/storage/v1/';
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
const DEFAULT_API_ENDPOINT = 'https://storage.googleapis.com';
|
||||
|
||||
const DEFAULT_API_ENDPOINT_TEMPLATE = 'https://storage.UNIVERSE_DOMAIN';
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
const UPLOAD_URI = 'https://storage.googleapis.com/upload/storage/v1/b/{bucket}/o{?query*}';
|
||||
|
||||
const UPLOAD_PATH = 'upload/storage/v1/b/{bucket}/o{?query*}';
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
const DOWNLOAD_URI = 'https://storage.googleapis.com/storage/v1/b/{bucket}/o/{object}{?query*}';
|
||||
|
||||
const DOWNLOAD_PATH = 'storage/v1/b/{bucket}/o/{object}{?query*}';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $projectId;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $apiEndpoint;
|
||||
|
||||
/**
|
||||
* @var callable
|
||||
* value null accepted
|
||||
*/
|
||||
private $restRetryFunction;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private ?string $retryStrategy;
|
||||
|
||||
/**
|
||||
* @var callable|null
|
||||
*/
|
||||
private $restDelayFunction;
|
||||
|
||||
/**
|
||||
* @var callable|null
|
||||
*/
|
||||
private $restCalcDelayFunction;
|
||||
|
||||
/**
|
||||
* @var callable|null
|
||||
*/
|
||||
private $restRetryListener;
|
||||
|
||||
/**
|
||||
* @param array $config
|
||||
*/
|
||||
public function __construct(array $config = [])
|
||||
{
|
||||
$config += [
|
||||
'serviceDefinitionPath' => __DIR__ . '/ServiceDefinition/storage-v1.json',
|
||||
'componentVersion' => StorageClient::VERSION,
|
||||
'apiEndpoint' => null,
|
||||
// If the user has not supplied a universe domain, use the environment variable if set.
|
||||
// Otherwise, use the default ("googleapis.com").
|
||||
'universeDomain' => getenv('GOOGLE_CLOUD_UNIVERSE_DOMAIN')
|
||||
?: GetUniverseDomainInterface::DEFAULT_UNIVERSE_DOMAIN,
|
||||
// Cloud Storage needs to provide a default scope because the Storage
|
||||
// API does not accept JWTs with "audience"
|
||||
'scopes' => StorageClient::FULL_CONTROL_SCOPE,
|
||||
];
|
||||
|
||||
$this->apiEndpoint = $this->getApiEndpoint(null, $config, self::DEFAULT_API_ENDPOINT_TEMPLATE);
|
||||
|
||||
$this->setRequestWrapper(new RequestWrapper($config));
|
||||
$this->setRequestBuilder(new RequestBuilder(
|
||||
$config['serviceDefinitionPath'],
|
||||
$this->apiEndpoint
|
||||
));
|
||||
|
||||
$this->projectId = $this->pluck('projectId', $config, false);
|
||||
$this->restRetryFunction = (isset($config['restRetryFunction'])) ? $config['restRetryFunction'] : null;
|
||||
$this->retryStrategy = $config['retryStrategy'] ?? null;
|
||||
$this->restDelayFunction = $config['restDelayFunction'] ?? null;
|
||||
$this->restCalcDelayFunction = $config['restCalcDelayFunction'] ?? null;
|
||||
$this->restRetryListener = $config['restRetryListener'] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function projectId()
|
||||
{
|
||||
return $this->projectId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function deleteAcl(array $args = [])
|
||||
{
|
||||
return $this->send($args['type'], 'delete', $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function getAcl(array $args = [])
|
||||
{
|
||||
return $this->send($args['type'], 'get', $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function listAcl(array $args = [])
|
||||
{
|
||||
return $this->send($args['type'], 'list', $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function insertAcl(array $args = [])
|
||||
{
|
||||
return $this->send($args['type'], 'insert', $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function patchAcl(array $args = [])
|
||||
{
|
||||
return $this->send($args['type'], 'patch', $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function deleteBucket(array $args = [])
|
||||
{
|
||||
return $this->send('buckets', 'delete', $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function restoreBucket(array $args = [])
|
||||
{
|
||||
return $this->send('buckets', 'restore', $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function getBucket(array $args = [])
|
||||
{
|
||||
return $this->send('buckets', 'get', $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function listBuckets(array $args = [])
|
||||
{
|
||||
return $this->send('buckets', 'list', $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function insertBucket(array $args = [])
|
||||
{
|
||||
return $this->send('buckets', 'insert', $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function patchBucket(array $args = [])
|
||||
{
|
||||
return $this->send('buckets', 'patch', $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function deleteObject(array $args = [])
|
||||
{
|
||||
return $this->send('objects', 'delete', $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function restoreObject(array $args = [])
|
||||
{
|
||||
return $this->send('objects', 'restore', $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function copyObject(array $args = [])
|
||||
{
|
||||
return $this->send('objects', 'copy', $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function rewriteObject(array $args = [])
|
||||
{
|
||||
return $this->send('objects', 'rewrite', $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function moveObject(array $args = [])
|
||||
{
|
||||
return $this->send('objects', 'move', $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function composeObject(array $args = [])
|
||||
{
|
||||
return $this->send('objects', 'compose', $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function getObject(array $args = [])
|
||||
{
|
||||
return $this->send('objects', 'get', $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function listObjects(array $args = [])
|
||||
{
|
||||
return $this->send('objects', 'list', $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function patchObject(array $args = [])
|
||||
{
|
||||
return $this->send('objects', 'patch', $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function downloadObject(array $args = [])
|
||||
{
|
||||
// This makes sure we honour the range headers specified by the user
|
||||
$requestedBytes = $this->getRequestedBytes($args);
|
||||
$resultStream = Utils::streamFor(null);
|
||||
$transcodedObj = false;
|
||||
|
||||
$args['retryStrategy'] ??= $this->retryStrategy;
|
||||
|
||||
list($request, $requestOptions) = $this->buildDownloadObjectParams($args);
|
||||
|
||||
$invocationId = Uuid::uuid4()->toString();
|
||||
$requestOptions['retryHeaders'] = self::getRetryHeaders($invocationId, 1);
|
||||
$requestOptions['restRetryFunction'] = $this->getRestRetryFunction('objects', 'get', $args);
|
||||
// We try to deduce if the object is a transcoded object when we receive the headers.
|
||||
$requestOptions['restOptions']['on_headers'] = function ($response) use (&$transcodedObj) {
|
||||
$header = $response->getHeader(self::TRANSCODED_OBJ_HEADER_KEY);
|
||||
if (is_array($header) && in_array(self::TRANSCODED_OBJ_HEADER_VAL, $header)) {
|
||||
$transcodedObj = true;
|
||||
}
|
||||
};
|
||||
$attempt = null;
|
||||
$requestOptions['restRetryListener'] = function (
|
||||
\Exception $e,
|
||||
$retryAttempt,
|
||||
&$arguments
|
||||
) use (
|
||||
$resultStream,
|
||||
$requestedBytes,
|
||||
$invocationId,
|
||||
&$attempt,
|
||||
) {
|
||||
// if the exception has a response for us to use
|
||||
if ($e instanceof RequestException
|
||||
&& $e->hasResponse()
|
||||
&& $e->getResponse()->getStatusCode() >= 200
|
||||
&& $e->getResponse()->getStatusCode() < 300
|
||||
) {
|
||||
$msg = (string) $e->getResponse()->getBody();
|
||||
|
||||
$fetchedStream = Utils::streamFor($msg);
|
||||
|
||||
// add the partial response to our stream that we will return
|
||||
Utils::copyToStream($fetchedStream, $resultStream);
|
||||
|
||||
// Start from the byte that was last fetched
|
||||
$startByte = intval($requestedBytes['startByte']) + $resultStream->getSize();
|
||||
$endByte = $requestedBytes['endByte'];
|
||||
|
||||
// modify the range headers to fetch the remaining data
|
||||
$arguments[1]['headers']['Range'] = sprintf('bytes=%s-%s', $startByte, $endByte);
|
||||
$arguments[0] = $this->modifyRequestForRetry($arguments[0], $retryAttempt, $invocationId);
|
||||
|
||||
// Copy the final result to the end of the stream
|
||||
$attempt = $retryAttempt;
|
||||
}
|
||||
};
|
||||
|
||||
$fetchedStream = $this->requestWrapper->send(
|
||||
$request,
|
||||
$requestOptions
|
||||
)->getBody();
|
||||
|
||||
// If no retry attempt was made, then we can return the stream as is.
|
||||
// This is important in the case where downloadObject is called to open
|
||||
// the file but not to read from it yet.
|
||||
if ($attempt === null) {
|
||||
return $fetchedStream;
|
||||
}
|
||||
|
||||
// If our object is a transcoded object, then Range headers are not honoured.
|
||||
// That means even if we had a partial download available, the final obj
|
||||
// that was fetched will contain the complete object. So, we don't need to copy
|
||||
// the partial stream, we can just return the stream we fetched.
|
||||
if ($transcodedObj) {
|
||||
return $fetchedStream;
|
||||
}
|
||||
|
||||
Utils::copyToStream($fetchedStream, $resultStream);
|
||||
|
||||
$resultStream->seek(0);
|
||||
return $resultStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
* @experimental The experimental flag means that while we believe this method
|
||||
* or class is ready for use, it may change before release in backwards-
|
||||
* incompatible ways. Please use with caution, and test thoroughly when
|
||||
* upgrading.
|
||||
*/
|
||||
public function downloadObjectAsync(array $args = [])
|
||||
{
|
||||
list($request, $requestOptions) = $this->buildDownloadObjectParams($args);
|
||||
|
||||
return $this->requestWrapper->sendAsync(
|
||||
$request,
|
||||
$requestOptions
|
||||
)->then(function (ResponseInterface $response) {
|
||||
return $response->getBody();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function insertObject(array $args = [])
|
||||
{
|
||||
$args = $this->resolveUploadOptions($args);
|
||||
|
||||
$uploadType = AbstractUploader::UPLOAD_TYPE_RESUMABLE;
|
||||
if ($args['streamable']) {
|
||||
$uploaderClass = StreamableUploader::class;
|
||||
} elseif ($args['resumable']) {
|
||||
$uploaderClass = ResumableUploader::class;
|
||||
} else {
|
||||
$uploaderClass = MultipartUploader::class;
|
||||
$uploadType = AbstractUploader::UPLOAD_TYPE_MULTIPART;
|
||||
}
|
||||
|
||||
$uriParams = [
|
||||
'bucket' => $args['bucket'],
|
||||
'query' => [
|
||||
'predefinedAcl' => $args['predefinedAcl'],
|
||||
'uploadType' => $uploadType,
|
||||
'userProject' => $args['userProject']
|
||||
]
|
||||
];
|
||||
|
||||
// Passing the preconditions we want to extract out of arguments
|
||||
// into our query params.
|
||||
$preconditions = self::$condIdempotentOps['objects.insert'];
|
||||
foreach ($preconditions as $precondition) {
|
||||
if (isset($args[$precondition])) {
|
||||
$uriParams['query'][$precondition] = $args[$precondition];
|
||||
}
|
||||
}
|
||||
|
||||
return new $uploaderClass(
|
||||
$this->requestWrapper,
|
||||
$args['data'],
|
||||
$this->expandUri($this->apiEndpoint . self::UPLOAD_PATH, $uriParams),
|
||||
$args['uploaderOptions']
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
private function resolveUploadOptions(array $args)
|
||||
{
|
||||
$args += [
|
||||
'bucket' => null,
|
||||
'name' => null,
|
||||
'validate' => true,
|
||||
'resumable' => null,
|
||||
'streamable' => null,
|
||||
'predefinedAcl' => null,
|
||||
'metadata' => [],
|
||||
'userProject' => null,
|
||||
];
|
||||
|
||||
$args['retryStrategy'] ??= $this->retryStrategy;
|
||||
|
||||
$args['data'] = Utils::streamFor($args['data']);
|
||||
|
||||
if ($args['resumable'] === null) {
|
||||
$args['resumable'] = $args['data']->getSize() > AbstractUploader::RESUMABLE_LIMIT;
|
||||
}
|
||||
|
||||
if (!$args['name']) {
|
||||
$args['name'] = basename($args['data']->getMetadata('uri'));
|
||||
}
|
||||
|
||||
$validate = $this->chooseValidationMethod($args);
|
||||
if ($validate === 'md5') {
|
||||
$args['metadata']['md5Hash'] = base64_encode(Utils::hash($args['data'], 'md5', true));
|
||||
} elseif ($validate === 'crc32') {
|
||||
$args['metadata']['crc32c'] = $this->crcFromStream($args['data']);
|
||||
}
|
||||
|
||||
$args['metadata']['name'] = $args['name'];
|
||||
if (isset($args['retention'])) {
|
||||
// during object creation retention properties go into metadata
|
||||
// but not into request body
|
||||
$args['metadata']['retention'] = $args['retention'];
|
||||
unset($args['retention']);
|
||||
}
|
||||
unset($args['name']);
|
||||
$args['contentType'] = $args['metadata']['contentType']
|
||||
?? MimeType::fromFilename($args['metadata']['name']);
|
||||
|
||||
$uploaderOptionKeys = [
|
||||
'restOptions',
|
||||
'retries',
|
||||
'requestTimeout',
|
||||
'chunkSize',
|
||||
'contentType',
|
||||
'metadata',
|
||||
'uploadProgressCallback',
|
||||
'restDelayFunction',
|
||||
'restCalcDelayFunction',
|
||||
];
|
||||
|
||||
$args['uploaderOptions'] = array_intersect_key($args, array_flip($uploaderOptionKeys));
|
||||
$args = array_diff_key($args, array_flip($uploaderOptionKeys));
|
||||
|
||||
// Passing on custom retry function to $args['uploaderOptions']
|
||||
$retryFunc = $this->getRestRetryFunction(
|
||||
'objects',
|
||||
'insert',
|
||||
$args
|
||||
);
|
||||
$args['uploaderOptions']['restRetryFunction'] = $retryFunc;
|
||||
|
||||
$args['uploaderOptions'] = $this->addRetryHeaderLogic(
|
||||
$args['uploaderOptions']
|
||||
);
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function getBucketIamPolicy(array $args)
|
||||
{
|
||||
return $this->send('buckets', 'getIamPolicy', $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function setBucketIamPolicy(array $args)
|
||||
{
|
||||
return $this->send('buckets', 'setIamPolicy', $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function testBucketIamPermissions(array $args)
|
||||
{
|
||||
return $this->send('buckets', 'testIamPermissions', $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function getNotification(array $args = [])
|
||||
{
|
||||
return $this->send('notifications', 'get', $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function deleteNotification(array $args = [])
|
||||
{
|
||||
return $this->send('notifications', 'delete', $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function insertNotification(array $args = [])
|
||||
{
|
||||
return $this->send('notifications', 'insert', $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function listNotifications(array $args = [])
|
||||
{
|
||||
return $this->send('notifications', 'list', $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function getServiceAccount(array $args = [])
|
||||
{
|
||||
return $this->send('projects.resources.serviceAccount', 'get', $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function lockRetentionPolicy(array $args = [])
|
||||
{
|
||||
return $this->send('buckets', 'lockRetentionPolicy', $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function createHmacKey(array $args = [])
|
||||
{
|
||||
return $this->send('projects.resources.hmacKeys', 'create', $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function deleteHmacKey(array $args = [])
|
||||
{
|
||||
return $this->send('projects.resources.hmacKeys', 'delete', $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function getHmacKey(array $args = [])
|
||||
{
|
||||
return $this->send('projects.resources.hmacKeys', 'get', $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function updateHmacKey(array $args = [])
|
||||
{
|
||||
return $this->send('projects.resources.hmacKeys', 'update', $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function listHmacKeys(array $args = [])
|
||||
{
|
||||
return $this->send('projects.resources.hmacKeys', 'list', $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
* @return array
|
||||
*/
|
||||
private function buildDownloadObjectParams(array $args)
|
||||
{
|
||||
$args += [
|
||||
'bucket' => null,
|
||||
'object' => null,
|
||||
'generation' => null,
|
||||
'userProject' => null
|
||||
];
|
||||
|
||||
$requestOptions = array_intersect_key($args, [
|
||||
'restOptions' => null,
|
||||
'retries' => null,
|
||||
'restRetryFunction' => null,
|
||||
'restCalcDelayFunction' => null,
|
||||
'restDelayFunction' => null
|
||||
]);
|
||||
|
||||
$queryOptions = [
|
||||
'generation' => $args['generation'],
|
||||
'alt' => 'media',
|
||||
'userProject' => $args['userProject'],
|
||||
];
|
||||
if (isset($args['softDeleted'])) {
|
||||
// alt param cannot be specified with softDeleted param. See:
|
||||
// https://cloud.google.com/storage/docs/json_api/v1/objects/get
|
||||
unset($args['alt']);
|
||||
$queryOptions['softDeleted'] = $args['softDeleted'];
|
||||
}
|
||||
|
||||
$uri = $this->expandUri($this->apiEndpoint . self::DOWNLOAD_PATH, [
|
||||
'bucket' => $args['bucket'],
|
||||
'object' => $args['object'],
|
||||
'query' => $queryOptions,
|
||||
]);
|
||||
|
||||
return [
|
||||
new Request('GET', Utils::uriFor($uri)),
|
||||
$requestOptions
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Choose an upload validation method based on user input and platform
|
||||
* requirements.
|
||||
*
|
||||
* @param array $args
|
||||
* @return bool|string
|
||||
*/
|
||||
private function chooseValidationMethod(array $args)
|
||||
{
|
||||
// If the user provided a hash, skip hashing.
|
||||
if (isset($args['metadata']['md5Hash']) || isset($args['metadata']['crc32c'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$validate = $args['validate'];
|
||||
if (in_array($validate, [false, 'crc32', 'md5'], true)) {
|
||||
return $validate;
|
||||
}
|
||||
|
||||
// not documented, but the feature is called crc32c, so let's accept that as input anyways.
|
||||
if ($validate === 'crc32c') {
|
||||
return 'crc32';
|
||||
}
|
||||
|
||||
// is the extension loaded?
|
||||
if ($this->crc32cExtensionLoaded()) {
|
||||
return 'crc32';
|
||||
}
|
||||
|
||||
// is crc32c available in `hash()`?
|
||||
if ($this->supportsBuiltinCrc32c()) {
|
||||
return 'crc32';
|
||||
}
|
||||
|
||||
return 'md5';
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a CRC32c checksum from a stream.
|
||||
*
|
||||
* @param StreamInterface $data
|
||||
* @return string
|
||||
*/
|
||||
private function crcFromStream(StreamInterface $data)
|
||||
{
|
||||
$pos = $data->tell();
|
||||
$data->rewind();
|
||||
$crc32c = hash_init('crc32c');
|
||||
while (!$data->eof()) {
|
||||
$buffer = $data->read(1048576);
|
||||
hash_update($crc32c, $buffer);
|
||||
}
|
||||
$data->seek($pos);
|
||||
$hash = hash_final($crc32c, true);
|
||||
return base64_encode($hash);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the crc32c extension is available.
|
||||
*
|
||||
* Protected access for unit testing.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function crc32cExtensionLoaded()
|
||||
{
|
||||
return extension_loaded('crc32c');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if hash() supports crc32c.
|
||||
*
|
||||
* @return bool
|
||||
* @deprecated
|
||||
*/
|
||||
protected function supportsBuiltinCrc32c()
|
||||
{
|
||||
return extension_loaded('hash') && in_array('crc32c', hash_algos());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the required retry function and send the request.
|
||||
*
|
||||
* @param string $resource resource name, eg: buckets.
|
||||
* @param string $method method name, eg: get
|
||||
* @param array $options [optional] Options used to build out the request.
|
||||
* @param array $whitelisted [optional]
|
||||
*/
|
||||
public function send($resource, $method, array $options = [], $whitelisted = false)
|
||||
{
|
||||
$retryMap = [
|
||||
'projects.resources.serviceAccount' => 'serviceaccount',
|
||||
'projects.resources.hmacKeys' => 'hmacKey',
|
||||
'bucketAccessControls' => 'bucket_acl',
|
||||
'defaultObjectAccessControls' => 'default_object_acl',
|
||||
'objectAccessControls' => 'object_acl'
|
||||
];
|
||||
$retryResource = isset($retryMap[$resource]) ? $retryMap[$resource] : $resource;
|
||||
|
||||
$options['restRetryFunction'] = $this->restRetryFunction ?? $this->getRestRetryFunction(
|
||||
$retryResource,
|
||||
$method,
|
||||
$options
|
||||
);
|
||||
|
||||
$options += array_filter([
|
||||
'retryStrategy' => $this->retryStrategy,
|
||||
'restDelayFunction' => $this->restDelayFunction,
|
||||
'restCalcDelayFunction' => $this->restCalcDelayFunction,
|
||||
'restRetryListener' => $this->restRetryListener,
|
||||
]);
|
||||
|
||||
$options = $this->addRetryHeaderLogic($options);
|
||||
|
||||
return $this->traitSend($resource, $method, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the retry headers to $args which amends retry hash and attempt
|
||||
* count to the required header.
|
||||
* @param array $args
|
||||
* @return array
|
||||
*/
|
||||
private function addRetryHeaderLogic(array $args)
|
||||
{
|
||||
$invocationId = Uuid::uuid4()->toString();
|
||||
$args['retryHeaders'] = self::getRetryHeaders($invocationId, 1);
|
||||
|
||||
$userListener = $args['restRetryListener'] ?? null;
|
||||
|
||||
// Adding callback logic to update headers while retrying
|
||||
$args['restRetryListener'] = function (
|
||||
\Exception $e,
|
||||
$retryAttempt,
|
||||
&$arguments
|
||||
) use (
|
||||
$invocationId,
|
||||
$userListener
|
||||
) {
|
||||
$arguments[0] = $this->modifyRequestForRetry(
|
||||
$arguments[0],
|
||||
$retryAttempt,
|
||||
$invocationId
|
||||
);
|
||||
|
||||
if ($userListener) {
|
||||
$userListener($e, $retryAttempt, $arguments);
|
||||
}
|
||||
};
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
private function modifyRequestForRetry(
|
||||
RequestInterface $request,
|
||||
int $retryAttempt,
|
||||
string $invocationId
|
||||
) {
|
||||
$changes = self::getRetryHeaders($invocationId, $retryAttempt + 1);
|
||||
$headerLine = $request->getHeaderLine(Retry::RETRY_HEADER_KEY);
|
||||
|
||||
// An associative array to contain final header values as
|
||||
// $headerValueKey => $headerValue
|
||||
$headerElements = [];
|
||||
|
||||
// Adding existing values
|
||||
$headerLineValues = explode(' ', $headerLine);
|
||||
foreach ($headerLineValues as $value) {
|
||||
$key = explode('/', $value)[0];
|
||||
$headerElements[$key] = $value;
|
||||
}
|
||||
|
||||
// Adding changes with replacing value if $key already present
|
||||
foreach ($changes as $change) {
|
||||
$key = explode('/', $change)[0];
|
||||
$headerElements[$key] = $change;
|
||||
}
|
||||
|
||||
return $request->withHeader(
|
||||
Retry::RETRY_HEADER_KEY,
|
||||
implode(' ', $headerElements)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Util function to compute the bytes requested for a download request.
|
||||
*
|
||||
* @param array $options Request options
|
||||
* @return array
|
||||
*/
|
||||
private function getRequestedBytes(array $options)
|
||||
{
|
||||
$startByte = 0;
|
||||
$endByte = '';
|
||||
|
||||
if (isset($options['restOptions']) && isset($options['restOptions']['headers'])) {
|
||||
$headers = $options['restOptions']['headers'];
|
||||
if (isset($headers['Range']) || isset($headers['range'])) {
|
||||
$header = isset($headers['Range']) ? $headers['Range'] : $headers['range'];
|
||||
$range = explode('=', $header);
|
||||
$bytes = explode('-', $range[1]);
|
||||
$startByte = $bytes[0];
|
||||
$endByte = $bytes[1];
|
||||
}
|
||||
}
|
||||
|
||||
return compact('startByte', 'endByte');
|
||||
}
|
||||
}
|
||||
247
vendor/google/cloud-storage/src/Connection/RetryTrait.php
vendored
Normal file
247
vendor/google/cloud-storage/src/Connection/RetryTrait.php
vendored
Normal file
@@ -0,0 +1,247 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2022 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Google\Cloud\Storage\Connection;
|
||||
|
||||
use Google\Cloud\Storage\StorageClient;
|
||||
|
||||
/**
|
||||
* Trait which provides helper methods for retry logic.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
trait RetryTrait
|
||||
{
|
||||
/**
|
||||
* The HTTP codes that will be retried by our custom retry function.
|
||||
* @var array
|
||||
*/
|
||||
private static $httpRetryCodes = [
|
||||
0, // connection-refused OR connection-reset gives status code of 0
|
||||
200, // partial download cases
|
||||
408,
|
||||
429,
|
||||
500,
|
||||
502,
|
||||
503,
|
||||
504
|
||||
];
|
||||
|
||||
/**
|
||||
* The operations which can be retried without any conditions
|
||||
* (Idempotent)
|
||||
* @var array
|
||||
*/
|
||||
private static $idempotentOps = [
|
||||
'bucket_acl.get',
|
||||
'bucket_acl.list',
|
||||
'buckets.delete',
|
||||
'buckets.get',
|
||||
'buckets.getIamPolicy',
|
||||
'buckets.insert',
|
||||
'buckets.list',
|
||||
'buckets.lockRetentionPolicy',
|
||||
'buckets.testIamPermissions',
|
||||
'default_object_acl.get',
|
||||
'default_object_acl.list',
|
||||
'hmacKey.delete',
|
||||
'hmacKey.get',
|
||||
'hmacKey.list',
|
||||
'notifications.delete',
|
||||
'notifications.get',
|
||||
'notifications.list',
|
||||
'object_acl.get',
|
||||
'object_acl.list',
|
||||
'objects.get',
|
||||
'objects.list',
|
||||
'serviceaccount.get',
|
||||
'signBlob.execute'
|
||||
];
|
||||
|
||||
/**
|
||||
* The operations which can be retried with specific conditions
|
||||
* (Conditionally idempotent)
|
||||
* @var array
|
||||
*/
|
||||
private static $condIdempotentOps = [
|
||||
'buckets.patch' => ['ifMetagenerationMatch', 'etag'],
|
||||
// Currently etag is not supported, so this preCondition never available
|
||||
'buckets.setIamPolicy' => ['etag'],
|
||||
'buckets.update' => ['ifMetagenerationMatch', 'etag'],
|
||||
'hmacKey.update' => ['etag'],
|
||||
'objects.compose' => ['ifGenerationMatch'],
|
||||
'objects.copy' => ['ifGenerationMatch'],
|
||||
'objects.delete' => ['ifGenerationMatch'],
|
||||
'objects.insert' => ['ifGenerationMatch', 'ifGenerationNotMatch'],
|
||||
'objects.patch' => ['ifMetagenerationMatch', 'etag'],
|
||||
'objects.rewrite' => ['ifGenerationMatch'],
|
||||
'objects.update' => ['ifMetagenerationMatch']
|
||||
];
|
||||
|
||||
/**
|
||||
* Retry strategies which enforce certain behaviour like:
|
||||
* - Always retrying a call when an exception occurs(within the limits of 'max retries').
|
||||
* - Never retrying a call when an exception occurs.
|
||||
* - Retrying only when the operation is considered idempotent(default).
|
||||
* These configurations are supplied for per api call basis.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Header that identifies a specific request hash. The
|
||||
* hash needs to stay the same for multiple retries.
|
||||
*/
|
||||
private static $INVOCATION_ID_HEADER = 'gccl-invocation-id';
|
||||
|
||||
/**
|
||||
* Header that identifies the attempt count for a request. The
|
||||
* value will increment by 1 with every retry.
|
||||
*/
|
||||
private static $ATTEMPT_COUNT_HEADER = 'gccl-attempt-count';
|
||||
|
||||
/**
|
||||
* Return a retry decider function.
|
||||
*
|
||||
* @param string $resource resource name, eg: buckets.
|
||||
* @param string $method method name, eg: get
|
||||
* @param array $args
|
||||
* @return callable
|
||||
*/
|
||||
private function getRestRetryFunction($resource, $method, array $args)
|
||||
{
|
||||
if (isset($args['restRetryFunction'])) {
|
||||
return $args['restRetryFunction'];
|
||||
}
|
||||
$methodName = sprintf('%s.%s', $resource, $method);
|
||||
$isOpIdempotent = in_array($methodName, self::$idempotentOps);
|
||||
$preconditionNeeded = array_key_exists($methodName, self::$condIdempotentOps);
|
||||
$preconditionSupplied = $this->isPreConditionSupplied($methodName, $args);
|
||||
$retryStrategy = isset($args['retryStrategy']) ?
|
||||
$args['retryStrategy'] :
|
||||
StorageClient::RETRY_IDEMPOTENT;
|
||||
|
||||
return function (
|
||||
\Exception $exception,
|
||||
$currentAttempt = 0,
|
||||
$maxRetries = null
|
||||
) use (
|
||||
$isOpIdempotent,
|
||||
$preconditionNeeded,
|
||||
$preconditionSupplied,
|
||||
$retryStrategy
|
||||
) {
|
||||
return $this->retryDeciderFunction(
|
||||
$exception,
|
||||
$isOpIdempotent,
|
||||
$preconditionNeeded,
|
||||
$preconditionSupplied,
|
||||
$retryStrategy,
|
||||
$currentAttempt,
|
||||
$maxRetries
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* This function returns true when the user given
|
||||
* precondtions ($preConditions) has values that are present
|
||||
* in the precondition map ($this->condIdempotentMap) for that method.
|
||||
* eg: condIdempotentMap has entry 'objects.copy' => ['ifGenerationMatch'],
|
||||
* if the user has given 'ifGenerationMatch' in the 'objects.copy' operation,
|
||||
* it will be available in the $preConditions
|
||||
* as an array ['ifGenerationMatch']. This makes the array_intersect
|
||||
* function return a non empty result and this function returns true.
|
||||
*
|
||||
* @param string $methodName method name, eg: buckets.get.
|
||||
* @param array $args arguments which include preconditions provided,
|
||||
* eg: ['ifGenerationMatch' => 0].
|
||||
* @return bool
|
||||
*/
|
||||
private function isPreConditionSupplied($methodName, array $args)
|
||||
{
|
||||
if (isset(self::$condIdempotentOps[$methodName])) {
|
||||
// return true if required precondition are given.
|
||||
return !empty(array_intersect(
|
||||
self::$condIdempotentOps[$methodName],
|
||||
array_keys($args)
|
||||
));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decide whether the op needs to be retried or not.
|
||||
*
|
||||
* @param \Exception $exception The exception object received
|
||||
* while sending the request.
|
||||
* @param int $currentAttempt Current retry attempt.
|
||||
* @param bool $isIdempotent
|
||||
* @param bool $preconditionNeeded
|
||||
* @param bool $preconditionSupplied
|
||||
* @param int|null $maxRetries The maximum number of retries allowed.
|
||||
* Null for no limit.
|
||||
* @return bool
|
||||
*/
|
||||
private function retryDeciderFunction(
|
||||
\Exception $exception,
|
||||
$isIdempotent,
|
||||
$preconditionNeeded,
|
||||
$preconditionSupplied,
|
||||
$retryStrategy,
|
||||
$currentAttempt = 0,
|
||||
$maxRetries = null
|
||||
) {
|
||||
// If maxRetries is specified, ensure we don't exceed it
|
||||
if ($maxRetries !== null && $currentAttempt >= $maxRetries) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($retryStrategy == StorageClient::RETRY_NEVER) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$statusCode = $exception->getCode();
|
||||
// Retry if the exception status code matches
|
||||
// with one of the retriable status code and
|
||||
// the operation is either idempotent or conditionally
|
||||
// idempotent with preconditions supplied.
|
||||
|
||||
if (in_array($statusCode, self::$httpRetryCodes)) {
|
||||
if ($retryStrategy == StorageClient::RETRY_ALWAYS) {
|
||||
return true;
|
||||
} elseif ($isIdempotent) {
|
||||
return true;
|
||||
} elseif ($preconditionNeeded) {
|
||||
return $preconditionSupplied;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility func that returns the list of headers that need to be
|
||||
* attached to every request and its retries.
|
||||
*/
|
||||
private static function getRetryHeaders($invocationId, $attemptCount)
|
||||
{
|
||||
return [
|
||||
sprintf('%s/%s', self::$INVOCATION_ID_HEADER, $invocationId),
|
||||
sprintf('%s/%d', self::$ATTEMPT_COUNT_HEADER, $attemptCount)
|
||||
];
|
||||
}
|
||||
}
|
||||
5918
vendor/google/cloud-storage/src/Connection/ServiceDefinition/storage-v1.json
vendored
Normal file
5918
vendor/google/cloud-storage/src/Connection/ServiceDefinition/storage-v1.json
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user