Страница 1 из 1

CHttpRequest::sendFile()

Добавлено: 2011.06.24, 14:02
Yiivgeny
Суть ошибочного поведения:
При включенной директиве "zlib.output_compression", скачка длится бесконечное число времени при использовании метода CHttpRequest::sendFile().

Причина в заголовке Content-Length, который посылается 705 строкой файла CHttpRequest.php
Выдается длина тела заведомо большая чем будет на самом деле, и в итоге браузер ждет и ждет окончания тела, которого не будет.

Код: Выделить всё

if(ini_get("output_handler")=='')
            header('Content-Length: '.(function_exists('mb_strlen') ? mb_strlen($content,'8bit') : strlen($content))); 
Имхо такая проверка некорректна, т.к.:
1) Не всегда (и даже чаще всего) OB включают не в конфигурации ini, а в коде. Это значит что даже если директива пуста, это не гарантирует того что на выходе будет совсем другой контент.
2) Не только эта директива отвечает за постобработку результата, а так же например "zlib.output_compression". Если не ошибаюсь аналоги есть для mbstring, iconv и tidy, не факт что все можно перечислить.

В итоге предлагаю делать проверку с помощью функции ob_get_status, которая выдает актуальный результат для всех перечисленных случаев, в т.ч. и для директивы "output_handler"

При наличии любой буферизации с обработкой посылать информацию о длине некорректно.

Re: CHttpRequest::sendFile()

Добавлено: 2011.06.28, 23:10
samdark
В 1.1.8 не исправилось? Там Qiang что-то фиксил на эту тему.

Re: CHttpRequest::sendFile()

Добавлено: 2011.06.29, 09:31
Yiivgeny
Эм..нет.

Re: CHttpRequest::sendFile()

Добавлено: 2011.07.04, 22:16
Yiivgeny

Код: Выделить всё

Index: web/CHttpRequest.php
===================================================================
--- web/CHttpRequest.php        (revision 3336)
+++ web/CHttpRequest.php        (working copy)
@@ -701,7 +701,7 @@
                header('Expires: 0');
                header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
                header("Content-type: $mimeType");
-               if(ini_get("output_handler")=='')
+               if(!ob_get_status())
                        header('Content-Length: '.(function_exists('mb_strlen') ? mb_strlen($content,'8bit') : strlen($content)));
                header("Content-Disposition: attachment; filename=\"$fileName\"");
                header('Content-Transfer-Encoding: binary');
Поправьте, а? 0:-)

Re: CHttpRequest::sendFile()

Добавлено: 2011.07.04, 22:26
samdark
Чуть позже залью…

Re: CHttpRequest::sendFile()

Добавлено: 2011.07.04, 23:56
samdark
Мб имелся ввиду ob_get_length, а не ob_get_status?

Re: CHttpRequest::sendFile()

Добавлено: 2011.07.05, 00:15
samdark

Re: CHttpRequest::sendFile()

Добавлено: 2011.07.05, 02:27
Yiivgeny
Sam Dark писал(а):Мб имелся ввиду ob_get_length, а не ob_get_status?
Принципиальной разницы нет, пустой массив из ob_get_status означает что буферизация не используется, так же как и FALSE возвращаемый ob_get_length означает что буферизация отключена. Только именно для получения статуса думаю предназначена функция с таким же названием.

Спасибо. Должно работать. Проверю.

Re: CHttpRequest::sendFile()

Добавлено: 2011.07.05, 12:45
Yiivgeny
Проверил. Все отлично.