*/
static function sendFile(string $filepath, $filesize) {
if (is_string(common_config('site', 'x-static-delivery'))) {
- $relative_path = end(explode(INSTALLDIR, $filepath));
+ $tmp = explode(INSTALLDIR, $filepath);
+ $relative_path = end($tmp);
common_debug("Using Static Delivery with header: '" .
common_config('site', 'x-static-delivery') . ": {$relative_path}'");
header(common_config('site', 'x-static-delivery') . ": {$relative_path}");
}
} else {
try {
- return File_thumbnail::byFile($this)->getPath();
+ return File_thumbnail::byFile($this, true)->getPath();
} catch (NoResultException $e) {
// File not stored locally
throw new FileNotStoredLocallyException($this);
{
if (!empty($thumbnail)) {
$filepath = $thumbnail->getPath();
- } elseif (empty($this->filename)) {
- $filepath = File_thumbnail::byFile($this)->getPath();
- } else {
+ } elseif (!empty($this->filename)) {
return $this->mimetype;
+ } else {
+ $filepath = File_thumbnail::byFile($this, true)->getPath();
}
$info = @getimagesize($filepath);
*/
public function getHtmlAttrs(array $orig=array(), $overwrite=true)
{
- $attrs = [
- 'height' => $this->getHeight(),
- 'width' => $this->getWidth(),
- 'src' => $this->getUrl(),
- ];
+ $attrs = [ 'height' => $this->getHeight(),
+ 'width' => $this->getWidth(),
+ 'src' => $this->getUrl() ];
return $overwrite ? array_merge($orig, $attrs) : array_merge($attrs, $orig);
}
} while ($maxRedirs);
return new GNUsocial_HTTPResponse($response, $this->getUrl(), $redirs);
}
+
+ public static function get_filename(string $url, array $headers = null) : string {
+ if ($headers === null) {
+ $head = (new HTTPClient())->head($url);
+ $headers = $head->getHeader();
+ $headers = array_change_key_case($headers, CASE_LOWER);
+ }
+ if (array_key_exists('content-disposition', $headers) &&
+ preg_match('/^.+; filename="(.+?)"$/', $headers['content-disposition'], $matches) === 1) {
+ return $matches[1];
+ } else {
+ common_log(LOG_INFO, "Couldn't determine filename for url: {$url}");
+ return _('Untitled attachment');
+ }
+ }
}
}
// And we'll only consider it an image if it has such a media type
- switch ($media) {
- case 'image':
- $imgPath = $file->getPath();
- break;
- default:
+ if($media !== 'image') {
throw new UnsupportedMediaException(_m('Unsupported media format.'), $file->getPath());
+ } else if (!empty($file->filename)) {
+ $imgPath = $file->getPath();
}
}
$type = $this->preferredType();
$ext = image_type_to_extension($type, true);
- $outpath = preg_replace("/\.[^\.]+$/", $ext, $outpath);
+ // Decoding returns null if the file is in the old format
+ $filename = MediaFile::decodeFilename(basename($outpath));
+ // Encoding null makes the file use 'untitled', and also replaces the extension
+ $outfilename = MediaFile::encodeFilename($filename, $this->filehash, $ext);
+ $outpath = dirname($outpath) . DIRECTORY_SEPARATOR . $outfilename;
switch ($type) {
case IMAGETYPE_GIF:
return $thumb;
}
- $filename = basename($this->filepath);
$extension = File::guessMimeExtension($this->mimetype);
- $outname = "thumb-{$this->fileRecord->getID()}-{$width}x{$height}-{$filename}";
+ $outname = "thumb-{$this->fileRecord->getID()}-{$width}x{$height}-{$this->filename}";
$outpath = File_thumbnail::path($outname);
// The boundary box for our resizing
));
// Perform resize and store into file
- $this->resizeTo($outpath, $box);
-
- try {
- // Avoid deleting the original
- if (!in_array($this->getPath(), [File::path($this->filename), File_thumbnail::path($this->filename)])) {
- $this->unlink();
- }
- } catch (FileNotFoundException $e) {
- // $this->getPath() says the file doesn't exist anyway, so no point in trying to delete it!
- }
+ $outpath = $this->resizeTo($outpath, $box);
+ $outname = basename($outpath);
return File_thumbnail::saveThumbnail(
$this->fileRecord->getID(),
* having an extension in the file, removing trust in extensions, while keeping the original name
* @throws ClientException
*/
- public static function encodeFilename(string $original_name, string $filehash, string $ext = null) : string
+ public static function encodeFilename($original_name, string $filehash, $ext = null) : string
{
if (empty($original_name)) {
$original_name = _('Untitled attachment');
*/
public static function decodeFilename(string $encoded_filename)
{
- $ret = preg_match('/^([^-]+?)-[^-]+$/', $encoded_filename, $matches);
+ // The x is because it is using in thumbnails
+ $ret = preg_match('/^([^-x]+?)-[^-]+$/', $encoded_filename, $matches);
if ($ret === false) {
return false;
} elseif ($ret === 0) {
} elseif ($filename === null) {
// The old file name format was "{hash}.{ext}" so we didn't have a name
// This extracts the extension
- $ret = preg_match('/^.+?\.(.+)$/', $file->filename, $matches);
+ $ret = preg_match('/^.+?\.+?(.+)$/', $file->filename, $matches);
if ($ret !== 1) {
common_log(LOG_ERR, $log_error_msg);
return _('Untitled attachment');
'unnecessarily downloading too large files. URL: %s',
$file->getID(), $remoteUrl));
+ $url = $remoteUrl;
$head = $http->head($remoteUrl);
$remoteUrl = $head->getEffectiveUrl(); // to avoid going through redirects again
+
+ if (empty($remoteUrl)) {
+ common_log(LOG_ERR, "URL after redirects is somehow empty, for URL {$url}");
+ return true;
+ }
+
if (!$this->checkBlackList($remoteUrl)) {
common_log(LOG_WARN, sprintf('%s: Non-blacklisted URL %s redirected to blacklisted URL %s',
__CLASS__, $file->getUrl(), $remoteUrl));
}
$headers = $head->getHeader();
+ $headers = array_change_key_case($headers, CASE_LOWER);
$filesize = isset($headers['content-length']) ?: $file->getSize();
if (empty($filesize)) {
//FIXME: Add some code so we don't have to store duplicate File rows for same hash files.
} catch (NoResultException $e) {
- if (preg_match('/^.+; filename="(.+?)"$/', $headers['content-disposition'], $matches) === 1) {
- $filename = MediaFile::encodeFilename($matches[1], $filehash);
- } else {
- common_log(LOG_ERR, "Couldn't determine filename for url: {$remoteUrl}");
- // throw new ServerError(_("Couldn't determine filename for url: {$remoteUrl}"));
- }
+ $original_name = HTTPClient::get_filename($remoteUrl, $headers);
+ $filename = MediaFile::encodeFilename($original_name, $filehash);
$fullpath = File::path($filename);
- common_debug("StoreRemoteMedia retrieved file with id={$file->id} and will store in {$filename}");
+ common_debug("StoreRemoteMedia retrieved url {$remoteUrl} for file with id={$file->id} " .
+ "and will store in {$fullpath}");
// Write the file to disk if it doesn't exist yet. Throw Exception on failure.
- if (!file_exists($fullpath) && file_put_contents($fullpath, $imgData) === false) {
+ if ((!file_exists($fullpath) || substr($fullpath, 0, strlen(INSTALLDIR)) != INSTALLDIR) &&
+ file_put_contents($fullpath, $imgData) === false) {
throw new ServerException(_('Could not write downloaded file to disk.'));
}