xsendfile仅适用于索引

时间:2011-09-20 11:44:09

标签: codeigniter codeigniter-2 x-sendfile

我正在尝试使用代码点火器框架中的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的顶部并加载root它工作正常,但如果我尝试从domain.com/controller/function访问它,它会返回404错误。

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

我认为这与xsendfile访问该文件的权限有关,但由于它是从root index.php开始工作的,我原以为它会拥有完整的权限,大概是基于请求网址是什么,哪个我觉得很奇怪。

所以....有没有人有任何关于我如何通过codeigniter从“domain.com/files/get/12”等网址获取xsendfile的建议?

4 个答案:

答案 0 :(得分:0)

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

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

将以下内容添加到相应的conf(XSendFilePathhttpd.confssl.conf等)和/或相应的VirtualHost声明中(如果使用vhosts)...

httpd-ssl.conf

注意:您 无法 将其添加到XSendFilePath /Absolute/Path/To/Your/Working/Directory/ 文件中。 必须 放入Apache conf。

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

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

答案 1 :(得分:-1)

使用下划线添加方法名称会使其无法通过URL访问。

来自文档:

<强> Private Functions

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

private function _utility()
{
    // some code
}

尝试通过网址访问它,就像这样,不起作用:example.com/index.php/blog/_utility/

答案 2 :(得分:-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']);
}
?>

答案 3 :(得分:-1)

我今天遇到了404错误。如果传递给标题的路径包含位于index.php所在的根文件夹之外的任何组件,那么您将获得404.确保路径 relative 到index.php,而不是一条绝对的道路。