Перейти к содержимому

Сайт на техработах - заглушка, доступ для своих, код ответа

Сайт закрывают на время выкладки, переноса домена или тяжёлой правки данных. Разбираем штатное закрытие, свою заглушку обработчиком и пропуск своих людей на закрытый сайт.

Решение

Штатное закрытие всех сайтов

Гасим публичную часть штатной настройкой:

Настройки > Настройки продукта > Настройки модулей > Главный модуль
[x] Закрыть публичную часть сайта
Текст сообщения: Сайт закрыт на технические работы

Настройка закрывает публичную часть сразу всей копии, а административный раздел остаётся открытым. Администраторы видят сайт как обычно, остальные посетители получают только текст сообщения.

Своя заглушка обработчиком

Ставим свою заглушку в файле инициализации:

// /local/php_interface/init.php - обработчик самого раннего подходящего события
AddEventHandler('main', 'OnBeforeProlog', 'maintenanceGuard', 50);
function maintenanceGuard()
{
global $USER;
if (!is_object($USER)) { // на этом шаге объекта может ещё не быть
$USER = new CUser();
}
if ($USER->IsAdmin()) {
return; // администратор идёт на сайт как обычно
}
include $_SERVER['DOCUMENT_ROOT'] . '/coming-soon/underconstruction.html';
die();
}

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

Кого пропускать на закрытый сайт

Пропускаем административный раздел и свои адреса:

$context = \Bitrix\Main\Context::getCurrent();
$request = $context->getRequest();
if ($request->isAdminSection()) {
return; // вход в админку остаётся живым
}
if (in_array($context->getServer()->get('REMOTE_ADDR'), ['203.0.113.7'], true)) {
return; // адрес офиса
}

Проверку административного раздела ставим первой: без неё заглушка закроет и вход в админку, и правку самого обработчика. Список адресов держим коротким и убираем вместе с заглушкой.

Пускаем остальных своих по ключу в куке:

$key = 'ba7f19'; // меняем ключ при каждом закрытии
if ($request->getQuery('open') === $key) {
$cookie = new \Bitrix\Main\Web\Cookie('MAINT', $key, time() + 86400);
$cookie->setPath('/');
$cookie->setHttpOnly(true);
$context->getResponse()->addCookie($cookie);
return; // кука уедет в ответе этого хита
}
if ($request->getCookie('MAINT') === $key) {
return;
}

Ссылку с ключом отдаём заказчику и тестировщикам, дальше их пускает кука. Ставить куку в ветке с die() бесполезно: ответ до клиента уже не дойдёт.

Один сайт из нескольких

Закрываем один сайт копии сайтовым файлом:

// /local/php_interface/<siteid>/init.php - файл конкретного сайта
AddEventHandler('main', 'OnBeforeProlog', 'maintenanceGuard', 50);

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

Код ответа для поисковых систем

Отдаём код временной недоступности вместо успеха:

\CHTTP::SetStatus('503 Service Unavailable');
header('Retry-After: 3600'); // через час робот вернётся сам
include $_SERVER['DOCUMENT_ROOT'] . '/coming-soon/underconstruction.html';
die();

Заголовки ставим напрямую, потому что после die() штатный объект ответа уже не отправится. С кодом успешной страницы робот запомнит текст заглушки вместо содержимого сайта.

Проверка и снятие

Проверяем ответ снаружи до объявления работ:

Окно терминала
curl -sI https://example.com/ | head -3 # ждём 503
curl -sI -b 'BITRIX_SM_MAINT=ba7f19' https://example.com/ | head -1

К имени куки платформа добавляет свой префикс, поэтому снаружи она называется BITRIX_SM_MAINT. Проверяем оба ответа с чужого адреса, а не из офиса, который сам попал в список пропуска.

Снимаем заглушку и чистим кэш витрины:

Окно терминала
rm -rf /home/bitrix/www/bitrix/cache/* /home/bitrix/www/bitrix/managed_cache/*
curl -sI https://example.com/ | head -1 # снова 200

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

Типичные проблемы

Call to a member function IsAdmin() on null.

На раннем событии объект текущего пользователя платформой ещё не создан. Его создают вручную после проверки is_object, до первого вызова метода.

Закрытие включено, а страницы открываются.

Витрину отдаёт композит или кэш страниц, минуя проверку закрытия сайта. После закрытия сбрасывают кэш и проверяют ответ из чистого браузера.

Заглушка отвечает кодом успешной страницы.

Код ответа в файле заглушки не выставлен, и робот принимает её за содержимое сайта. Позиции после такой индексации возвращаются неделями.

Вместе с витриной закрылась и админка.

В обработчике нет проверки административного раздела, а die() обрывает любой хит. Снимать заглушку приходится по SSH или файловым менеджером хостинга.

Фоновые задания встали на время работ.

Агенты запускаются на хитах сайта, а обработчик обрывает хит раньше их проверки. Долгие задания на время работ переносят на cron.

Частые вопросы

Не могу закрыть публичную часть сайта, галочка стоит, а сайт открыт.

Проверяем из чужого браузера и без авторизации: администратору закрытый сайт виден как обычно. Если и там открыт, страницу отдаёт композит или кэш, и его сбрасывают вручную.

Как открыть доступ к публичной части редакторам, а не только администраторам?

Штатное закрытие пускает администраторов, и остальные группы туда настройкой не добавить. Для редакторов и тестировщиков ставят свою заглушку и пропускают по ключу в куке или по адресу.

Как закрыть один сайт из двух на одном ядре?

Штатная настройка гасит сразу всю копию, поэтому берут обработчик в сайтовом файле инициализации. Он подключается только для своего сайта, и вторая витрина работает дальше.

Какой код ответа отдавать на время работ?

Код временной недоступности вместе с заголовком Retry-After. Он говорит роботу вернуться позже, а код успешной страницы уводит в индекс текст заглушки.

Работы на десять минут - нужна ли заглушка вообще?

Нужна, если в эти минуты идут выкладка или миграция данных. Посетитель на полусобранном сайте успеет оформить заказ, который потом придётся разбирать руками.

Смежное

Первоисточник