[MEDIA] Fix trying to display file wich is not available locally

This commit is contained in:
Miguel Dantas 2019-06-28 00:18:27 +01:00 committed by Diogo Cordeiro
parent 04d1caff78
commit da82048d77
7 changed files with 59 additions and 33 deletions

View File

@ -59,15 +59,20 @@ class AttachmentAction extends ManagedAction
{ {
parent::prepare($args); parent::prepare($args);
if (!empty($id = $this->trimmed('attachment'))) { try {
$this->attachment = File::getByID($id); if (!empty($id = $this->trimmed('attachment'))) {
} elseif (!empty($filehash = $this->trimmed('filehash'))) { $this->attachment = File::getByID($id);
$this->attachment = File::getByHash($filehash); } elseif (!empty($filehash = $this->trimmed('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,11 +173,15 @@ class AttachmentAction extends ManagedAction
$cache = Cache::instance(); $cache = Cache::instance();
if($cache) { if($cache) {
$key = Cache::key('attachments:etag:' . $this->attachment->getPath()); try {
$etag = $cache->get($key); $key = Cache::key('attachments:etag:' . $this->attachment->getPath());
if($etag === false) { $etag = $cache->get($key);
$etag = crc32(file_get_contents($this->attachment->getPath())); if($etag === false) {
$cache->set($key,$etag); $etag = crc32(file_get_contents($this->attachment->getPath()));
$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}).");
} }
} }
} }

View File

@ -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);
} }
} }

View File

@ -64,12 +64,17 @@ class Attachment_thumbnailAction extends AttachmentAction
$file = $e->file; $file = $e->file;
} }
if (!empty($thumb)) { try {
$filepath = $thumb->getPath(); if (!empty($thumb)) {
$filesize = 0; $filepath = $thumb->getPath();
} else { $size = 0;
$filepath = $file->getPath(); } elseif ($file->isLocal()) {
$filesize = $file->size; $filepath = $file->getPath();
$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);
} }
} }

View File

@ -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);
} }
} }

View File

@ -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?
} }

View File

@ -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

View File

@ -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;