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

From Gratiel's Wiki
(→‎Code Block 1)
Line 11: Line 11:
 
  private $objectCache;
 
  private $objectCache;
 
   
 
   
−
  /** @var CappedMemoryCache|bool[] */
+
  <span style='background-color: #ecfdf0; border: #5bfb81 4px solid;'>/** @var CappedMemoryCache|bool[] */</span>
−
  private $directoryCache;
+
  <span style='background-color: #ecfdf0; border: #5bfb81 4px solid;'>private $directoryCache;</span>
 
   
 
   
 
  /** @var CappedMemoryCache|array */
 
  /** @var CappedMemoryCache|array */

Revision as of 23:07, 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