【问题标题】:PHP display/download directory files outside the webserver rootPHP 显示/下载网络服务器根目录外的目录文件
【发布时间】:2011-05-21 21:35:25
【问题描述】:

我已经下载并添加了这个非常简单的一个文件,php web 文件浏览器系统(称为Indexer)到我的 XAMPP 服务器。

我的 XAMMP 服务器在我的 C: 驱动器上,但我希望 Indexer 在我的 G: 驱动器上显示一个目录。但是当我改变(我认为是)正确的配置变量时,它就不能正常工作了。

这是我认为与问题有关的代码:

// configuration  
$Root = realpath("G:/test");  
$AllowDownload = TRUE;  
$WebServerPath = dirname("G:/test");

以及稍后在代码中...

elseif ($AllowDownload) {  

        echo "<a href=\"http://".getenv("SERVER_NAME").$WebServerPath."/$rel_path".$item["filename"]."\">".$item["name"]."</a>";
    }

会发生这种情况:脚本 确实 正确显示了 G: 驱动器上“test”目录的内容,但是当我单击文件名时,要下载/查看文件,链接坏了,因为 php 构造了错误的链接(我想)。 链接如下所示:http://localhostg//[文件名]。

你知道如何解决这个问题吗?

如果我更改配置变量以显示相对子目录的内容,此脚本将完美运行。它还说 $Root 变量可以位于网络服务器根目录之外。

此外,即使单击链接不起作用,右键单击并选择“目标另存为”允许我保存/下载文件。

(如果您需要更多信息,请随时询问):)

【问题讨论】:

    标签: php html directory


    【解决方案1】:

    您的网络服务器无法看到 DocRoot 之外的文件,因此它无法通过浏览器提供带有直接链接的文件。您需要使用 readfile() 将它们的内容打印到浏览器中,并正确设置标题。

    要完成这项工作,您需要更改 indexer.php 中的配置:

    // this way it works with accentuated letters in Windows
    $Root = utf8_decode("G:\test"); // define the directory the index should be created for (can also be located outside the webserver root)
    
    $AllowDownload = TRUE; // enclose file items with the anchor-tag (only makes sense when the files are in the webserver root)
    // you need to place download.php in the same directory as indexer.php
    $WebServerPath = dirname($_SERVER['SCRIPT_NAME']) . "/download.php?path="; // path where the indexed files can be accessed via a http URL (only required when $AllowDownload is TRUE)
    

    你必须将一个名为download.php的新文件放在与indexer.php相同的目录中,内容如下:

    <?php
    
    // it must be the same as in indexer.php
    $Root = utf8_decode("G:\test");
    
    function checkFileIsInsideRootDirectory($path, $root_directory) {
        $realpath = realpath($path);
    
        if (!file_exists($realpath))
            die("File is not readable: " . $path);
    
        // detects insecure path with for example /../ in it
        if (strpos($realpath, $root_directory) === false || strpos($realpath, $root_directory) > 0)
            die("Download from outside of the specified root directory is not allowed!");
    }
    
    function forceDownload($path) {
        $realpath = realpath($path);
    
        if (!is_readable($realpath))
            die("File is not readable: " . $path);
    
        $savename = (basename($path));
    
        header("Pragmaes: 0");
        header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
        header("Cache-Control: private", false);
        header("Content-type: application/force-download");
        header("Content-Transfer-Encoding: Binary");
        header("Content-length: " . filesize($path));
        header("Content-disposition: attachment; filename=\"$savename\"");
    
        readfile("$path");
        exit;
    }
    
    if (!isset($_GET['path']))
        die("Path not specified!");
    
    $fullPath = $Root . $_GET['path'];
    
    checkFileIsInsideRootDirectory($fullPath, $Root);
    
    forceDownload($fullPath);
    

    【讨论】:

    • 感谢您的回答!这听起来很有希望;我需要把这段代码放在哪里(我需要更改任何变量名)吗?
    • 编辑了我的答案,现在它适用于indexer
    • 感谢您一直以来的支持:)我应该把代码放在哪里,需要替换什么?
    • @Jopper 正如我写的,您只需要更改 indexer.php 中的配置参数(实际上只需更改 $WebServerPath 即可破解下载 url),并且您需要创建一个新的 php处理下载的脚本,它必须根据$webServerPath的值命名(在本例中为download.php)。
    • 也可以将两个文件合二为一,不过这样好像更简单(而且我不想修改indexer.php)。
    【解决方案2】:

    您必须更改您的 apache 配置。问题不在于 php 脚本,而在于网络服务器(它无法在网络根目录之外提供文件,除非您将其配置为)。

    在你的 apache 配置中尝试这样的事情:

    Alias /testalias "G:/test"
    <Directory "G:/test">
      Options Indexes FollowSymLinks MultiViews ExecCGI
      AllowOverride All
      Order allow,deny
      Allow from all
    </Directory>
    

    这告诉 Apache 在您访问 http://localhost/testalias 时从 G:/test 提供文件

    然后像这样更改您的脚本配置:

    $WebServerPath = dirname("testalias");
    

    它应该可以工作!

    【讨论】:

    • 我在 XAMPP Apache config (conf) 文件夹中找到了一个名为“httpd.conf”的文件。我想这是正确的文件,但我只是将代码(从您的第一个代码框)粘贴到该文件中,还是覆盖某些内容?另外,我是否需要将“testalias”的名称更改为 Indexer.php 文件所在文件夹的名称?
    • 只是一个建议:它可以正常工作,除非您的意图是保护您​​的文件(将它们从 webroot 中删除)。
    【解决方案3】:

    让我们看看那个脚本:

    $Root = realpath("."); // define the directory the index should be created for (can also be located outside the webserver root)
    $AllowDownload = TRUE; // enclose file items with the anchor-tag (only makes sense when the files are in the webserver root)
    $WebServerPath = dirname(getenv("SCRIPT_NAME")); // path where the indexed files can be accessed via a http URL (only required when $AllowDownload is TRUE)
    

    注意“仅当文件位于网络服务器根目录中时才有意义”和“可以通过 http URL 访问索引文件的路径”。这表明此脚本并非旨在下载 Web 服务器根目录之外的文件。

    但是,您可以修改此脚本,以便能够按照 styu 在他的回答中指出的方式执行此操作。然后,您可以将更改发送给脚本的作者。

    顺便说一句,我在自己的服务器上对此进行了测试。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-13
      相关资源
      最近更新 更多