英文:
PHP - create a download script to avoid direct html links in WordPress
问题
在我的WordPress插件中,我在受限制的文件夹中创建了一个文件。
如何编写一个下载脚本,以将其作为HTML非直接链接提供?
换句话说,我希望文件的真实路径不会显示在链接的“href”上,而是从后端函数中检测并添加。
前端HTML可能如下所示:
<a href="/download?fn=filename.ext">下载我的文件</a>
但真实的文件路径/名称将是“/restriced-dir/filename.ext”。
英文:
In my WordPress plugin I create a file in a restricted folder.
How is possible to produce a download script to serve it as html not-direct link?
In other words I want the real path of the file not to be showed on the "href" of a link, but to be detected and added from a backend function.
The frontend html would be something like:
<a href="/download?fn=filename.ext">Download my file</a>
But the teal file path/name would be "/restriced-dir/filename.ext".
答案1
得分: 1
最终我自己解决了这个问题。
在我的插件中,我创建了一个"脏"的自定义终端点,用于服务于受限文件夹中的任何现有文件(位于非公开位置)。
定义( 'RESTRICTED_DOWNLOAD_DIR', '/restricted-dir/' );
添加动作( 'parse_request', 'parse_request_endpoint' );
function parse_request_endpoint($wp) {
// 终端点URL
$endpoint="download";
if ( $endpoint == $wp->request ) {
@$fn=sanitize_file_name($_GET["fn"]);//出于安全原因建议这样做
$filename=RESTRICTED_DOWNLOAD_DIR.$fn;
if(is_file($filename)){
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'. basename($filename) . '"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($filename));
readfile($filename);
unlink($filename);//如果只提供一次服务
exit;
}
}
}
然后我可以使用一个函数来生成HTML输出,并从代码或短代码中调用它:
function my_file_link(){
$filename="myfile.ext";//这个文件必须存在于RESTRICTED_DOWNLOAD_DIR中
$html="<a href=\"/download?fn=$filename\">Download my file</a>";
return $html;
}
这样,如果找到文件,则会下载,但如果在没有正确参数的情况下调用URL,WordPress将显示404页面。可以通过在下载终端点中添加阻止逻辑来改进解决方案。
英文:
In the end I solved the problem by myself.
In my plugin I've created a "dirty" custom endpoint to serve any existing file from a restricted folder (in a non-public location).
define( 'RESTRICTED_DOWNLOAD_DIR', '/restricted-dir/' );
add_action( 'parse_request', 'parse_request_endpoint' );
function parse_request_endpoint($wp) {
//endpoint url
$endpoint="download";
if ( $endpoint == $wp->request ) {
@$fn=sanitize_file_name($_GET["fn"]);//As from suggestion for security reasons
$filename=RESTRICTED_DOWNLOAD_DIR.$fn;
if(is_file($filename)){
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . basename($filename) . '"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($filename));
readfile($filename);
unlink($filename);//If served just once
exit;
}
}
}
Then I can use a function for the html output ant call it from code or shortcode:
function my_file_link(){
$filename="myfile.ext";//this file must exist in RESTRICTED_DOWNLOAD_DIR
$html="<a href=\"/download?fn=$filename\">Download my file</a>";
return $html;
}
This way if the file is found gets downloaded but if the url is called without the right parameter WordPress will show a 404 page. The solution could be improved adding a blocking logic in download endpoint.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论