Symfony Принудительно загружает ответные текстовые файлы


Я создал функцию для своего приложения Symfony на основе этого ответа: https://stackoverflow.com/a/13025363/1749653

Функция такова:

public function getForceDownloadResponse($file_path, $file_name){
    $file_info = finfo_open(FILEINFO_MIME_TYPE);
    $mine_type = finfo_file($file_info, $file_path.$file_name);
    finfo_close($file_info);

    $response = new Response();
    $response->headers->set('Cache-Control', 'private');
    $response->headers->set('Content-type', $mine_type);
    $response->headers->set('Content-Disposition', 'attachment; filename="' . $file_name . '"');
    $response->headers->set('Content-length', filesize($file_path.$file_name));

    $response->sendHeaders();
    $response->setContent(readfile($file_path.$file_name));

    return $response;
}

И все это сработало довольно хорошо... пока кто-то не попытался загрузить с него текстовый файл. По какой-то причине все текстовые файлы загружаются с неправильным именем файла. Все они следуют этой схеме: Фактическое имя_файла-, вложение так, например: new_text.txt -,приложение и т. Д.

После некоторого расследование Я обнаружил только одну ошибку в текстовых файлах в целом. Каким-то образом поля заголовка ответа дублируются. Где двоичные файлы будут выводить что-то вроде этого:

Cache-Control:private
Connection:close
Content-Disposition:attachment; filename="Jellyfish.jpg"
Content-Length:775702
Content-Type:image/jpeg
Date:Mon, 10 Nov 2014 09:14:41 GMT
Server:Apache/2.4.7 (Win32) OpenSSL/1.0.1e PHP/5.5.6

Любой текстовый файл будет выглядеть следующим образом:

Cache-Control:private
Cache-Control:private
Connection:Keep-Alive
Content-Disposition:attachment; filename="full.txt"
Content-Disposition:attachment; filename="full.txt"
Content-Length:15
Content-Type:text/plain; charset=UTF-8
Date:Mon, 10 Nov 2014 09:06:00 GMT
Keep-Alive:timeout=5, max=97
Server:Apache/2.4.7 (Win32) OpenSSL/1.0.1e PHP/5.5.6

Я подозреваю, что непреднамеренное поведение коренится где-то в том, что вызывает такое поведение заголовка содержимого. Но я ни за что на свете не могу понять, как это происходит.

Итак, если кто-нибудь знает больше о том, как они создаются, что может их вызвать чтобы вести себя так или даже как решить проблему напрямую, любая помощь была бы очень признательна.

Author: Community, 2014-11-10

1 answers

Наконец-то понял это. Разместите его здесь на случай, если у кого-то где-то возникнет аналогичная проблема и он сочтет ее полезной:

Итак. Оказывается, проблемная строка была такой:

$response-sendHeaders()

Для двоичных файлов эта строка имеет решающее значение для обеспечения его работы. Текстовые файлы в этом не нуждаются и на самом деле будут ломаться, как показано выше. Я не выяснил точно, "почему" он ведет себя так. Но решение состояло в том, чтобы просто проверить, является ли запрошенный файл текстовым файлом или нет. (с помощью встроить исключение для файлов .html, но это скорее дополнительная функция/особенность проекта, и поэтому ее можно безопасно игнорировать)

Вот как выглядит функция сейчас, и она работает нормально:

public function getForceDownloadResponse($file_path, $file_name){
    $file_info = finfo_open(FILEINFO_MIME_TYPE);
    $mime_type = finfo_file($file_info, $file_path.$file_name);
    $text = (substr(finfo_file($file_info, $file_path.$file_name), 0, 4) == 'text') ? 1 : 0;
    finfo_close($file_info);

    $response = new Response();
    $response->headers->set('Cache-Control', 'private');
    $response->headers->set('Content-type', $mime_type);
    $response->headers->set('Content-Disposition', 'attachment; filename="' . $file_name . '"');
    $response->headers->set('Content-length', filesize($file_path.$file_name));

    if(!$text || $mime_type == 'text/html'){
        $response->sendHeaders();
    }

    $response->setContent(readfile($file_path.$file_name));

    return $response;
}

Поскольку я до сих пор не знаю, что на самом деле вызвало различное поведение, оно не так безопасно и надежно, как мне бы хотелось, но пока оно отлично справляется со своей работой.

 0
Author: C.Funken, 2014-11-11 09:56:17