Типичная проблема сайта, когда тот оказывается за балансировщиком нагрузки (load balancer), это несоответствие части заголовков запроса клиента и тех заголовков, которые передаются балансировщиком серверу. Чаще всего мы сталкиваемся с этим при запуске сайта на продакшн, где сайт впервые оказывается на HTTPS.
В Drupal 6/7 была возможность установить значение $base_url, что решало все возможные проблемы. В 8ке эту настройку отправили в утиль.
Если cформированы верно заголовки балансировщика:
- X_FORWARDED_HOST
- X_FORWARDED_PORT
- X_FORWARDED_PROTO
- X_FORWARDED_FOR
И настройки в файле settings.php также верно указывают на прокси сервера:
1 2 |
$settings['reverse_proxy'] = TRUE; $settings['reverse_proxy_addresses'] = ['a.b.c.d', …]; |
То никаких проблем не возникает.
Но aws cloudfront определяет собственные заголовки FORWARDED —
1 |
$_SERVER['HTTP_CLOUDFRONT_FORWARDED_PROTO'] |
Что приводит к неправильному формированию ссылок. К примеру, canonical и shortlink содержат не правильный протокол — http вместо https.
1 2 |
<link rel="canonical" href="http://www.britishlandlogistics.com/" /> <link rel="shortlink" href="http://www.britishlandlogistics.com/" /> |
Здесь проблема заключается в том, что значение $_SERVER[‘HTTP_CLOUDFRONT_FORWARDED_PROTO’] должно быть в $_SERVER[‘HTTP_X_FORWARDED_PROTO’].
Первая мысль — это переопределить значение $_SERVER[‘HTTP_X_FORWARDED_PROTO’] в файле settings.php. Но это бесполезно, т.к. верное значение переменной должно быть установлено до операции (это в index.php):
1 |
$response = $kernel->handle($request); |
Потому правильное решение — это установить значение заголовка в настройках вашего сервера или (если это возможно) поправить настройки cloudfront.
Есть и универсальное решение (хоть и не кононичное) — добавить переопределение в index.php:
1 2 3 4 5 |
// в самом начале корневого index.php: if (!empty($_SERVER['HTTP_CLOUDFRONT_FORWARDED_PROTO'])) { $_SERVER['HTTP_X_FORWARDED_PROTO'] = $_SERVER['HTTP_CLOUDFRONT_FORWARDED_PROTO']; unset($_SERVER['HTTP_X_FORWARDED_PORT']); } |