diff options
author | Adrian Brzezinski <adrian.brzezinski@eo.pl> | 2020-01-14 09:47:18 +0100 |
---|---|---|
committer | Adrian Brzezinski <adrian.brzezinski@eo.pl> | 2020-04-27 14:16:50 +0200 |
commit | 354c0996d83c853ee88dd1a26ce47e15f9866504 (patch) | |
tree | ada6b1a733c543082d1b01a5e7b9acf57b41969a /lib/private/Files/ObjectStore/Swift.php | |
parent | 2d7f71facaea2c7527db1d0e95fdf27e15be9d4d (diff) | |
download | nextcloud-server-354c0996d83c853ee88dd1a26ce47e15f9866504.tar.gz nextcloud-server-354c0996d83c853ee88dd1a26ce47e15f9866504.zip |
It's a fix for issue #14116,
Improves efficiency when downloading files from Swift storage.
Before, files were downloaded and then pushed back to user.
That behaevior causes all kinds of performance problems.
Now, files are streamed directly to user.
Signed-off-by: Adrian Brzezinski <adrian.brzezinski@eo.pl>
Diffstat (limited to 'lib/private/Files/ObjectStore/Swift.php')
-rw-r--r-- | lib/private/Files/ObjectStore/Swift.php | 37 |
1 files changed, 23 insertions, 14 deletions
diff --git a/lib/private/Files/ObjectStore/Swift.php b/lib/private/Files/ObjectStore/Swift.php index 9a2aa82295e..e0d819f8a2a 100644 --- a/lib/private/Files/ObjectStore/Swift.php +++ b/lib/private/Files/ObjectStore/Swift.php @@ -25,6 +25,12 @@ namespace OC\Files\ObjectStore; +use GuzzleHttp\Client; +use GuzzleHttp\Exception\ClientException; +use GuzzleHttp\Exception\ConnectException; +use GuzzleHttp\Exception\RequestException; +use GuzzleHttp\Exception\BadResponseException; +use GuzzleHttp\HandlerStack; use function GuzzleHttp\Psr7\stream_for; use Icewind\Streams\RetryWrapper; use OCP\Files\NotFoundException; @@ -89,30 +95,33 @@ class Swift implements IObjectStore { /** * @param string $urn the unified resource name used to identify the object * @return resource stream with the read data - * @throws \Exception from openstack lib when something goes wrong + * @throws \Exception from openstack or GuzzleHttp libs when something goes wrong * @throws NotFoundException if file does not exist */ public function readObject($urn) { try { - $object = $this->getContainer()->getObject($urn); - - // we need to keep a reference to objectContent or - // the stream will be closed before we can do anything with it - $objectContent = $object->download(); - } catch (BadResponseError $e) { - if ($e->getResponse()->getStatusCode() === 404) { + $publicUri = $this->getContainer()->getObject($urn)->getPublicUri(); + $tokenId = $this->swiftFactory->getCachedTokenId(); + + $response = (new Client())->request('GET', $publicUri, + [ + 'stream' => true, + 'headers' => [ + 'X-Auth-Token' => $tokenId, + 'Cache-Control' => 'no-cache' + ], + ] + ); + + } catch (BadResponseException $e) { + if ($e->getResponse() && $e->getResponse()->getStatusCode() === 404) { throw new NotFoundException("object $urn not found in object store"); } else { throw $e; } } - $objectContent->rewind(); - - $stream = $objectContent->detach(); - // save the object content in the context of the stream to prevent it being gc'd until the stream is closed - stream_context_set_option($stream, 'swift', 'content', $objectContent); - return RetryWrapper::wrap($stream); + return RetryWrapper::wrap($response->getBody()->detach()); } /** |