diff --git a/.htaccess b/.htaccess
index c0ea1b7bb..ae3580590 100644
--- a/.htaccess
+++ b/.htaccess
@@ -39,3 +39,6 @@ RewriteRule ^([a-zA-Z0-9_]+)/([0-9]+)$ ./index.php?mid=$1&document_srl=$2 [L,QSA
# mid + entry title
RewriteRule ^([a-zA-Z0-9_]+)/entry/(.+)$ ./index.php?mid=$1&entry=$2 [L,QSA]
+
+# file download
+RewriteRule ^files/download/([0-9]+)/([a-zA-Z0-9_-]+)/(.+)$ ./index.php?act=procFileOutput&file_srl=$1&file_key=$2&filename=$3 [L]
diff --git a/common/framework/ua.php b/common/framework/ua.php
index 02c919b0e..d57463ea5 100644
--- a/common/framework/ua.php
+++ b/common/framework/ua.php
@@ -228,12 +228,6 @@ class UA
return $result;
}
}
- if ($result->os === 'Android' && preg_match('#^AndroidDownloadManager/([0-9])#', $ua, $matches))
- {
- $result->browser = 'Android';
- $result->version = $matches[1];
- return $result;
- }
if (preg_match('#Edge/([0-9]+\\.)#', $ua, $matches))
{
$result->browser = 'Edge';
@@ -341,14 +335,8 @@ class UA
// Get the browser name and version.
$browser = self::getBrowserInfo($ua);
- // Get the Android version.
- if ($browser->os === 'Android')
- {
- $android_version = preg_match('/Android ([0-9]+)/', $ua, $matches) ? intval($matches[1]) : 0;
- }
-
// Find the best format that this browser supports.
- if ($browser->browser === 'Chrome' && $browser->version >= 11 && !$browser->is_webview)
+ if ($browser->browser === 'Chrome' && $browser->version >= 11 & !$browser->is_webview)
{
$output_format = 'rfc5987';
}
@@ -374,14 +362,7 @@ class UA
}
elseif ($browser->browser === 'Android' || $browser->browser === 'Whale' || $browser->is_webview)
{
- if ($android_version >= 10)
- {
- $output_format = 'rfc5987';
- }
- else
- {
- $output_format = 'raw';
- }
+ $output_format = 'raw';
}
elseif ($browser->browser === 'Chrome' || $browser->browser === 'Safari')
{
diff --git a/common/manual/server_config/rhymix-nginx-subdir.conf b/common/manual/server_config/rhymix-nginx-subdir.conf
index 60dd89976..69b8ef0df 100644
--- a/common/manual/server_config/rhymix-nginx-subdir.conf
+++ b/common/manual/server_config/rhymix-nginx-subdir.conf
@@ -52,3 +52,6 @@ rewrite ^/rhymix/([a-zA-Z0-9_]+)/([0-9]+)$ /rhymix/index.php?mid=$1&document_srl
# mid + entry title
rewrite ^/rhymix/([a-zA-Z0-9_]+)/entry/(.+)$ /rhymix/index.php?mid=$1&entry=$2 last;
+
+# file download
+rewrite ^/rhymix/files/download/([0-9]+)/([a-zA-Z0-9_-]+)/(.+)$ /rhymix/index.php?act=procFileOutput&file_srl=$1&file_key=$2&filename=$3 last;
diff --git a/common/manual/server_config/rhymix-nginx.conf b/common/manual/server_config/rhymix-nginx.conf
index f4938457b..11aed6f3f 100644
--- a/common/manual/server_config/rhymix-nginx.conf
+++ b/common/manual/server_config/rhymix-nginx.conf
@@ -52,3 +52,6 @@ rewrite ^/([a-zA-Z0-9_]+)/([0-9]+)$ /index.php?mid=$1&document_srl=$2 last;
# mid + entry title
rewrite ^/([a-zA-Z0-9_]+)/entry/(.+)$ /index.php?mid=$1&entry=$2 last;
+
+# file download
+rewrite ^/files/download/([0-9]+)/([a-zA-Z0-9_-]+)/(.+)$ /index.php?act=procFileOutput&file_srl=$1&file_key=$2&filename=$3 last;
diff --git a/modules/file/file.admin.controller.php b/modules/file/file.admin.controller.php
index 417163e06..1f31ff0ab 100644
--- a/modules/file/file.admin.controller.php
+++ b/modules/file/file.admin.controller.php
@@ -130,6 +130,7 @@ class fileAdminController extends file
$config->allow_outlink = Context::get('allow_outlink');
$config->allow_outlink_format = Context::get('allow_outlink_format');
$config->allow_outlink_site = Context::get('allow_outlink_site');
+ $config->download_short_url = Context::get('download_short_url') === 'Y' ? 'Y' : 'N';
$config->inline_download_format = array_map('utf8_trim', Context::get('inline_download_format'));
// Save and redirect
diff --git a/modules/file/file.controller.php b/modules/file/file.controller.php
index 650be2778..cf9fb1f8e 100644
--- a/modules/file/file.controller.php
+++ b/modules/file/file.controller.php
@@ -384,7 +384,17 @@ class fileController extends file
$file_key_data = sprintf('%d:%d:%s:%s', $file_obj->file_srl, $file_key_timestamp, $file_obj->uploaded_filename, \RX_CLIENT_IP);
$file_key_sig = \Rhymix\Framework\Security::createSignature($file_key_data);
$file_key = dechex($file_key_timestamp) . $file_key_sig;
- header('Location: '.getNotEncodedUrl('', 'act', 'procFileOutput', 'file_srl', $file_srl, 'file_key', $file_key, 'force_download', Context::get('force_download') === 'Y' ? 'Y' : null));
+
+ // Use short URL or long URL
+ if ($file_module_config->download_short_url === 'Y' && config('use_rewrite'))
+ {
+ $url = RX_BASEURL . sprintf('files/download/%d/%s/%s', $file_srl, $file_key, rawurlencode($filename));
+ }
+ else
+ {
+ $url = getNotEncodedUrl('', 'act', 'procFileOutput', 'file_srl', $file_srl, 'file_key', $file_key, 'force_download', Context::get('force_download') === 'Y' ? 'Y' : null);
+ }
+ header('Location: ' . $url);
Context::close();
exit();
}
@@ -395,7 +405,8 @@ class fileController extends file
$oFileModel = getModel('file');
$file_srl = Context::get('file_srl');
$file_key = Context::get('file_key');
-
+ $filename_arg = Context::get('filename');
+
$columnList = array('source_filename', 'uploaded_filename', 'file_size');
$file_obj = $oFileModel->getFile($file_srl, $columnList);
$file_config = $oFileModel->getFileConfig($file_obj->module_srl ?: null);
@@ -441,7 +452,14 @@ class fileController extends file
}
// Encode the filename.
- $filename_param = Rhymix\Framework\UA::encodeFilenameForDownload($filename);
+ if ($filename_arg && $filename_arg === $filename)
+ {
+ $filename_param = '';
+ }
+ else
+ {
+ $filename_param = '; ' . Rhymix\Framework\UA::encodeFilenameForDownload($filename);
+ }
// Close context to prevent blocking the session
Context::close();
@@ -508,7 +526,7 @@ class fileController extends file
// Set filename headers
header('Content-Type: ' . ($download_type === 'inline' ? $mime_type : 'application/octet-stream'));
- header('Content-Disposition: ' . $download_type . '; ' . $filename_param);
+ header('Content-Disposition: ' . $download_type . $filename_param);
// Set cache headers
header('Cache-Control: private; max-age=3600');
diff --git a/modules/file/file.model.php b/modules/file/file.model.php
index 68db2ff5f..271dd325c 100644
--- a/modules/file/file.model.php
+++ b/modules/file/file.model.php
@@ -300,6 +300,7 @@ class fileModel extends file
$config->allowed_filetypes = $config->allowed_filetypes ?? '*.*';
$config->allow_outlink = $config->allow_outlink ?? 'Y';
$config->download_grant = $config->download_grant ?? [];
+ $config->download_short_url = $config->download_short_url ?? 'N';
$config->inline_download_format = $config->inline_download_format ?? [];
$config->image_autoconv = $config->image_autoconv ?? [];
$config->image_quality_adjustment = $config->image_quality_adjustment ?? 75;
diff --git a/modules/file/lang/en.php b/modules/file/lang/en.php
index ec203e106..f2578e730 100644
--- a/modules/file/lang/en.php
+++ b/modules/file/lang/en.php
@@ -18,6 +18,7 @@ $lang->allow_outlink_format = 'Allowed Formats';
$lang->allowed_filesize = 'Maximum File Size';
$lang->allowed_attach_size = 'Maximum Attachments';
$lang->allowed_filetypes = 'Allowed extentsions';
+$lang->download_short_url = 'Use short URL';
$lang->inline_download_format = 'Open in current window';
$lang->inline_download_image = 'Image';
$lang->inline_download_audio = 'Audio';
@@ -27,6 +28,7 @@ $lang->inline_download_pdf = 'PDF';
$lang->file_save_changelog = 'Save changelog';
$lang->use_default_file_config = 'Use Default Settings';
$lang->about_use_default_file_config = 'Follow the default settings from the File module.';
+$lang->about_download_short_url = 'Using short URLs can fix broken filenames in Android and some other platforms.
Short URLs must be enabled, and rewrite rules must be updated to the latest version if you use nginx.';
$lang->about_inline_download_format = 'Selected types of files will be opened in the current window instead of a download dialog when a user clicks the download link.';
$lang->enable_download_group = 'Downloadable Groups';
$lang->about_allow_outlink = 'Allow other websites to link directly to your download URLs.
Rhymix does not control links to image files that can be embedded directly in a document.
in order to block external links to such images, you may need to modify your web server configuration.';
@@ -101,4 +103,4 @@ $lang->about_video_mp4_gif_time = 'treat silent MP4 videos with duration less th
$lang->ffmpeg_path = 'FFmpeg path';
$lang->ffprobe_path = 'FFprobe path';
$lang->msg_cannot_use_ffmpeg = 'FFmpeg and FFprobe must can be executed by PHP.';
-$lang->msg_cannot_use_exif = 'PHP Exif module is required.';
\ No newline at end of file
+$lang->msg_cannot_use_exif = 'PHP Exif module is required.';
diff --git a/modules/file/lang/ko.php b/modules/file/lang/ko.php
index ace8d7242..8e64ff63a 100644
--- a/modules/file/lang/ko.php
+++ b/modules/file/lang/ko.php
@@ -18,6 +18,7 @@ $lang->allow_outlink_format = '외부 접근 허용 확장자';
$lang->allowed_filesize = '파일 용량 제한';
$lang->allowed_attach_size = '문서 첨부 제한';
$lang->allowed_filetypes = '허용 확장자';
+$lang->download_short_url = '다운로드시 짧은주소 사용';
$lang->inline_download_format = '다운로드시 현재 창 사용';
$lang->inline_download_image = '이미지';
$lang->inline_download_audio = '오디오';
@@ -27,6 +28,7 @@ $lang->inline_download_pdf = 'PDF';
$lang->file_save_changelog = '변경 내역 기록';
$lang->use_default_file_config = '기본 파일 설정 사용';
$lang->about_use_default_file_config = '파일 모듈의 기본 설정을 따릅니다.';
+$lang->about_download_short_url = '안드로이드 등 일부 환경에서 첨부파일 다운로드시 파일명이 깨지는 문제를 해결할 수 있습니다.
짧은주소 사용이 활성화되어 있어야 하며, nginx 사용시 rewrite 규칙을 최신 버전으로 업데이트하여야 합니다.';
$lang->about_inline_download_format = '선택한 종류의 파일은 다운로드 링크를 클릭하더라도 다운로드 창을 열지 않고 현재 창에 표시합니다.';
$lang->enable_download_group = '다운로드 가능 그룹';
$lang->about_allow_outlink = '다른 사이트에서 파일 다운로드 링크에 직접 접근하는 것을 허용합니다.
본문에 바로 삽입할 수 있는 이미지 파일은 라이믹스에서 접근을 통제할 수 없으며, 이를 차단하려면 웹서버 설정이 필요합니다.';
diff --git a/modules/file/tpl/download_config.html b/modules/file/tpl/download_config.html
index 16493d05e..74902252c 100644
--- a/modules/file/tpl/download_config.html
+++ b/modules/file/tpl/download_config.html
@@ -30,6 +30,14 @@
{$lang->about_allow_outlink_site}
+{$lang->about_download_short_url}
+