Difference between revisions of "NextCloud: Heroku: Install: Apply S3 Patch to NextCloud"

From Gratiel's Wiki
(Created page with "Need to apply the patch. git add . git commit -m "Apply S3 Patch". == Return == * NextCloud: Heroku: Install * NextCloud: Heroku * NextCloud * Public")
 
Line 1: Line 1:
 +
== Replace AmaonS3.php ==
 +
You can find this file under:
 +
server/apps/files_external/lib/Lib/Storage/AmazonS3.php
 +
 +
== Manually Applying Code ==
 +
 +
=== Code Block 1 ===
 +
Navigate to Line 61:
 +
 +
/** @var CappedMemoryCache|Result[] */
 +
private $objectCache;
 +
 +
/** @var CappedMemoryCache|bool[] */
 +
private $directoryCache;
 +
 +
/** @var CappedMemoryCache|array */
 +
private $filesCache;
 +
 +
=== Code Block 2 ===
 +
Navigate to Line 71:
 +
parent::__construct($parameters);
 +
$this->parseParams($parameters);
 +
$this->objectCache = new CappedMemoryCache();
 +
$this->directoryCache = new CappedMemoryCache();
 +
$this->filesCache = new CappedMemoryCache();
 +
 +
=== Code Block 3 ===
 +
Navigate to Line 103:
 +
private function clearCache() {
 +
    $this->objectCache = new CappedMemoryCache();
 +
    $this->directoryCache = new CappedMemoryCache();
 +
    $this->filesCache = new CappedMemoryCache();
 +
}
 +
 +
=== Code Block 4 ===
 +
Navigate to Line 115:
 +
            unset($this->objectCache[$existingKey]);
 +
        }
 +
    }
 +
    unset($this->filesCache[$key]);
 +
    unset($this->directoryCache[$key], $this->filesCache[$key]);
 +
}
 +
 +
=== Code Block 5 ===
 +
Navigate to Line 140:
 +
        return $this->objectCache[$key];
 +
    }
 +
 +
    /**
 +
      * Return true if directory exists
 +
      *
 +
      * There are no folders in s3. A folder like structure could be archived
 +
      * by prefixing files with the folder name.
 +
      *
 +
      * Implementation from flysystem-aws-s3-v3:
 +
      * https://github.com/thephpleague/flysystem-aws-s3-v3/blob/8241e9cc5b28f981e0d24cdaf9867f14c7498ae4/src/AwsS3Adapter.php#L670-L694
 +
      *
 +
      * @param $path
 +
      * @return bool
 +
      * @throws \Exception
 +
      */
 +
    private function doesDirectoryExist($path) {
 +
        if (!isset($this->directoryCache[$path])) {
 +
            // Maybe this isn't an actual key, but a prefix.
 +
            // Do a prefix listing of objects to determine.
 +
            try {
 +
                $result = $this->getConnection()->listObjects([
 +
                    'Bucket' => $this->bucket,
 +
                    'Prefix' => rtrim($path, '/') . '/',
 +
                    'MaxKeys' => 1,
 +
                ]);
 +
                $this->directoryCache[$path] = $result['Contents'] || $result['CommonPrefixes'];
 +
            } catch (S3Exception $e) {
 +
                if ($e->getStatusCode() === 403) {
 +
                    $this->directoryCache[$path] = false;
 +
                }
 +
                throw $e;
 +
            }
 +
        }
 +
 
 +
        return $this->directoryCache[$path];
 +
      }
 +
 +
      /**
 +
      * Updates old storage ids (v0.2.1 and older) that are based on key and secret to new ones based on the bucket name.
 +
      * TODO Do this in an update.php. requires iterating over all users and loading the mount.json from their home
 +
 +
 +
 +
=== Code Block 6 ===
 +
Navigate to Line 334:
 +
// sub folders
 +
if (is_array($result['CommonPrefixes'])) {
 +
    foreach ($result['CommonPrefixes'] as $prefix) {
 +
        $files[] = substr(trim($prefix['Prefix'], '/'), strlen($path));
 +
        $directoryName = trim($prefix['Prefix'], '/');
 +
        $files[] = substr($directoryName, strlen($path));
 +
        $this->directoryCache[$directoryName] = true;
 +
    }
 +
}
 +
 +
=== Code Block 7 ===
 +
Navigate to Line 434:
 +
public function is_dir($path) {
 +
    $path = $this->normalizePath($path);
 +
 +
    if (isset($this->filesCache[$path])) {
 +
        return false;
 +
    }
 +
 +
    try {
 +
        return $this->isRoot($path) || $this->headObject($path . '/');
 +
        return $this->isRoot($path) || $this->doesDirectoryExist($path);
 +
    } catch (S3Exception $e) {
 +
        \OC::$server->getLogger()->logException($e, ['app' => 'files_external']);
 +
        return false;
 +
 +
=== Code Block 8 ===
 +
Navigate to Line 458:
 +
    if (isset($this->filesCache[$path]) || $this->headObject($path)) {
 +
        return 'file';
 +
    }
 +
    if ($this->headObject($path . '/')) {
 +
    if ($this->doesDirectoryExist($path)) {
 +
        return 'dir';
 +
    }
 +
} catch (S3Exception $e) {
 +
 +
 +
 +
 
Need to apply the patch.
 
Need to apply the patch.
  

Revision as of 23:00, 16 September 2019

Replace AmaonS3.php

You can find this file under:

server/apps/files_external/lib/Lib/Storage/AmazonS3.php

Manually Applying Code

Code Block 1

Navigate to Line 61:

/** @var CappedMemoryCache|Result[] */
private $objectCache;

/** @var CappedMemoryCache|bool[] */
private $directoryCache;

/** @var CappedMemoryCache|array */
private $filesCache;

Code Block 2

Navigate to Line 71:

parent::__construct($parameters);
$this->parseParams($parameters);
$this->objectCache = new CappedMemoryCache();
$this->directoryCache = new CappedMemoryCache();
$this->filesCache = new CappedMemoryCache();

Code Block 3

Navigate to Line 103:

private function clearCache() {
    $this->objectCache = new CappedMemoryCache();
    $this->directoryCache = new CappedMemoryCache();
    $this->filesCache = new CappedMemoryCache();
}

Code Block 4

Navigate to Line 115:

            unset($this->objectCache[$existingKey]);
        }
    }
    unset($this->filesCache[$key]);
    unset($this->directoryCache[$key], $this->filesCache[$key]);
}

Code Block 5

Navigate to Line 140:

        return $this->objectCache[$key];
    }

    /**
     * Return true if directory exists
     *
     * There are no folders in s3. A folder like structure could be archived
     * by prefixing files with the folder name.
     *
     * Implementation from flysystem-aws-s3-v3:
     * https://github.com/thephpleague/flysystem-aws-s3-v3/blob/8241e9cc5b28f981e0d24cdaf9867f14c7498ae4/src/AwsS3Adapter.php#L670-L694
     *
     * @param $path
     * @return bool
     * @throws \Exception
     */
    private function doesDirectoryExist($path) {
        if (!isset($this->directoryCache[$path])) {
            // Maybe this isn't an actual key, but a prefix.
            // Do a prefix listing of objects to determine.
            try {
                $result = $this->getConnection()->listObjects([
                    'Bucket' => $this->bucket,
                    'Prefix' => rtrim($path, '/') . '/',
                    'MaxKeys' => 1,
                ]);
                $this->directoryCache[$path] = $result['Contents'] || $result['CommonPrefixes'];
            } catch (S3Exception $e) {
                if ($e->getStatusCode() === 403) {
                    $this->directoryCache[$path] = false;
                }
                throw $e;
            }
        }
 
        return $this->directoryCache[$path];
     }

     /**
      * Updates old storage ids (v0.2.1 and older) that are based on key and secret to new ones based on the bucket name.
      * TODO Do this in an update.php. requires iterating over all users and loading the mount.json from their home


Code Block 6

Navigate to Line 334:

// sub folders
if (is_array($result['CommonPrefixes'])) {
    foreach ($result['CommonPrefixes'] as $prefix) {
        $files[] = substr(trim($prefix['Prefix'], '/'), strlen($path));
        $directoryName = trim($prefix['Prefix'], '/');
        $files[] = substr($directoryName, strlen($path));
        $this->directoryCache[$directoryName] = true;
    }
}

Code Block 7

Navigate to Line 434:

public function is_dir($path) {
    $path = $this->normalizePath($path);

    if (isset($this->filesCache[$path])) {
        return false;
    }

    try {
        return $this->isRoot($path) || $this->headObject($path . '/');
        return $this->isRoot($path) || $this->doesDirectoryExist($path);
    } catch (S3Exception $e) {
        \OC::$server->getLogger()->logException($e, ['app' => 'files_external']);
        return false;

Code Block 8

Navigate to Line 458:

    if (isset($this->filesCache[$path]) || $this->headObject($path)) {
        return 'file';
    }
    if ($this->headObject($path . '/')) {
    if ($this->doesDirectoryExist($path)) {
        return 'dir';
    }
} catch (S3Exception $e) {



Need to apply the patch.

git add .
git commit -m "Apply S3 Patch".

Return