«Парсер» студии Лебедева и thttpd
Сегодня потратил часть дня, чтобы выяснить, что Парсер не заработает с thttpd.
Вообще, мне очень нравится веб-сервер nginx, но, увы, nginx не поддерживает CGI, а Парсер работает либо так, либо как модуль Apache. Поэтому я решил взять какой-нибудь простой веб-сервер, который поддерживает CGI и поставить его позади nginx.
Что-то у меня с nginx в последнее время любовь как-то не складывается.
У меня Ubuntu 10.04, поэтому я всё поставил из пакетов, Парсер в том числе, пакет неофициальный, я его нашёл в разделе прислали пользователи.
После того как я всё настроил, ничего не заработало. Отладка через strace быстро показала, что Парсер падает. Я его перекомпилировал. Если будете перекомпилировать, вот мой рецепт.
Я поставил следующие пакеты (легко допускаю, что где-то поставил лишнего, так как ориентировался по названиям): libgmime2.1-dev libgmime-2.4-2 glibc-2.10-1 libgc1c2 bison.
В каталог /opt/pcre-8.12 я положил свежую версию PCRE, в /opt/pcre лежит скомпилированная версия. Строка компиляции получилась вот такая:
CPPFLAGS='-I/opt/pcre-8.12 -I/opt/pcre/include/' \
./configure --prefix=/opt/parser3/ --with-shared-gc --with-static-pcre=/opt/pcre
make
sudo make install
После того как я стал пользоваться собранным мною Парсером, что-то в браузер я получил, но всё было не то. Причём при запуске из консоли, я получал на экран результат работы скрипта.
Тут я догадался (поскольку в консоли не видел HTTP-заголовков), что Парсер имеет какой-то механизм, который должен его переключать из режима командной строки в режим CGI и обратно. Из вида протокола CGI понятно, что это какие-то переменные окружения.
Я создал небольшой shell-скрипт, в который накидал разных переменных окружения, необходимых по стандарту для CGI и подбором выяснил, что для Парсера критично наличие переменных GATEWAY_INTERFACE, SCRIPT_NAME, PATH_INFO и PATH_TRANSLATED. Вот небольшой пример:
if(cgi) {
// few absolute obligatory
const char* path_info=getenv("PATH_INFO");
if(!path_info)
SAPI::die("CGI: illegal call (missing PATH_INFO)");
const char* script_name=getenv("SCRIPT_NAME");
if(!script_name)
SAPI::die("CGI: illegal call (missing SCRIPT_NAME)");
// … ещё много кода …
}
При помощи CGI, написанного на bash, я выгрузил все переменные окружения, которые предоставляет thttpd (у меня версия 2.25b), оказалось, что двух последних переменных в дампе нет. Причём в интернете эта проблема уже поднималась (правда без связи с Парсером) и была успешна разрешена авторами thttpd. Наверное в последней версии что-то сломали.
Добавлено: я что-то явно делаю не так. Я попробовал ещё сервер mini-httpd, там в changelog есть такая фраза: «Added PATH_INFO to CGI environment», но я опять же не вижу эту переменную в окружении. В исходниках так же упоминаются обе переменных «PATH_…».
Добавлено ещё позже: так, по коду выходит следующее: если mini-httpd или thttpd находит файл по URL на файловой системе сразу, то PATH-переменные не заполняется, но заполняется SCRIPT_NAME, если не находит, то алгоритм отрезает путь до первого слеша и кладёт орезанное в PATH_INFO, формируя PATH_TRANSLATED из этого пути, присоединяя к нему рабочий каталог.
При этом куда-то пропадает SCRIPT_NAME, в коде я ещё не нашёл куда и почему. Но, похоже, для Парсера mini-httpd и thttpd (у них один автор) не подойдут.
Чтобы понимать:
http://example.org/cgi-bin/test.cgi — формируется SCRIPT_NAME, но не PATH_INFO и PATH_TRANSLATED
http://example.org/cgi-bin/test.cgi/ — формируется PATH_INFO и PATH_TRANSLATED, но не SCRIPT_NAME
И ещё позднее: попробовал веб-серверы Boa, Bozohttpd и Cherokee. Парсер с ними не заработал, причина та же — нехватает переменных. Очень похоже, что Парсер сильно неправ в своей трактовке протокола CGI.
А чем Вас парсер заинтересовал?
Комментарий для анон:
На нём написан определённый софт, который у нас используется.
а почему нелзя fastcgi обёртку написать и использовать ngnix сразу?
Комментарий для http://gurgray.ya.ru:
http://bolknote.ru/all/3157