Последние статьи
Дефицит идей.На данный момент в сайтостроении, да и как везде, в общем то, наблюдается некий застой в решениях. Для сайтов...
Yandex с блекждеком и шлюхами.Как то размышляя о способах монетизации различных веб-проектов, я увидел некоторую нестыковку на...
Flash: построение графика с динамическим обновлением данных.До того, как я открыл для себя такие веши как Munin и прочие утилиты для отслеживания состояния серверов - я...
Защита комментариев от спама.Все люди, которые вели, ведут или собираются вести блоги, форумы или гостевые книги сталкиваются с...
Nginx и Bitrix. Использование их без использования апача. Встала тут задача поднять сервер, исключительно под сайты, написанные на базе CMS Bitrix (в силу...
Eval - наше все!Казалось бы, весь интернет напичкан статьями и рекомендациями к программистам, в которых говориться, что eval...
Кризис. Пожуем эту тему еще разок ? Бредоглава 0 (мы же программисты, у нас обязана быть нулевая глава :). Введение . О мировом экономическом...
Дизайн ЯндексаЯндекс в своем  желании заработать как можно больше демонстрирует просто потрясяющую способность...

Nginx и Bitrix. Использование их без использования апача.

 Встала тут задача поднять сервер, исключительно под сайты, написанные на базе CMS Bitrix (в силу тормознутости этой CMS, дабы своей прожорливостью она не портила жизнь всем остальным сайтам), и чтобы по максимуму быстро отдавать содержимое Bitrix-овских сайтов, решил, что Apache на сервере нафиг не нужен и что nginx-а будет вполне достаточно. Избавится от апача я решил, не потому, что имею к нему какие то притензии, а по двум причинам, во-первых, для быстрой отдачи статики все равно использовать nginx удобней, а во-вторых, на первом серевере у меня уже использовался nginx в качестве проксирующего сервера, но поскольку админ, ответственный за добавление сайтов, не парился над тем, чтобы прописывать для сайтов в конфиге nginx-а папки со статикой, получилось, что в нем срабатывал конфиг по умолчанию, который, естественно, не знал где эта статика лежит и все равно все запросы переадресовывал апачу. То есть выйгрыш был только на отдаче больших файлов, в этом случае nginx просто отпускал apache, а сам сидел на раздаче контента конечному пользователю. И чтобы не плодить лишних конфигов (к сожалению, структура сайтов была разной и написать один универсальный конфиг для всех не представляется возможным), я решил просто убрать apache вообще. Сказано, сделано. Apache даже не ставился (единственное, что от него было поставлено - это ab для анализа производительности), а к nginx-у PHP был прикручен как FastCGI, благо описаний, как это сделать, в интернете было много. Итак, ставлю тестовый сайт на Bitrix-е - и все работает. Ну вот, думаю, счастье есть. Все, можно отдыхать. Но не тут то было. Мне просто повезло, что этот сайт был без ЧПУ и mod_rewrite от apache там просто не задействовался. Но вот, ставят сайт с ЧПУ и началось. Типовое содержимое .htaccess Битрикса для реализации ЧПУ выглядит следеющим образом:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !/bitrix/urlrewrite.php$
RewriteRule ^(.*)$ /bitrix/urlrewrite.php [L]
</IfModule>

Гугление и чтение доки на сайте nginx-а показало, что конструкция
location / {
root /home/www/domain.name/public_html;
index index.php index.html index.htm;
if (!-e $request_filename) {
rewrite ^(.*)$ /bitrix/urlrewrite.php last;
}
}
легко и непринужденно заменяет всю пачку Apach-евских инструкций для реализации ЧПУ. Но всплыло одно НО. Битрикс после добавления товара в корзину, делает редирект на страницу товара, но не просто на ту же папку, а с какого то перепугу, дописывает в конец пути index.php. То есть, если путь к товару был, к примеру, /e-store/xml_catalog/1067/38608/, то после добавления его в корзину, Битрикс перенаправляет посетителя на /e-store/xml_catalog/1067/38608/index.php. И, ахтунг !!!, if (!-e $request_filename) совершенно игнорирует тот факт, что такой директории не существует, и понятное дело, что в несуществующей директории index.php ну никак не может быть. В итоге, срабатывает описание для файлов PHP:
location ~ \.php$ {
fastcgi_pass 127.0.0.1:1026;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /home/www/domain.name/public_html$fastcgi_script_name;
include fastcgi_params;
}
И поскольку такого файла то нет, мы получаем ошибку: No input file specified. Чтобы избежать этого, пришлось вставить проверку на существование файла c расширением php в само описание обработчика FastCGI, и если такого файла не существует, делать редирект на URL, но уже без файла:
location ~ \.php$ {
root /home/www/domain.name/public_html;
if (!-f $request_filename) {
rewrite ^(.*)/index.php$ $1/ redirect;
}
fastcgi_pass 127.0.0.1:1026;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /home/www/domain.name/public_html$fastcgi_script_name;
include fastcgi_params;
}

Еще несколько тонкостей - поскольку мы не знаем, существует ли сама директория, то нам надо запускать процесс анализа полученного урла заново, и чтобы это произошло, надо использовать именно флаг redirect, а не last или break. Во-вторых, Битрикс, как выяснилось очень привередлив к наличию слеша в конце URL, и если его там нет, он игнорирует значение последней директории в пути, что приводит к поднятию на уровень выше. То есть если вместо rewrite ^(.*)/index.php$ $1/ redirect; написать rewrite ^(.*)/index.php$ $1 redirect; - вместо описания товара мы попадаем на уровень выше, то есть на список товаров в данной категории.
вернуться в список статей