xsendfile работает только из индекса - PullRequest
0 голосов
/ 20 сентября 2011

Я пытаюсь отправить файл пользователю с помощью 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-адрес запроса, который Я нахожу странным.

Итак ... есть ли у кого-нибудь какие-либо предложения относительно того, как я могу заставить xsendfile работать через codeigniter, с URL-адреса, такого как "domain.com/files/get/12"?

?"

Ответы [ 4 ]

0 голосов
/ 01 июня 2016

XSendFile имеет некоторые специфические особенности безопасности, связанные с путями ... и в зависимости от конфигурации вашего сервера эти проблемы могут иногда возникать по HTTPS, даже если кажется, что HTTP работает правильно.

Если вы сталкиваетесь с таинственными 404 при использовании mod_xsendfile и можете подтвердить, что обслуживаемые файлы действительно существуют, то вам, вероятно, нужно настроить XSendFilePath в ваших настройках Apache.

Добавьте следующее в соответствующий conf (httpd.conf, ssl.conf, httpd-ssl.conf и т. Д.) И / или внутри соответствующего объявления VirtualHost (если используется vhosts) ...

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

Примечание: вы не можете добавить это в файл .htaccess. Это должно быть помещено в Apache conf.

Обычно xsendfile пытается определить рабочий каталог автоматически, но иногда это не удается. Эта директива в явном виде сообщает, какой каталог (или директор i * ) должен быть доступен через xsendfile. Скорее всего, таинственный 404 означает, что ваш каталог по какой-то причине не проходит проверку белого списка. Это исправит это.

И не забудьте перезагрузить apache после изменения конфигурации.

0 голосов
/ 24 сентября 2011

Кажется, этот ответ так и не получил ответа, в конце концов, я просто создал в своем корне файл с именем "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']);
}
?>
0 голосов
/ 03 января 2012

Сегодня я столкнулся с ошибкой 404. Если путь, который вы передаете заголовку, содержит какие-либо компоненты, которые находятся за пределами корневой папки, в которой находится index.php, то вы получите 404. Убедитесь, что путь относительно к index.php, а не абсолютный путь.

0 голосов
/ 20 сентября 2011

Префикс имени метода с подчеркиванием делает его недоступным через URL.

Из документации:

Частные функции

В некоторых случаях вы можете захотеть скрыть определенные функции от публичного доступа.Чтобы сделать функцию закрытой, просто добавьте подчеркивание в качестве префикса имени, и оно не будет обрабатываться через URL-запрос.Например, если бы у вас была такая функция:

private function _utility()
{
    // some code
}

Попытка получить к ней доступ через URL, например, не будет работать: example.com/index.php/blog/_utility/

...