[MEDIA] Fix trying to display file wich is not available locally
This commit is contained in:
parent
04d1caff78
commit
da82048d77
@ -59,15 +59,20 @@ class AttachmentAction extends ManagedAction
|
|||||||
{
|
{
|
||||||
parent::prepare($args);
|
parent::prepare($args);
|
||||||
|
|
||||||
|
try {
|
||||||
if (!empty($id = $this->trimmed('attachment'))) {
|
if (!empty($id = $this->trimmed('attachment'))) {
|
||||||
$this->attachment = File::getByID($id);
|
$this->attachment = File::getByID($id);
|
||||||
} elseif (!empty($filehash = $this->trimmed('filehash'))) {
|
} elseif (!empty($filehash = $this->trimmed('filehash'))) {
|
||||||
$this->attachment = File::getByHash($filehash);
|
$this->attachment = File::getByHash($filehash);
|
||||||
}
|
}
|
||||||
|
} catch (Exception $e) {
|
||||||
|
// Not found
|
||||||
|
}
|
||||||
if (!$this->attachment instanceof File) {
|
if (!$this->attachment instanceof File) {
|
||||||
// TRANS: Client error displayed trying to get a non-existing attachment.
|
// TRANS: Client error displayed trying to get a non-existing attachment.
|
||||||
$this->clientError(_('No such attachment.'), 404);
|
$this->clientError(_('No such attachment.'), 404);
|
||||||
|
} elseif (empty($this->attachment->filename)) {
|
||||||
|
$this->clientError(_('Requested local URL for a file that is not stored locally.'), 404);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -145,8 +150,11 @@ class AttachmentAction extends ManagedAction
|
|||||||
if (common_config('site', 'use_x_sendfile')) {
|
if (common_config('site', 'use_x_sendfile')) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
return filemtime($this->attachment->getPath());
|
return filemtime($this->attachment->getPath());
|
||||||
|
} catch (InvalidFilenameException $e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -165,12 +173,16 @@ class AttachmentAction extends ManagedAction
|
|||||||
|
|
||||||
$cache = Cache::instance();
|
$cache = Cache::instance();
|
||||||
if($cache) {
|
if($cache) {
|
||||||
|
try {
|
||||||
$key = Cache::key('attachments:etag:' . $this->attachment->getPath());
|
$key = Cache::key('attachments:etag:' . $this->attachment->getPath());
|
||||||
$etag = $cache->get($key);
|
$etag = $cache->get($key);
|
||||||
if($etag === false) {
|
if($etag === false) {
|
||||||
$etag = crc32(file_get_contents($this->attachment->getPath()));
|
$etag = crc32(file_get_contents($this->attachment->getPath()));
|
||||||
$cache->set($key,$etag);
|
$cache->set($key,$etag);
|
||||||
}
|
}
|
||||||
|
} catch (InvalidFilenameException $e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
return $etag;
|
return $etag;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,22 +193,23 @@ class AttachmentAction extends ManagedAction
|
|||||||
/**
|
/**
|
||||||
* Include $filepath in the response, for viewing and downloading
|
* Include $filepath in the response, for viewing and downloading
|
||||||
*/
|
*/
|
||||||
static function sendFile(string $filepath, int $size) {
|
static function sendFile(string $filepath, int $filesize) {
|
||||||
if (common_config('site', 'use_x_sendfile')) {
|
if (common_config('site', 'use_x_sendfile')) {
|
||||||
header('X-Sendfile: ' . $filepath);
|
header('X-Sendfile: ' . $filepath);
|
||||||
} else {
|
} else {
|
||||||
// ensure we have a file size
|
if (empty($filesize)) {
|
||||||
if (empty($size)) {
|
$filesize = filesize($filepath);
|
||||||
$size = filesize($filepath);
|
|
||||||
}
|
}
|
||||||
header("Content-Length: {$size}");
|
header("Content-Length: {$filesize}");
|
||||||
// header('Cache-Control: private, no-transform, no-store, must-revalidate');
|
// header('Cache-Control: private, no-transform, no-store, must-revalidate');
|
||||||
|
|
||||||
$ret = @readfile($filepath);
|
$ret = @readfile($filepath);
|
||||||
|
|
||||||
if ($ret === false || $ret !== $filesize) {
|
if (ret === false) {
|
||||||
|
common_log(LOG_ERR, "Couldn't read file at {$filepath}.");
|
||||||
|
} elseif ($ret !== $filesize) {
|
||||||
common_log(LOG_ERR, "The lengths of the file as recorded on the DB (or on disk) for the file " .
|
common_log(LOG_ERR, "The lengths of the file as recorded on the DB (or on disk) for the file " .
|
||||||
"{$filepath}, with id={$this->attachment->id} differ from what was sent to the user.");
|
"{$filepath} differ from what was sent to the user ({$filesize} vs {$ret}).");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,6 @@ class Attachment_downloadAction extends AttachmentAction
|
|||||||
header('Expires: 0');
|
header('Expires: 0');
|
||||||
header('Content-Transfer-Encoding: binary'); // FIXME? Can this be different?
|
header('Content-Transfer-Encoding: binary'); // FIXME? Can this be different?
|
||||||
|
|
||||||
parent::sendFile($filepath, $filesize);
|
AttachmentAction::sendFile($filepath, $filesize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,12 +64,17 @@ class Attachment_thumbnailAction extends AttachmentAction
|
|||||||
$file = $e->file;
|
$file = $e->file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
if (!empty($thumb)) {
|
if (!empty($thumb)) {
|
||||||
$filepath = $thumb->getPath();
|
$filepath = $thumb->getPath();
|
||||||
$filesize = 0;
|
$size = 0;
|
||||||
} else {
|
} elseif ($file->isLocal()) {
|
||||||
$filepath = $file->getPath();
|
$filepath = $file->getPath();
|
||||||
$filesize = $file->size;
|
$size = $file->size;
|
||||||
|
}
|
||||||
|
} catch (InvalidFilenameException $e) {
|
||||||
|
// We don't have a file to display
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$filename = MediaFile::getDisplayName($file);
|
$filename = MediaFile::getDisplayName($file);
|
||||||
@ -85,6 +90,6 @@ class Attachment_thumbnailAction extends AttachmentAction
|
|||||||
header('Expires: 0');
|
header('Expires: 0');
|
||||||
header('Content-Transfer-Encoding: binary');
|
header('Content-Transfer-Encoding: binary');
|
||||||
|
|
||||||
parent::sendFile($filepath, $filesize);
|
AttachmentAction::sendFile($filepath, $size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,6 @@ class Attachment_viewAction extends AttachmentAction
|
|||||||
header('Expires: 0');
|
header('Expires: 0');
|
||||||
header('Content-Transfer-Encoding: binary');
|
header('Content-Transfer-Encoding: binary');
|
||||||
|
|
||||||
parrent::sendFile($filepath, $filesize);
|
AttachmentAction::sendFile($filepath, $filesize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -127,11 +127,11 @@ class File extends Managed_DataObject
|
|||||||
$args = $r->map(mb_substr($u['path'], 1));
|
$args = $r->map(mb_substr($u['path'], 1));
|
||||||
if ($args['action'] === 'attachment') {
|
if ($args['action'] === 'attachment') {
|
||||||
try {
|
try {
|
||||||
// $args['attachment'] should always be set if action===attachment, given our routing rules
|
if (!empty($args['attachment'])) {
|
||||||
$file = File::getByID($args['attachment']);
|
return File::getByID($args['attachment']);
|
||||||
return $file;
|
} elseif ($args['filehash']) {
|
||||||
} catch (EmptyPkeyValueException $e) {
|
return File::getByHash($args['filehash']);
|
||||||
// ...but $args['attachment'] can also be 0...
|
}
|
||||||
} catch (NoResultException $e) {
|
} catch (NoResultException $e) {
|
||||||
// apparently this link goes to us, but is _not_ an existing attachment (File) ID?
|
// apparently this link goes to us, but is _not_ an existing attachment (File) ID?
|
||||||
}
|
}
|
||||||
|
@ -577,6 +577,10 @@ class MediaFile
|
|||||||
* @returns string
|
* @returns string
|
||||||
*/
|
*/
|
||||||
public static function getDisplayName(File $file) : string {
|
public static function getDisplayName(File $file) : string {
|
||||||
|
if (empty($file->filename)) {
|
||||||
|
return _('Untitled attachment');
|
||||||
|
}
|
||||||
|
|
||||||
// New file name format is "{bin2hex(original_name.ext)}-{$hash}"
|
// New file name format is "{bin2hex(original_name.ext)}-{$hash}"
|
||||||
$ret = preg_match('/^([^\.-]+)-.+$/', $file->filename, $matches);
|
$ret = preg_match('/^([^\.-]+)-.+$/', $file->filename, $matches);
|
||||||
// If there was an error in the match, something's wrong with some piece
|
// If there was an error in the match, something's wrong with some piece
|
||||||
|
@ -83,6 +83,10 @@ class StoreRemoteMediaPlugin extends Plugin
|
|||||||
|
|
||||||
$remoteUrl = $file->getUrl();
|
$remoteUrl = $file->getUrl();
|
||||||
|
|
||||||
|
if (empty($remoteUrl)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!$this->checkWhiteList($remoteUrl) ||
|
if (!$this->checkWhiteList($remoteUrl) ||
|
||||||
!$this->checkBlackList($remoteUrl)) {
|
!$this->checkBlackList($remoteUrl)) {
|
||||||
return true;
|
return true;
|
||||||
|
Loading…
Reference in New Issue
Block a user