Fork me on GitHub

The WebDevil

Enjoy development

Надо сделать ограничения по скорости отдачи файлов. Да и в принципе саму отдачу.
Дело было под Debian etch.

Для того, чтобы отдать файл средствами php, например, надо сделать

<?php
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"bigbinary.bin\"\n");
readfile("/var/www/lighttpd/bigbinary.bin");
?>

А теперь отдайте так файл 100 пользователям. Даже lighttpd+php(fastcgi) просядет. Из-за PHP.
Но если работа lighttpd – отдавать статические файлы, то почему же ее не переложить на него? Однако, не хочется давать прямую ссылку.
Именно для этого есть специальный заголовок: X-Sendfile

<?php
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"bigbinary.bin\"\n");
header("X-Sendfile: /var/www/lighttpd/bigbinary.bin");
?>

В конфиге надо включить для 1.4 для fastcgi (в описании fastcgi-сервера):

allow-x-sendfile     = "enable"

А для 1.5 fastcgi уже реализован через mod_proxy_core, соответственно

proxy-core.allow-x-sendfile     = "enable"

Проверьте отдачу. Разница налицо.

Далее, стоял вопрос в контроле скорости отдачи.
Если правила для всего сервера одинаковы, то можно прописать в конфиге

connection.kbytes-per-second = 1000

или суммарную для всего сервера:

server.kbytes-per-second = 1000

Но если надо из скрипта управлять скоростью?
Делается вот таким образом:

<?php
header("Content-type: application/octet-stream");
header("X-LIGHTTPD-KBytes-per-second: 100");
header("Content-Disposition: attachment; filename=\"bigbinary.bin\"\n");
header("X-Sendfile: /var/www/lighttpd/bigbinary.bin");
?>

Однако ограничение скорости не работает. Во всем виноват mod_speed, точнее его отсутствие среди исходников.
Вот исходник модуля.
Итак, скачиваем его в папку src к остальным исходникам lighttpd, в src/Makefile.am добавляем:

lib_LTLIBRARIES += mod_speed.la
mod_speed_la_SOURCES = mod_speed.c
mod_speed_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined
mod_speed_la_LIBADD = $(common_libadd)

Желательно это сделать до выполнения autogen.sh. Или же запустить

./configure --enable-maintainer-mode

и потом в конфиге дописать в загрузке модулей mod_speed.

ПРИМЕЧАНИЯ
В 1.5 появилась возможность обработки X-Sendfile из бэкэнда у proxy_core. В версии 1.4 эта возможность была в модуле mod_fastcgi и от бэкэнда-апача, например, заголовок такой поймать было нельзя.

В версии 1.5 есть возможность выбирать backend для отдачи файлов. Посмотреть на сравнение можно тут. А установить нужный можно так:

server.network-backend = "gthread-aio"

Также у меня возникал вопрос, а как можно сделать простую обработку входящих параметров на некоем встроенном языке? Для примера, у nginx есть встроенный perl-овый модуль, при помощи которого можно реализовать мини-логику прямо на вэб-сервере. В lighttpd такая возможность нашлась – mod_magnet и в качестве обработчика скрипт на LUA. Ну что ж, будет повод освоить LUA.

2 Responses to “Lighttpd and speed limits”

  1. В nginx то же самое делается через header X-Accel-Redirect.

    deMone

  2. В курсе. Но был выбран именно lighttpd. Хотябы для того, чтоб сравнить его с nginx-ом ;)

    dm