Отдать файл скриптом over SSL (глючит в IE)

Игорь

Новичок
Отдать файл скриптом over SSL (глючит в IE)

Добрый день.

В своё время был написан скрипт, который делал следующее:

В файловой системе, за пределами web, лежит файл.
Скрипт проверяет возможность отдачи его пользователю, и отдаёт его.

Код, отдающий файл:
PHP:
$fd = $row["over_file"]; // абсолютный путь к файлу
$fo = $row["over_file_name"]; // имя файла, которое будет видно пользователю

header("Content-Length: ".filesize($fd));
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Type: application/force-download");
header("Content-Disposition: attachment; filename=".$fo);
header("Content-Transfer-Encoding: binary");
readfile($fd);
Этот скрипт прекрасно работал, до тех пор, пока не пришлось переехать на https протокол.

Вот с этого времени данный браузер (IE) не хочет принимать файл. Сначала браузер выдаёт окошко, как при загрузке файла (запустить, сохранить, отменить), но тотчас следом появляется popup окно с ошибкой: Internet Explorer не удаётся загрузить scriptname.php из domainname.ru Не удаётся открыть этот узел Интернета. Узел недоступен или не найден. Повторите попытку позднее.

Замечена эта ошибка на браузерах IE 6й и 7й версий. Мозила, Сафари, Опера -- принимают файл.
Если тянуть файл просто, из web каталога, проблем не возникает.

Сертификат само собой самодельный, без подписи удостоверяющего центра, но узел добавлен в доверенные.

При переносе скрипта на http всё работает на ура.

Вопрос: что нужно сделать, чтобы получить файл посредством скрипта?

Правильно ли я понимаю, что браузер запрашивает скрипт, скрипт отсылает ему заголовки, и браузеру они по какой-то причине не нравятся? Как эту беду побороть?
 

DIS

Новичок
+1

наблюдается аналогичный баг в IE 6 и 7 по https

PHP:
header("Content-type: application/octet-stream");
header("pragma: public");
header("pragma: no-cache");
header("Cache-Control: cache");
header("Cache-Control: must-revalidate");


      header("Content-Disposition: attachment; filename=\"".$name.".txt\"");
      header('Content-Length: '. strlen($str));
      echo $str;
до меня писалось - я забил - пользуюсь FireFox`ом для закачки этого файла - благо это не публичная часть.

но было интересно понять в чём дело
 

DiMA

php.spb.ru
Команда форума
> Если тянуть файл просто, из web каталога, проблем не возникает.

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

Игорь

Новичок
Проблема решена. Этапы решения:

Локализовал проблему, но на этом этапе не смог её порешать.

Скрипт принимает решения, следует ли отдавать файл клиенту, используя сессию, с сохранинем PHPSESSID в куках.

Если закоментировать session_start(), и, следовательно, анализ отдавать/неотдавать, то файл отдаётся.

Сложность перехвата трафика в том, что протокол over SSL, поэтому перехватывал трафик просто http.

Для перехвата использовал fiddler.

Заголовки принимаемого файла практически идентичны, но у файла со включенным session_start() в заголовок добавляется строка Expires: Thu, 19 Nov 1981 08:52:00 GMT

Больше различий нет.

Дата конечно протухшая (интересно, и откуда она такая взялась?), и я менял Expiries на валидную дату, но от этого файл отдаваться не стал.

Активист, гугля это первый инструмент, который использовался. Кстати, благодарю за ссылку на activecollab. Ни одна из приведённых ссылок не содержала решения, но косвенно обсуждение на activecollab привело к решению проблемы.

Итак, краткое резюме:

Проблема возникает из-за использования sesson_start()
Проблема лечится вставкой session_cache_limiter ("public") перед вызовом session_start.

Теперь код выглядит так:
PHP:
session_cache_limiter ("public");
session_start();

// поскипано, как не относящееся к проблеме

$fd = $row["over_file"]; // абсолютный путь к файлу 
$fo = $row["over_file_name"]; // имя файла, которое будет видно пользователю 

header("Content-Length: ".filesize($fd));
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Type: application/octet-steam");
header("Content-Type: application/zip");
header("Content-Type: application/force-download");
header("Content-Disposition: attachment; filename=\"".$fo."\"");
header("Content-Transfer-Encoding: binary");
readfile($fd);
 
Сверху