php - сервер прерывает скачивание файла размером выше 1.2 ГБ

Когда питаюсь скачать файл размерностью 1.5 ГБ, он доходит к 1.2 ГБ и начинает скачку заново. Данная особенность только на продакшене. Код скачки файла:

if (file_exists($file) === true) {
   if (ob_get_level()) {
       ob_end_clean();
   }

   header('Content-Description: File Transfer');
   header('Content-Type: application/zip');
   header('Content-Disposition: attachment; filename=' . basename($file));
   header('Content-Transfer-Encoding: binary');
   header('Cache-Control: no-store');
   header('Cache-Control: no-cache, no-store, must-revalidate');
   header('Content-Length: ' . filesize($file));
   readfile($file);
   exit;
}

Ответы (1 шт):

Автор решения: UKRman

Решил проблему!

Для скачки больших файлов можно подкрутить значения max_execution_time и memory_limit как описано тут, но данный подход плох тем что если файл постоянно растет настройки тоже должны соотносительно расти - не комильфо.

Нужное мне решения было описано тут, тут и тут по использованию X-Sendfile - для загрузки больных файлов.

Вкратце нужно установить библиотеку mod_xsendfile.c и подключить ее в httpd.conf, модифицировать php код в моем вопросе - примеры стандартной установки библиотеки для apache2 тут или тут, но мне нужно было через docker, момент з докером опускается если установка у вас в ручную.

Dockefile:

FROM httpd:2.4

RUN apt-get update && apt-get install -y \
    wget \
    apache2-dev

RUN wget -O /tmp/mod_xsendfile.tar.gz https://tn123.org/mod_xsendfile/mod_xsendfile-0.12.tar.gz \
    && mkdir /tmp/mod_xsendfile \
    && tar -xf /tmp/mod_xsendfile.tar.gz -C /tmp/mod_xsendfile --strip-components=1 \
    && cd /tmp/mod_xsendfile \
    && apxs -cia mod_xsendfile.c \
    && rm -r /tmp/*

httpd.conf:

LoadModule xsendfile_module modules/mod_xsendfile.so

XSendFile on

XSendFilePath /path/to/download/catalog/

php:

...
header("X-Sendfile: $file"); // $file -> /path/to/file
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . basename($file));
ob_end_clean();
flush();
readfile($file);
exit;

или в моём случае Yii2:

return Yii::$app->response->xSendFile($file); // $file -> /path/to/file
→ Ссылка