如何下载访问public_html目录以外的文件?

时间:2012-04-22 23:00:56

标签: php .htaccess redirect

为了安全起见,我将文件存储在public_html文件夹之外。但是,我想以某种方式链接到特定文件,用户可以下载其中一个文件。

我正在使用一个jquery脚本,它允许我将服务器PATH指定为上传文件夹,并且它会在public_html文件夹之外上传。

唯一的问题是它要求我指定用于下载文件的“上传路径”的URL。我想我可以做类似的事情:

public_html/redirect (contains htaccess which forwards all requests to "hiding" folder)

hiding (outside public_html)

A user clicks /redirect/file.doc and they download a file located at hiding/file.doc

这可能吗?如果没有,我如何给我的public_html目录之外的文件提供特定的文件下载访问权限?我知道我之前在其他脚本上已经看过它...

3 个答案:

答案 0 :(得分:8)

您可以使用“php download handler”:

执行此操作

您可以使用这样的方法将文件内容和文件信息标题返回给用户浏览器,只需确保在此之前没有输出任何其他内容。

我建议你把它放在单独的文件中并调用它,例如download.php

function returnFile( $filename ) {
    // Check if file exists, if it is not here return false:
    if ( !file_exists( $filename )) return false;
    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    // Suggest better filename for browser to use when saving file:
    header('Content-Disposition: attachment; filename='.basename($filename));
    header('Content-Transfer-Encoding: binary');
    // Caching headers:
    header('Expires: 0');
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    header('Pragma: public');
    // This should be set:
    header('Content-Length: ' . filesize($filename));
    // Clean output buffer without sending it, alternatively you can do ob_end_clean(); to also turn off buffering.
    ob_clean();
    // And flush buffers, don't know actually why but php manual seems recommending it:
    flush();
    // Read file and output it's contents:
    readfile( $filename );
    // You need to exit after that or at least make sure that anything other is not echoed out:
    exit;
}

将其扩展为基本用途:

// Added to download.php
if (isset($_GET['file'])) {
    $filename = '/home/username/public_files/'.$_GET['file'];
    returnFile( $filename );
}

警告:

这是一个基本的例子,没有考虑到用户可能会尝试使用未正确消毒的$_GET的某些邪恶优势。

这意味着,如果某些条件适用,基本上用户可以检索passwd文件或其他一些敏感信息。

例如,检索/etc/passwd

只需将浏览器指向http://server.com/download.php?file=../../../etc/passwd,服务器就会返回该文件。因此,在实际使用之前,您应该了解如何正确检查和清理任何用户提供的参数。

答案 1 :(得分:1)

public_html以外的路径无法使用。

mod_rewrite仅重写请求,但路径仍然可供用户使用。

答案 2 :(得分:0)

另一种标准方法是使用mod_xsendfile - 它允许Web应用程序让Web服务器通过在标头(X-SendFile)中指定路径来发送文件作为其输出。