Merge pull request #4358 from octobercms/wip/file-improvements

Use temporaryUrls for protected files if the storage driver supports them. Related: octobercms/library#406
This commit is contained in:
Luke Towers 2019-06-02 20:49:12 -06:00 committed by GitHub
commit 15e3bd131a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 65 additions and 12 deletions

View File

@ -278,14 +278,20 @@ return [
| folder - a folder prefix for storing all generated files inside.
| path - the public path relative to the application base URL,
| or you can specify a full URL path.
|
| Optionally, you can specify how long temporary URLs to protected files
| in cloud storage (ex. AWS, RackSpace) are valid for by setting
| temporaryUrlTTL to a value in seconds to define a validity period. This
| is only used for the 'uploads' config when using a supported cloud disk
*/
'storage' => [
'uploads' => [
'disk' => 'local',
'folder' => 'uploads',
'path' => '/storage/app/uploads',
'disk' => 'local',
'folder' => 'uploads',
'path' => '/storage/app/uploads',
'temporaryUrlTTL' => 3600,
],
'media' => [

View File

@ -1,6 +1,8 @@
<?php namespace Backend\Controllers;
use View;
use Cache;
use Config;
use Backend;
use Response;
use System\Models\File as FileModel;
@ -51,6 +53,40 @@ class Files extends Controller
return Response::make(View::make('backend::404'), 404);
}
/**
* Attempt to return a redirect to a temporary URL to the asset instead of streaming the asset - if supported
*
* @param System|Models\File $file
* @param string|null $path Optional, defaults to the getDiskPath() of the file
* @return string|null
*/
protected static function getTemporaryUrl($file, $path = null)
{
// Get the disk and adapter used
$url = null;
$disk = $file->getDisk();
$adapter = $disk->getAdapter();
if (class_exists('\League\Flysystem\Cached\CachedAdapter') && $adapter instanceof \League\Flysystem\Cached\CachedAdapter) {
$adapter = $adapter->getAdapter();
}
if ((class_exists('\League\Flysystem\AwsS3v3\AwsS3Adapter') && $adapter instanceof \League\Flysystem\AwsS3v3\AwsS3Adapter) ||
(class_exists('\League\Flysystem\Rackspace\RackspaceAdapter') && $adapter instanceof \League\Flysystem\Rackspace\RackspaceAdapter) ||
method_exists($adapter, 'getTemporaryUrl')
) {
if (empty($path)) {
$path = $file->getDiskPath();
}
$expires = now()->addSeconds(Config::get('cms.storage.uploads.temporaryUrlTTL', 3600));
$url = Cache::remember('backend.file:' . $path, $expires, function () use ($disk, $path, $expires) {
return $disk->temporaryUrl($path, $expires);
});
}
return $url;
}
/**
* Returns the URL for downloading a system file.
* @param $file System\Models\File
@ -58,7 +94,13 @@ class Files extends Controller
*/
public static function getDownloadUrl($file)
{
return Backend::url('backend/files/get/' . self::getUniqueCode($file));
$url = static::getTemporaryUrl($file);
if (!empty($url)) {
return $url;
} else {
return Backend::url('backend/files/get/' . self::getUniqueCode($file));
}
}
/**
@ -71,7 +113,13 @@ class Files extends Controller
*/
public static function getThumbUrl($file, $width, $height, $options)
{
return Backend::url('backend/files/thumb/' . self::getUniqueCode($file)) . '/' . $width . '/' . $height . '/' . $options['mode'] . '/' . $options['extension'];
$url = static::getTemporaryUrl($file, $file->getDiskPath($file->getThumbFilename($width, $height, $options)));
if (!empty($url)) {
return $url;
} else {
return Backend::url('backend/files/thumb/' . self::getUniqueCode($file)) . '/' . $width . '/' . $height . '/' . $options['mode'] . '/' . $options['extension'];
}
}
/**

View File

@ -42,13 +42,13 @@ class File extends FileBase
/**
* {@inheritDoc}
*/
public function getPath()
public function getPath($fileName = null)
{
$url = '';
if (!$this->isPublic() && class_exists(Files::class)) {
$url = Files::getDownloadUrl($this);
} else {
$url = parent::getPath();
$url = parent::getPath($fileName);
}
return $url;
@ -103,12 +103,11 @@ class File extends FileBase
}
/**
* Copy the local file to Storage
* @return bool True on success, false on failure.
* Returns the storage disk the file is stored on
* @return FilesystemAdapter
*/
protected function copyLocalToStorage($localPath, $storagePath)
public function getDisk()
{
$disk = Storage::disk(Config::get('cms.storage.uploads.disk'));
return $disk->put($storagePath, FileHelper::get($localPath), $this->isPublic() ? 'public' : null);
return Storage::disk(Config::get('cms.storage.uploads.disk'));
}
}