diff options
author | Git'Fellow <12234510+solracsf@users.noreply.github.com> | 2024-07-05 10:49:10 +0200 |
---|---|---|
committer | Git'Fellow <12234510+solracsf@users.noreply.github.com> | 2024-07-05 16:24:32 +0200 |
commit | c84e76a7493917133b0b8b2884a54cc29174e978 (patch) | |
tree | 913f69999578fec20f96612b3e4903d923a55a28 /lib/private | |
parent | a98a0eb7cd8dc33b906a5c1aa981fcdc96c23da9 (diff) | |
download | nextcloud-server-c84e76a7493917133b0b8b2884a54cc29174e978.tar.gz nextcloud-server-c84e76a7493917133b0b8b2884a54cc29174e978.zip |
fix(s3): Don't wait indefinitely for S3 to return
Signed-off-by: Git'Fellow <12234510+solracsf@users.noreply.github.com>
fix: lint
Signed-off-by: Git'Fellow <12234510+solracsf@users.noreply.github.com>
fix: use AwsException
Signed-off-by: Git'Fellow <12234510+solracsf@users.noreply.github.com>
fix: Throw on connection failure
Signed-off-by: Git'Fellow <12234510+solracsf@users.noreply.github.com>
fix: Wrap all in try catch block
Signed-off-by: Git'Fellow <12234510+solracsf@users.noreply.github.com>
fix: use RequestTimeout error message
Signed-off-by: Git'Fellow <12234510+solracsf@users.noreply.github.com>
log: use OCP Server class
Signed-off-by: Git'Fellow <12234510+solracsf@users.noreply.github.com>
fix: Handle connect timeout only
Signed-off-by: Git'Fellow <12234510+solracsf@users.noreply.github.com>
fix: Handle errors more generically
Signed-off-by: Git'Fellow <12234510+solracsf@users.noreply.github.com>
Diffstat (limited to 'lib/private')
-rw-r--r-- | lib/private/Files/ObjectStore/S3ConnectionTrait.php | 66 |
1 files changed, 37 insertions, 29 deletions
diff --git a/lib/private/Files/ObjectStore/S3ConnectionTrait.php b/lib/private/Files/ObjectStore/S3ConnectionTrait.php index 4609ad18905..0506eb35353 100644 --- a/lib/private/Files/ObjectStore/S3ConnectionTrait.php +++ b/lib/private/Files/ObjectStore/S3ConnectionTrait.php @@ -14,6 +14,7 @@ use Aws\S3\S3Client; use GuzzleHttp\Promise\Create; use GuzzleHttp\Promise\RejectedPromise; use OCP\ICertificateManager; +use OCP\Server; use Psr\Log\LoggerInterface; trait S3ConnectionTrait { @@ -98,7 +99,11 @@ trait S3ConnectionTrait { 'signature_provider' => \Aws\or_chain([self::class, 'legacySignatureProvider'], ClientResolver::_default_signature_provider()), 'csm' => false, 'use_arn_region' => false, - 'http' => ['verify' => $this->getCertificateBundlePath()], + 'http' => [ + 'verify' => $this->getCertificateBundlePath(), + // Timeout for the connection to S3 server, not for the request. + 'connect_timeout' => 5 + ], 'use_aws_shared_config_files' => false, ]; @@ -116,35 +121,38 @@ trait S3ConnectionTrait { } $this->connection = new S3Client($options); - if (!$this->connection::isBucketDnsCompatible($this->bucket)) { - $logger = \OC::$server->get(LoggerInterface::class); - $logger->debug('Bucket "' . $this->bucket . '" This bucket name is not dns compatible, it may contain invalid characters.', - ['app' => 'objectstore']); - } - - if ($this->params['verify_bucket_exists'] && !$this->connection->doesBucketExist($this->bucket)) { - $logger = \OC::$server->get(LoggerInterface::class); - try { - $logger->info('Bucket "' . $this->bucket . '" does not exist - creating it.', ['app' => 'objectstore']); - if (!$this->connection::isBucketDnsCompatible($this->bucket)) { - throw new \Exception("The bucket will not be created because the name is not dns compatible, please correct it: " . $this->bucket); - } - $this->connection->createBucket(['Bucket' => $this->bucket]); - $this->testTimeout(); - } catch (S3Exception $e) { - $logger->debug('Invalid remote storage.', [ - 'exception' => $e, - 'app' => 'objectstore', - ]); - if ($e->getAwsErrorCode() !== "BucketAlreadyOwnedByYou") { - throw new \Exception('Creation of bucket "' . $this->bucket . '" failed. ' . $e->getMessage()); + try { + $logger = Server::get(LoggerInterface::class); + if (!$this->connection::isBucketDnsCompatible($this->bucket)) { + $logger->debug('Bucket "' . $this->bucket . '" This bucket name is not dns compatible, it may contain invalid characters.', + ['app' => 'objectstore']); + } + + if ($this->params['verify_bucket_exists'] && !$this->connection->doesBucketExist($this->bucket)) { + try { + $logger->info('Bucket "' . $this->bucket . '" does not exist - creating it.', ['app' => 'objectstore']); + if (!$this->connection::isBucketDnsCompatible($this->bucket)) { + throw new \Exception("The bucket will not be created because the name is not dns compatible, please correct it: " . $this->bucket); + } + $this->connection->createBucket(['Bucket' => $this->bucket]); + $this->testTimeout(); + } catch (S3Exception $e) { + $logger->debug('Invalid remote storage.', [ + 'exception' => $e, + 'app' => 'objectstore', + ]); + if ($e->getAwsErrorCode() !== 'BucketAlreadyOwnedByYou') { + throw new \Exception('Creation of bucket "' . $this->bucket . '" failed. ' . $e->getMessage()); + } } } - } - - // google cloud's s3 compatibility doesn't like the EncodingType parameter - if (strpos($base_url, 'storage.googleapis.com')) { - $this->connection->getHandlerList()->remove('s3.auto_encode'); + + // google cloud's s3 compatibility doesn't like the EncodingType parameter + if (strpos($base_url, 'storage.googleapis.com')) { + $this->connection->getHandlerList()->remove('s3.auto_encode'); + } + } catch (S3Exception $e) { + throw new \Exception('S3 service is unable to handle request: ' . $e->getMessage()); } return $this->connection; @@ -193,7 +201,7 @@ trait S3ConnectionTrait { // since we store the certificate bundles on the primary storage, we can't get the bundle while setting up the primary storage if (!isset($this->params['primary_storage'])) { /** @var ICertificateManager $certManager */ - $certManager = \OC::$server->get(ICertificateManager::class); + $certManager = Server::get(ICertificateManager::class); return $certManager->getAbsoluteBundlePath(); } else { return \OC::$SERVERROOT . '/resources/config/ca-bundle.crt'; |