xsendfile 仅适用于索引

问题描述 投票:0回答:4

我正在尝试在代码点火器框架内使用 xsendfile 向用户发送文件。

一切都安装正确,我的问题是它似乎只能从路由中工作,即使每个页面都来自index.php。

这是我的职责:

function _output_file($name, $root_location, $public_location = FALSE)
{
    if (function_exists('apache_get_modules') && in_array('mod_xsendfile', apache_get_modules())) {
        header ('Content-Description: File Transfer');
        header ('Content-Type: application/octet-stream');
        if (strstr($_SERVER["HTTP_USER_AGENT"], "MSIE") != FALSE) {
            header ('Content-Disposition: attachment; filename='.urlencode($name));
        } else {
            header ('Content-Disposition: attachment; filename="'.$name.'"');
        }
        //86400 is one day
        header ('Expires: '.gmdate('D, d M Y H:i:s', (TIME_NOW + 86400)));
        header ('Cache-Control: must-revalidate, post-check=0, pre-check=0');
        header ('Pragma: public');
        header ('X-Sendfile: '.$root_location);
        exit;
    } else {
        redirect(site_url($public_location));
    }
}

如果我将其放在 index.php 的顶部并加载根目录,它工作正常,但如果我尝试从domain.com/controller/function 访问它,它会返回 404 错误。

它肯定使用了index.php文件,因为如果我用die(“test”)替换函数调用;这会显示在屏幕上。

我相信这与 xsendfile 必须访问该文件的权限有关,但由于它是从根 index.php 工作的,所以我认为它具有完整的权限,大概它是基于我发现的请求 url 的内容奇怪。

那么....是否有人对我如何从“domain.com/files/get/12”等网址通过 codeigniter 让 xsendfile 工作有任何建议?

php codeigniter codeigniter-2 x-sendfile
4个回答
0
投票

XSendFile 具有一些特定的与安全相关的路径怪癖...并且根据您的服务器配置,即使 HTTP 似乎工作正常,这些问题有时也可能通过 HTTPS 发生。

如果您在使用 mod_xsendfile 时遇到神秘的 404,并且您可以确认所提供的文件确实存在,那么您可能需要在 Apache confs 中配置

XSendFilePath

将以下内容添加到适当的conf(

httpd.conf
ssl.conf
httpd-ssl.conf
等)和/或适当的VirtualHost声明中(如果使用虚拟主机)...

XSendFilePath /Absolute/Path/To/Your/Working/Directory/

注意:您不能将其添加到

.htaccess
文件中。它必须放入Apacheconf中。

一般情况下,xsendfile 会尝试自动找出工作目录,但有时却不能。该指令明确告诉它应该通过 xsendfile 访问哪个目录(或directories)。神秘的 404 很可能意味着您的目录由于某种原因未通过白名单检查。这将解决这个问题。

更改配置后不要忘记重新启动 apache。


-1
投票

在方法名称前添加下划线将使其无法通过 URL 访问。

来自文档:

私有功能

在某些情况下,您可能希望某些功能对公众隐藏。要使函数私有,只需添加下划线作为名称前缀,它将不会通过 URL 请求提供服务。例如,如果你有一个这样的函数:

private function _utility()
{
    // some code
}

尝试通过 URL 访问它,就像这样,是行不通的:

example.com/index.php/blog/_utility/


-1
投票

这个答案似乎从未得到回应,最后我只是在我的根目录中创建了一个名为“getfile.php”的文件,它并不完美,但它暂时完成了工作,这里适合任何可能觉得它有用的人.

<?php
define('BASEPATH', 'just done to stop direct access being disallowed');

function show_getfile_error()
{
    echo 'You do not have permission to download this file, if you think this is a mistake please get in contact.';
    exit;
}

include('applications/config/database.php');
$mysqli = new mysqli($db['default']['hostname'], $db['default']['username'], $db['default']['password'], $db['default']['database']);
if(!preg_match('%^[0-9]+$%', $_GET['key']))
{
    show_getfile_error();
}
else
{
    $query = mysqli_query($mysqli, 'SELECT * FROM getfiles WHERE getfile_key = '.(int)$_GET['key']);

    $result = mysqli_fetch_array($query, MYSQLI_ASSOC);

    if(!$result || $result['getfile_ip'] != $_SERVER['REMOTE_ADDR'])
    {
        show_getfile_error();
    }

    header ('Content-Description: File Transfer');
    header ('Content-Type: application/octet-stream');
    if (strstr($_SERVER["HTTP_USER_AGENT"], "MSIE") != FALSE) {
        header ('Content-Disposition: attachment; filename='.urlencode($result['getfile_name']));
    } else {
        header ('Content-Disposition: attachment; filename="'.$result['getfile_name'].'"');
    }
    //86400 is one day
    header ('Expires: '.gmdate('D, d M Y H:i:s', (TIME_NOW + 86400)));
    header ('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    header ('Pragma: public');
    header ('X-Sendfile: '.$result['getfile_location']);
}
?>

-1
投票

我今天遇到了 404 错误。如果传递给标头的路径包含位于 index.php 所在根文件夹之外的任何组件,则会收到 404。确保该路径是相对于 index.php 的路径,而不是绝对路径。

© www.soinside.com 2019 - 2024. All rights reserved.